Skip to content

Commit 5d34e84

Browse files
committed
std out supp
1 parent e1cd20e commit 5d34e84

File tree

1 file changed

+75
-39
lines changed

1 file changed

+75
-39
lines changed

ml_grid/pipeline/data_feature_methods.py

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def getNFeaturesMarkovBlanket(
110110
svc_kernel (str): The kernel to be used by the SVC model.
111111
Defaults to "rbf".
112112
suppress_print (bool): If True, suppresses stdout from the fit method.
113-
Defaults to "rbf".
113+
Defaults to True.
114114
115115
Raises:
116116
TypeError: If X_train is not a pandas DataFrame.
@@ -119,6 +119,9 @@ def getNFeaturesMarkovBlanket(
119119
List[str]: A list containing the names of the top n features from
120120
the Markov Blanket.
121121
"""
122+
import os
123+
import sys
124+
122125
# Ensure input is a pandas DataFrame to access column names
123126
if not isinstance(X_train, pd.DataFrame):
124127
raise TypeError(
@@ -131,53 +134,86 @@ def getNFeaturesMarkovBlanket(
131134
stratified_kfold = StratifiedKFold(n_splits=cv, shuffle=True, random_state=27)
132135

133136
# Use the provided classifier, or default to SVC if none is given.
134-
model_to_use = classifier if classifier is not None else SVC(random_state=27, class_weight="balanced", kernel=svc_kernel)
135-
136-
# Initialize the PyImpetus object with desired parameters
137-
model = PPIMBC(model=model_to_use,
138-
p_val_thresh=0.05,
139-
num_simul=num_simul,
140-
simul_size=0.2,
141-
simul_type=0,
142-
sig_test_type="non-parametric",
143-
cv=stratified_kfold,
144-
random_state=27,
145-
n_jobs=-1,
146-
# Set verbose to 0 to prevent calls to the problematic
147-
# progress printing function in joblib, which causes the
148-
# 'AttributeError: ... _pre_dispatch_amount'.
149-
verbose=0)
137+
# CRITICAL: Set verbose=False for SVC to prevent LibSVM output
138+
model_to_use = classifier if classifier is not None else SVC(
139+
random_state=27,
140+
class_weight="balanced",
141+
kernel=svc_kernel,
142+
verbose=False # This is the key parameter for LibSVM
143+
)
150144

151-
import os
152-
import sys
145+
# Ensure verbose is set to False at multiple levels
146+
if hasattr(model_to_use, 'set_params'):
147+
try:
148+
model_to_use.set_params(verbose=False)
149+
except:
150+
pass
151+
if hasattr(model_to_use, 'verbose'):
152+
model_to_use.verbose = False
153+
154+
# Suppress output at the OS level BEFORE creating any model objects
155+
devnull_fd = None
156+
old_stdout_fd = None
157+
old_stderr_fd = None
158+
159+
if suppress_print:
160+
try:
161+
# Save original file descriptors
162+
old_stdout_fd = os.dup(1)
163+
old_stderr_fd = os.dup(2)
164+
165+
# Open devnull and redirect stdout/stderr to it
166+
devnull_fd = os.open(os.devnull, os.O_RDWR)
167+
os.dup2(devnull_fd, 1)
168+
os.dup2(devnull_fd, 2)
169+
except Exception as e:
170+
# If suppression fails, just continue without it
171+
logging.getLogger('ml_grid').warning(f"Could not suppress output: {e}")
172+
suppress_print = False
153173

154-
# Fit and transform the training data
155-
# PyImpetus works with numpy arrays and returns feature indices in model.MB
156174
try:
157-
if suppress_print:
158-
# Use OS-level redirection to silence C-level libraries like LibSVM
159-
devnull = os.open(os.devnull, os.O_WRONLY)
160-
old_stdout = os.dup(1)
161-
old_stderr = os.dup(2)
162-
os.dup2(devnull, 1)
163-
os.dup2(devnull, 2)
164-
try:
165-
model.fit(X_train.values, y_train)
166-
finally:
167-
# Restore original stdout and stderr
168-
os.dup2(old_stdout, 1)
169-
os.dup2(old_stderr, 2)
170-
os.close(devnull)
171-
os.close(old_stdout)
172-
os.close(old_stderr)
173-
else:
174-
model.fit(X_train.values, y_train)
175+
# Initialize the PyImpetus object with desired parameters
176+
model = PPIMBC(model=model_to_use,
177+
p_val_thresh=0.05,
178+
num_simul=num_simul,
179+
simul_size=0.2,
180+
simul_type=0,
181+
sig_test_type="non-parametric",
182+
cv=stratified_kfold,
183+
random_state=27,
184+
n_jobs=-1,
185+
verbose=0)
186+
187+
# Fit the model (this is where LibSVM prints)
188+
model.fit(X_train.values, y_train)
189+
175190
except ValueError as e:
191+
# Restore output before logging
192+
if suppress_print and old_stdout_fd is not None:
193+
os.dup2(old_stdout_fd, 1)
194+
os.dup2(old_stderr_fd, 2)
195+
if devnull_fd is not None:
196+
os.close(devnull_fd)
197+
os.close(old_stdout_fd)
198+
os.close(old_stderr_fd)
199+
176200
# This handles cases where PyImpetus fails due to numerical precision
177201
# issues (e.g., y_prob > 1). We'll log the error and fall back to
178202
# using all original features for this trial.
179203
logging.getLogger('ml_grid').error(f"PyImpetus failed during fit: {e}. Using all features as a fallback.")
180204
return list(original_columns)
205+
finally:
206+
# Always restore stdout/stderr
207+
if suppress_print and old_stdout_fd is not None:
208+
try:
209+
os.dup2(old_stdout_fd, 1)
210+
os.dup2(old_stderr_fd, 2)
211+
if devnull_fd is not None:
212+
os.close(devnull_fd)
213+
os.close(old_stdout_fd)
214+
os.close(old_stderr_fd)
215+
except:
216+
pass # Silently fail if restoration doesn't work
181217

182218
# Get the feature indices from the Markov blanket (MB)
183219
selected_features = model.MB

0 commit comments

Comments
 (0)