wrapshap 0.1.1__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wrapshap-0.1.1/wrapshap.egg-info → wrapshap-0.1.2}/PKG-INFO +2 -2
- {wrapshap-0.1.1 → wrapshap-0.1.2}/setup.py +2 -2
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/_internal/_already_wrapped.py +9 -3
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/_internal/_already_wrapped_LGB.py +10 -4
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/_internal/_wrapshap.py +126 -8
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/already_wrapped.py +1 -1
- wrapshap-0.1.2/wrapshap/gpu_implementation/__init__.py +1 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/gpu_implementation/_internal/_already_wrapped_gpu.py +8 -8
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/gpu_implementation/_internal/_already_wrapped_lgb_gpu.py +8 -8
- wrapshap-0.1.2/wrapshap/gpu_implementation/_internal/_wrapshap_gpu.py +774 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/gpu_implementation/already_wrapped_gpu.py +1 -1
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/gpu_implementation/wrapshap_gpu.py +17 -5
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/wrapshap.py +11 -6
- {wrapshap-0.1.1 → wrapshap-0.1.2/wrapshap.egg-info}/PKG-INFO +2 -2
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap.egg-info/requires.txt +1 -1
- wrapshap-0.1.1/wrapshap/gpu_implementation/__init__.py +0 -1
- wrapshap-0.1.1/wrapshap/gpu_implementation/_internal/_wrapshap_gpu.py +0 -429
- {wrapshap-0.1.1 → wrapshap-0.1.2}/LICENSE +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/README.md +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/README_PyPI.md +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/pyproject.toml +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/setup.cfg +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/__init__.py +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/_internal/__init__.py +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/gpu_implementation/_internal/__init__.py +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap.egg-info/SOURCES.txt +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap.egg-info/dependency_links.txt +0 -0
- {wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wrapshap
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: SHAP-based feature selection and exploration for high-dimensional data
|
|
5
5
|
Home-page: https://github.com/fefurger/wrapshap
|
|
6
6
|
Author: Félix Furger
|
|
@@ -22,7 +22,7 @@ Requires-Dist: lightgbm>=4.6.0
|
|
|
22
22
|
Requires-Dist: seaborn>=0.13.2
|
|
23
23
|
Requires-Dist: matplotlib>=3.8.4
|
|
24
24
|
Provides-Extra: gpu
|
|
25
|
-
Requires-Dist: tensorflow
|
|
25
|
+
Requires-Dist: tensorflow<=2.20,>=2.16.1; extra == "gpu"
|
|
26
26
|
Dynamic: author
|
|
27
27
|
Dynamic: author-email
|
|
28
28
|
Dynamic: classifier
|
|
@@ -6,7 +6,7 @@ README = Path(__file__).parent / "README_PyPI.md"
|
|
|
6
6
|
|
|
7
7
|
setup(
|
|
8
8
|
name='wrapshap',
|
|
9
|
-
version='0.1.
|
|
9
|
+
version='0.1.2',
|
|
10
10
|
author='Félix Furger',
|
|
11
11
|
author_email='fefurger@hotmail.com',
|
|
12
12
|
description='SHAP-based feature selection and exploration for high-dimensional data',
|
|
@@ -27,7 +27,7 @@ setup(
|
|
|
27
27
|
],
|
|
28
28
|
extras_require={
|
|
29
29
|
'gpu': [
|
|
30
|
-
'tensorflow>=2.16.1'
|
|
30
|
+
'tensorflow>=2.16.1, <=2.20'
|
|
31
31
|
]
|
|
32
32
|
},
|
|
33
33
|
license="Apache-2.0",
|
|
@@ -132,7 +132,7 @@ class WrappedXGB(ABC):
|
|
|
132
132
|
self.shap_test = self.model.predict(xgb.DMatrix(self.X_test, self.y_test), pred_contribs=True)[:,:-1]
|
|
133
133
|
|
|
134
134
|
@wrapshap_required('wrapshap')
|
|
135
|
-
def shapRFE(self, surrogate_metrics: bool = False, top: int = None):
|
|
135
|
+
def shapRFE(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True,time_info:bool = False):
|
|
136
136
|
"""
|
|
137
137
|
Simply calls Wrapshap implementation of Recursive Feature Elimination (RFE).
|
|
138
138
|
|
|
@@ -149,11 +149,13 @@ class WrappedXGB(ABC):
|
|
|
149
149
|
return self.wrapshap.shapRFE(
|
|
150
150
|
surrogate_metrics=surrogate_metrics,
|
|
151
151
|
top=top,
|
|
152
|
+
plot = plot,
|
|
153
|
+
time_info=time_info
|
|
152
154
|
)
|
|
153
155
|
|
|
154
156
|
|
|
155
157
|
@wrapshap_required('wrapshap')
|
|
156
|
-
def shapFFS(self, surrogate_metrics: bool = False, top: int = None):
|
|
158
|
+
def shapFFS(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True,time_info:bool = True):
|
|
157
159
|
"""
|
|
158
160
|
Simply calls Wrapshap implementation of Forward Feature Selection (FFS).
|
|
159
161
|
|
|
@@ -170,11 +172,13 @@ class WrappedXGB(ABC):
|
|
|
170
172
|
return self.wrapshap.shapFFS(
|
|
171
173
|
surrogate_metrics=surrogate_metrics,
|
|
172
174
|
top=top,
|
|
175
|
+
plot = plot,
|
|
176
|
+
time_info=time_info
|
|
173
177
|
)
|
|
174
178
|
|
|
175
179
|
|
|
176
180
|
@wrapshap_required('wrapshap')
|
|
177
|
-
def shapBFE(self, surrogate_metrics: bool = False, top: int = None):
|
|
181
|
+
def shapBFE(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True, time_info:bool=False):
|
|
178
182
|
"""
|
|
179
183
|
Simply calls Wrapshap implementation of Forward Feature Selection (BFE).
|
|
180
184
|
|
|
@@ -191,6 +195,8 @@ class WrappedXGB(ABC):
|
|
|
191
195
|
return self.wrapshap.shapBFE(
|
|
192
196
|
surrogate_metrics=surrogate_metrics,
|
|
193
197
|
top=top,
|
|
198
|
+
plot = plot,
|
|
199
|
+
time_info = time_info
|
|
194
200
|
)
|
|
195
201
|
|
|
196
202
|
|
|
@@ -146,7 +146,7 @@ class WrappedLGB(ABC):
|
|
|
146
146
|
self.shap_test = shap_test
|
|
147
147
|
|
|
148
148
|
@wrapshap_required('wrapshap')
|
|
149
|
-
def shapRFE(self, surrogate_metrics: bool = False, top: int = None):
|
|
149
|
+
def shapRFE(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True, time_info:bool = False):
|
|
150
150
|
"""
|
|
151
151
|
Simply calls Wrapshap implementation of Recursive Feature Elimination (RFE).
|
|
152
152
|
|
|
@@ -163,11 +163,13 @@ class WrappedLGB(ABC):
|
|
|
163
163
|
return self.wrapshap.shapRFE(
|
|
164
164
|
surrogate_metrics=surrogate_metrics,
|
|
165
165
|
top=top,
|
|
166
|
+
plot = plot,
|
|
167
|
+
time_info = time_info
|
|
166
168
|
)
|
|
167
169
|
|
|
168
170
|
|
|
169
171
|
@wrapshap_required('wrapshap')
|
|
170
|
-
def shapFFS(self, surrogate_metrics: bool = False, top: int = None):
|
|
172
|
+
def shapFFS(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True, time_info:bool = True):
|
|
171
173
|
"""
|
|
172
174
|
Simply calls Wrapshap implementation of Forward Feature Selection (FFS).
|
|
173
175
|
|
|
@@ -184,11 +186,13 @@ class WrappedLGB(ABC):
|
|
|
184
186
|
return self.wrapshap.shapFFS(
|
|
185
187
|
surrogate_metrics=surrogate_metrics,
|
|
186
188
|
top=top,
|
|
189
|
+
plot = plot,
|
|
190
|
+
time_info=time_info
|
|
187
191
|
)
|
|
188
192
|
|
|
189
193
|
|
|
190
194
|
@wrapshap_required('wrapshap')
|
|
191
|
-
def shapBFE(self, surrogate_metrics: bool = False, top: int = None):
|
|
195
|
+
def shapBFE(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True,time_info:bool = False):
|
|
192
196
|
"""
|
|
193
197
|
Simply calls Wrapshap implementation of Forward Feature Selection (BFE).
|
|
194
198
|
|
|
@@ -205,6 +209,8 @@ class WrappedLGB(ABC):
|
|
|
205
209
|
return self.wrapshap.shapBFE(
|
|
206
210
|
surrogate_metrics=surrogate_metrics,
|
|
207
211
|
top=top,
|
|
212
|
+
plot=plot,
|
|
213
|
+
time_info=time_info
|
|
208
214
|
)
|
|
209
215
|
|
|
210
216
|
|
|
@@ -565,4 +571,4 @@ def _plot_regression_metrics(y_train, y_test, y_train_pred, y_test_pred):
|
|
|
565
571
|
ax[1].set_ylabel('Predictions')
|
|
566
572
|
ax[1].set_title(f'Test Set: R2 = {test_r2:.2f}, MAE = {test_mae:.2f}')
|
|
567
573
|
|
|
568
|
-
plt.show()
|
|
574
|
+
plt.show()
|
|
@@ -14,6 +14,8 @@ from sklearn.preprocessing import StandardScaler
|
|
|
14
14
|
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
|
|
15
15
|
from sklearn.metrics import r2_score, mean_absolute_error
|
|
16
16
|
from scipy.special import expit
|
|
17
|
+
import matplotlib.pyplot as plt
|
|
18
|
+
from time import time
|
|
17
19
|
|
|
18
20
|
# ----------------------------------------------------------------------------------------------------------------------
|
|
19
21
|
# Public API - These utilities are used by other modules and re-exported.
|
|
@@ -26,7 +28,9 @@ def shapRFE(
|
|
|
26
28
|
feature_names: list,
|
|
27
29
|
surrogate_metrics: bool = False,
|
|
28
30
|
top: int = None,
|
|
29
|
-
task_type: str = 'classification'
|
|
31
|
+
task_type: str = 'classification',
|
|
32
|
+
plot : bool = True,
|
|
33
|
+
time_info : bool = False
|
|
30
34
|
) -> tuple:
|
|
31
35
|
"""
|
|
32
36
|
Wrapshap implementation of Recursive Feature Elimination (RFE).
|
|
@@ -62,7 +66,7 @@ def shapRFE(
|
|
|
62
66
|
shap_test_normalized = scaler.transform(shap_test)
|
|
63
67
|
|
|
64
68
|
_progress_bar(0, len(feature_names), mode='ascending')
|
|
65
|
-
|
|
69
|
+
start_time = time()
|
|
66
70
|
while remaining_features:
|
|
67
71
|
|
|
68
72
|
model = LinearRegression()
|
|
@@ -85,6 +89,8 @@ def shapRFE(
|
|
|
85
89
|
results[len(remaining_features)][f'test_{key}'] = metrics_test[key]
|
|
86
90
|
for key in metrics_train:
|
|
87
91
|
results[len(remaining_features)][f'train_{key}'] = metrics_train[key]
|
|
92
|
+
|
|
93
|
+
results[len(remaining_features)]['time']=time() - start_time
|
|
88
94
|
|
|
89
95
|
min_importance_index = np.argmin(np.abs(model.coef_))
|
|
90
96
|
removed_feature = remaining_features.pop(min_importance_index)
|
|
@@ -93,6 +99,9 @@ def shapRFE(
|
|
|
93
99
|
_progress_bar(len(removed_features), len(feature_names), mode='ascending')
|
|
94
100
|
|
|
95
101
|
removed_features.reverse()
|
|
102
|
+
|
|
103
|
+
if plot :
|
|
104
|
+
_plot_performance(results, time_info)
|
|
96
105
|
return removed_features, results
|
|
97
106
|
|
|
98
107
|
|
|
@@ -102,7 +111,9 @@ def shapFFS(
|
|
|
102
111
|
feature_names: list,
|
|
103
112
|
surrogate_metrics: bool = False,
|
|
104
113
|
top: int = None,
|
|
105
|
-
task_type: str = 'classification'
|
|
114
|
+
task_type: str = 'classification',
|
|
115
|
+
plot: bool = True,
|
|
116
|
+
time_info: bool = True
|
|
106
117
|
) -> tuple:
|
|
107
118
|
"""
|
|
108
119
|
Wrapshap implementation of Forward Feature Selection (FFS).
|
|
@@ -133,6 +144,7 @@ def shapFFS(
|
|
|
133
144
|
results = {}
|
|
134
145
|
|
|
135
146
|
_progress_bar(0, len(feature_names), mode='ascending')
|
|
147
|
+
start_time = time()
|
|
136
148
|
|
|
137
149
|
while len(selected_features) < n_features:
|
|
138
150
|
best_score = float('-inf')
|
|
@@ -164,6 +176,7 @@ def shapFFS(
|
|
|
164
176
|
best_metrics[f'test_{key}'] = metrics_test[key]
|
|
165
177
|
for key in metrics_train:
|
|
166
178
|
best_metrics[f'train_{key}'] = metrics_train[key]
|
|
179
|
+
best_metrics['time']=time() - start_time
|
|
167
180
|
|
|
168
181
|
|
|
169
182
|
selected_features.append(best_feature)
|
|
@@ -181,6 +194,8 @@ def shapFFS(
|
|
|
181
194
|
top=top,
|
|
182
195
|
task_type=task_type
|
|
183
196
|
)
|
|
197
|
+
if plot :
|
|
198
|
+
_plot_performance(results, time_info)
|
|
184
199
|
|
|
185
200
|
return selected_features, results
|
|
186
201
|
|
|
@@ -191,7 +206,9 @@ def shapBFE(
|
|
|
191
206
|
feature_names: list,
|
|
192
207
|
surrogate_metrics: bool = False,
|
|
193
208
|
top: int = None,
|
|
194
|
-
task_type: str = 'classification'
|
|
209
|
+
task_type: str = 'classification',
|
|
210
|
+
plot: bool = True,
|
|
211
|
+
time_info: bool = False
|
|
195
212
|
) -> tuple:
|
|
196
213
|
"""
|
|
197
214
|
Wrapshap implementation of Backward Feature Elimination (BFE).
|
|
@@ -222,10 +239,11 @@ def shapBFE(
|
|
|
222
239
|
results = {}
|
|
223
240
|
|
|
224
241
|
_progress_bar(0, len(feature_names), mode='ascending')
|
|
242
|
+
start_time = time()
|
|
225
243
|
|
|
226
244
|
model = LinearRegression()
|
|
227
245
|
model.fit(shap_train, y_pred_train)
|
|
228
|
-
|
|
246
|
+
|
|
229
247
|
lnr_predictions_train = model.predict(shap_train)
|
|
230
248
|
lnr_predictions_test = model.predict(shap_test)
|
|
231
249
|
|
|
@@ -237,9 +255,9 @@ def shapBFE(
|
|
|
237
255
|
results[len(selected_features)][f'test_{key}'] = metrics_test[key]
|
|
238
256
|
for key in metrics_train:
|
|
239
257
|
results[len(selected_features)][f'train_{key}'] = metrics_train[key]
|
|
240
|
-
|
|
241
|
-
_progress_bar(1, len(feature_names), mode='ascending')
|
|
258
|
+
results[len(selected_features)]['time'] = time() - start_time
|
|
242
259
|
|
|
260
|
+
_progress_bar(1, len(feature_names), mode='ascending')
|
|
243
261
|
while len(selected_features) > 1:
|
|
244
262
|
worst_score = float('-inf')
|
|
245
263
|
worst_feature = None
|
|
@@ -267,6 +285,8 @@ def shapBFE(
|
|
|
267
285
|
worst_metrics[f'test_{key}'] = metrics_test[key]
|
|
268
286
|
for key in metrics_train:
|
|
269
287
|
worst_metrics[f'train_{key}'] = metrics_train[key]
|
|
288
|
+
worst_metrics['time'] = time() - start_time
|
|
289
|
+
|
|
270
290
|
|
|
271
291
|
selected_features.remove(worst_feature)
|
|
272
292
|
removed_features.append(worst_feature)
|
|
@@ -287,6 +307,8 @@ def shapBFE(
|
|
|
287
307
|
top=top,
|
|
288
308
|
task_type=task_type
|
|
289
309
|
)
|
|
310
|
+
if plot :
|
|
311
|
+
_plot_performance(results, time_info)
|
|
290
312
|
|
|
291
313
|
return removed_features, results
|
|
292
314
|
|
|
@@ -318,6 +340,7 @@ def get_surrogate_metrics(
|
|
|
318
340
|
"""
|
|
319
341
|
|
|
320
342
|
_progress_bar(0, len(feature_ranking), mode='ascending', suffix='Complete (surrogate metrics computation)')
|
|
343
|
+
start_time = time()
|
|
321
344
|
for i in range(1, len(feature_ranking)+1):
|
|
322
345
|
|
|
323
346
|
model = LinearRegression()
|
|
@@ -339,6 +362,8 @@ def get_surrogate_metrics(
|
|
|
339
362
|
metrics_dict[i][f'test_{key}'] = metrics_test[key]
|
|
340
363
|
for key in metrics_train:
|
|
341
364
|
metrics_dict[i][f'train_{key}'] = metrics_train[key]
|
|
365
|
+
metrics_dict[i]['time'] = time() - start_time
|
|
366
|
+
|
|
342
367
|
_progress_bar(i, len(feature_ranking), mode='ascending', suffix='Complete (surrogate metrics computation)')
|
|
343
368
|
|
|
344
369
|
return metrics_dict
|
|
@@ -404,4 +429,97 @@ def _calculate_metrics(y_true, lnr_predictions, model_predictions, task_type, su
|
|
|
404
429
|
if surrogate:
|
|
405
430
|
metrics = _surrogate_metrics(y_true, lnr_predictions, task_type, metrics)
|
|
406
431
|
|
|
407
|
-
return metrics
|
|
432
|
+
return metrics
|
|
433
|
+
|
|
434
|
+
def _plot_performance(perfs, time_info = True):
|
|
435
|
+
n_features_list = []
|
|
436
|
+
r2_list = []
|
|
437
|
+
time_list = []
|
|
438
|
+
|
|
439
|
+
alpha = 1
|
|
440
|
+
beta= 0.2
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
for n_feat, values in perfs.items():
|
|
444
|
+
n_features_list.append(int(n_feat))
|
|
445
|
+
for metric, value in values.items():
|
|
446
|
+
if metric == 'test_pred_r2':
|
|
447
|
+
r2_list.append(value)
|
|
448
|
+
if metric == 'time':
|
|
449
|
+
time_list.append(value)
|
|
450
|
+
|
|
451
|
+
# Trier par nombre de features
|
|
452
|
+
order = np.argsort(n_features_list)
|
|
453
|
+
n_features = np.array(n_features_list)[order]
|
|
454
|
+
r2_scores = np.array(r2_list)[order]
|
|
455
|
+
time_scores = np.array(time_list)[order]
|
|
456
|
+
|
|
457
|
+
def normalize(x):
|
|
458
|
+
x = np.array(x, dtype=float)
|
|
459
|
+
return (x - x.min()) / (x.max() - x.min() + 1e-9)
|
|
460
|
+
|
|
461
|
+
#r2_norm = normalize(r2_scores) # on veut maximiser -> reste tel quel
|
|
462
|
+
nf_norm = normalize(n_features) # on veut minimiser
|
|
463
|
+
time_norm = normalize(time_scores) # on veut minimiser
|
|
464
|
+
|
|
465
|
+
fig, ax = plt.subplots(figsize=(8, 4))
|
|
466
|
+
fs_scores = []
|
|
467
|
+
for nf, r2, t in zip(nf_norm, r2_scores, time_norm):
|
|
468
|
+
fs_scores.append((r2*alpha - beta*nf))
|
|
469
|
+
|
|
470
|
+
fs_scores = np.array(fs_scores)
|
|
471
|
+
# -------------------------------------------------------
|
|
472
|
+
# AXE 1 — R²
|
|
473
|
+
# -------------------------------------------------------
|
|
474
|
+
|
|
475
|
+
ax.plot(n_features, r2_scores,
|
|
476
|
+
color='steelblue', linewidth=2,
|
|
477
|
+
marker='o', markersize=5, zorder=3, label='Test R²', )
|
|
478
|
+
ax.fill_between(n_features, r2_scores, alpha=0.08, color='steelblue')
|
|
479
|
+
|
|
480
|
+
best_idx = np.argmax(fs_scores)
|
|
481
|
+
ax.scatter(n_features[best_idx], r2_scores[best_idx],
|
|
482
|
+
color='steelblue', zorder=4, s=60, marker='D',
|
|
483
|
+
label=f'FS_score={fs_scores[best_idx]:.3f} ({n_features[best_idx]} features)')
|
|
484
|
+
|
|
485
|
+
ax.set_xlabel('Number of selected features', fontsize=12)
|
|
486
|
+
ax.set_ylabel('Test R²', fontsize=12, color='black')
|
|
487
|
+
ax.tick_params(axis='y', labelcolor='black', labelsize = 8)
|
|
488
|
+
ax.spines['top'].set_visible(False)
|
|
489
|
+
|
|
490
|
+
# -------------------------------------------------------
|
|
491
|
+
# AXE 2 — Computation time
|
|
492
|
+
# -------------------------------------------------------
|
|
493
|
+
if time_info :
|
|
494
|
+
ax2 = ax.twinx() # partage le même axe x
|
|
495
|
+
ax2.plot(n_features, time_scores,
|
|
496
|
+
color='coral', linewidth=2, linestyle='--',
|
|
497
|
+
marker='s', markersize=4, zorder=2, label='Cumulative computation time')
|
|
498
|
+
|
|
499
|
+
ax2.set_ylabel('Cumulative computation time (s)', fontsize=12, color='black')
|
|
500
|
+
ax2.tick_params(axis='y', labelcolor='black', labelsize = 8)
|
|
501
|
+
ax2.spines['top'].set_visible(False)
|
|
502
|
+
|
|
503
|
+
# -------------------------------------------------------
|
|
504
|
+
# LÉGENDE COMBINÉE
|
|
505
|
+
# -------------------------------------------------------
|
|
506
|
+
|
|
507
|
+
lines1, labels1 = ax.get_legend_handles_labels()
|
|
508
|
+
if time_info == True :
|
|
509
|
+
lines2, labels2 = ax2.get_legend_handles_labels()
|
|
510
|
+
ax.legend(lines1 + lines2, labels1 + labels2, fontsize = 10, framealpha=0.5, loc ='lower right' )
|
|
511
|
+
else :
|
|
512
|
+
ax.legend(lines1, labels1, fontsize = 10, framealpha=0.5, loc ='lower right' )
|
|
513
|
+
|
|
514
|
+
ax.set_title('Feature selection — performance vs. parsimony trade-off',
|
|
515
|
+
fontsize=12)
|
|
516
|
+
if len(n_features) > 25:
|
|
517
|
+
ax.set_xticks(n_features[::2])
|
|
518
|
+
ax.set_xticklabels(n_features[::2], rotation=45, fontsize=10)
|
|
519
|
+
if len(n_features) <= 25:
|
|
520
|
+
ax.set_xticks(n_features)
|
|
521
|
+
ax.set_xticklabels(n_features, rotation=45, fontsize=10)
|
|
522
|
+
ax.tick_params(labelsize=10)
|
|
523
|
+
|
|
524
|
+
plt.tight_layout()
|
|
525
|
+
plt.show()
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
from ._internal._already_wrapped import WrappedBinaryClassifierXGB, WrappedRegressorXGB
|
|
2
|
-
from ._internal._already_wrapped_LGB import WrappedBinaryClassifierLGB, WrappedRegressorLGB
|
|
2
|
+
from ._internal._already_wrapped_LGB import WrappedBinaryClassifierLGB, WrappedRegressorLGB
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .wrapshap_gpu import WrapshapGPU, print_XFFS_tree, plot_XFFS_tree
|
{wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/gpu_implementation/_internal/_already_wrapped_gpu.py
RENAMED
|
@@ -40,7 +40,7 @@ class WrappedBinaryClassifierXGB_GPU(WrappedBinaryClassifierXGB):
|
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
@wrapshap_required('wrapshap')
|
|
43
|
-
def shapFFS(self, surrogate_metrics: bool = False, top: int = None):
|
|
43
|
+
def shapFFS(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True, time_info:bool = True):
|
|
44
44
|
"""
|
|
45
45
|
Simply calls Wrapshap GPU implementation of Forward Feature Selection (FFS).
|
|
46
46
|
|
|
@@ -54,11 +54,11 @@ class WrappedBinaryClassifierXGB_GPU(WrappedBinaryClassifierXGB):
|
|
|
54
54
|
dictionary with the corresponding performance metrics.
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
|
-
return self.wrapshap.shapFFS(surrogate_metrics=surrogate_metrics, top=top)
|
|
57
|
+
return self.wrapshap.shapFFS(surrogate_metrics=surrogate_metrics, top=top,plot=plot, time_info = time_info)
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
@wrapshap_required('wrapshap')
|
|
61
|
-
def shapBFE(self, surrogate_metrics: bool = False, top: int = None):
|
|
61
|
+
def shapBFE(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True,time_info:bool = False):
|
|
62
62
|
"""
|
|
63
63
|
Simply calls Wrapshap implementation of Backward Feature Elimination (BFE).
|
|
64
64
|
|
|
@@ -72,7 +72,7 @@ class WrappedBinaryClassifierXGB_GPU(WrappedBinaryClassifierXGB):
|
|
|
72
72
|
dictionary with the corresponding performance metrics.
|
|
73
73
|
"""
|
|
74
74
|
|
|
75
|
-
return self.wrapshap.shapBFE(surrogate_metrics=surrogate_metrics, top=top)
|
|
75
|
+
return self.wrapshap.shapBFE(surrogate_metrics=surrogate_metrics, top=top,plot=plot, time_info=time_info)
|
|
76
76
|
|
|
77
77
|
@wrapshap_required('wrapshap')
|
|
78
78
|
def shapNCK(self, k: int = 2, batch_size: int = 500, selected_features: list = [], top: int = None):
|
|
@@ -138,7 +138,7 @@ class WrappedRegressorXGB_GPU(WrappedRegressorXGB):
|
|
|
138
138
|
)
|
|
139
139
|
|
|
140
140
|
@wrapshap_required('wrapshap')
|
|
141
|
-
def shapFFS(self, surrogate_metrics: bool = False, top: int = None):
|
|
141
|
+
def shapFFS(self, surrogate_metrics: bool = False, top: int = None, plot:bool=True, time_info:bool=True):
|
|
142
142
|
"""
|
|
143
143
|
Simply calls Wrapshap implementation of Forward Feature Selection (FFS).
|
|
144
144
|
|
|
@@ -152,11 +152,11 @@ class WrappedRegressorXGB_GPU(WrappedRegressorXGB):
|
|
|
152
152
|
dictionary with the corresponding performance metrics.
|
|
153
153
|
"""
|
|
154
154
|
|
|
155
|
-
return self.wrapshap.shapFFS(surrogate_metrics=surrogate_metrics, top=top)
|
|
155
|
+
return self.wrapshap.shapFFS(surrogate_metrics=surrogate_metrics, top=top, plot=plot, time_info=time_info)
|
|
156
156
|
|
|
157
157
|
|
|
158
158
|
@wrapshap_required('wrapshap')
|
|
159
|
-
def shapBFE(self, surrogate_metrics: bool = False, top: int = None):
|
|
159
|
+
def shapBFE(self, surrogate_metrics: bool = False, top: int = None, plot=True, time_info:bool= False):
|
|
160
160
|
"""
|
|
161
161
|
Simply calls Wrapshap implementation of Backward Feature Elimination (BFE).
|
|
162
162
|
|
|
@@ -170,7 +170,7 @@ class WrappedRegressorXGB_GPU(WrappedRegressorXGB):
|
|
|
170
170
|
dictionary with the corresponding performance metrics.
|
|
171
171
|
"""
|
|
172
172
|
|
|
173
|
-
return self.wrapshap.shapBFE(surrogate_metrics=surrogate_metrics, top=top)
|
|
173
|
+
return self.wrapshap.shapBFE(surrogate_metrics=surrogate_metrics, top=top, plot=plot, time_info = time_info)
|
|
174
174
|
|
|
175
175
|
|
|
176
176
|
@wrapshap_required('wrapshap')
|
{wrapshap-0.1.1 → wrapshap-0.1.2}/wrapshap/gpu_implementation/_internal/_already_wrapped_lgb_gpu.py
RENAMED
|
@@ -46,7 +46,7 @@ class WrappedBinaryClassifierLGB_GPU(WrappedBinaryClassifierLGB):
|
|
|
46
46
|
)
|
|
47
47
|
|
|
48
48
|
@wrapshap_required('wrapshap')
|
|
49
|
-
def shapFFS(self, surrogate_metrics: bool = False, top: int = None):
|
|
49
|
+
def shapFFS(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True, time_info:bool = True):
|
|
50
50
|
"""
|
|
51
51
|
Simply calls Wrapshap GPU implementation of Forward Feature Selection (FFS).
|
|
52
52
|
|
|
@@ -60,11 +60,11 @@ class WrappedBinaryClassifierLGB_GPU(WrappedBinaryClassifierLGB):
|
|
|
60
60
|
dictionary with the corresponding performance metrics.
|
|
61
61
|
"""
|
|
62
62
|
|
|
63
|
-
return self.wrapshap.shapFFS(surrogate_metrics=surrogate_metrics, top=top)
|
|
63
|
+
return self.wrapshap.shapFFS(surrogate_metrics=surrogate_metrics, top=top, plot= plot, time_info=time_info)
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
@wrapshap_required('wrapshap')
|
|
67
|
-
def shapBFE(self, surrogate_metrics: bool = False, top: int = None):
|
|
67
|
+
def shapBFE(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True, time_info:bool = False):
|
|
68
68
|
"""
|
|
69
69
|
Simply calls Wrapshap implementation of Backward Feature Elimination (BFE).
|
|
70
70
|
|
|
@@ -78,7 +78,7 @@ class WrappedBinaryClassifierLGB_GPU(WrappedBinaryClassifierLGB):
|
|
|
78
78
|
dictionary with the corresponding performance metrics.
|
|
79
79
|
"""
|
|
80
80
|
|
|
81
|
-
return self.wrapshap.shapBFE(surrogate_metrics=surrogate_metrics, top=top)
|
|
81
|
+
return self.wrapshap.shapBFE(surrogate_metrics=surrogate_metrics, top=top, plot= plot)
|
|
82
82
|
|
|
83
83
|
@wrapshap_required('wrapshap')
|
|
84
84
|
def shapNCK(self, k: int = 2, batch_size: int = 500, selected_features: list = [], top: int = None):
|
|
@@ -142,7 +142,7 @@ class WrappedRegressorLGB_GPU(WrappedRegressorLGB):
|
|
|
142
142
|
)
|
|
143
143
|
|
|
144
144
|
@wrapshap_required('wrapshap')
|
|
145
|
-
def shapFFS(self, surrogate_metrics: bool = False, top: int = None):
|
|
145
|
+
def shapFFS(self, surrogate_metrics: bool = False, top: int = None, plot:bool = True, time_info:bool=True):
|
|
146
146
|
"""
|
|
147
147
|
Simply calls Wrapshap implementation of Forward Feature Selection (FFS).
|
|
148
148
|
|
|
@@ -156,11 +156,11 @@ class WrappedRegressorLGB_GPU(WrappedRegressorLGB):
|
|
|
156
156
|
dictionary with the corresponding performance metrics.
|
|
157
157
|
"""
|
|
158
158
|
|
|
159
|
-
return self.wrapshap.shapFFS(surrogate_metrics=surrogate_metrics, top=top)
|
|
159
|
+
return self.wrapshap.shapFFS(surrogate_metrics=surrogate_metrics, top=top, plot=plot, time_info = time_info)
|
|
160
160
|
|
|
161
161
|
|
|
162
162
|
@wrapshap_required('wrapshap')
|
|
163
|
-
def shapBFE(self, surrogate_metrics: bool = False, top: int = None):
|
|
163
|
+
def shapBFE(self, surrogate_metrics: bool = False, top: int = None, plot: bool = True, time_info:bool=False):
|
|
164
164
|
"""
|
|
165
165
|
Simply calls Wrapshap implementation of Backward Feature Elimination (BFE).
|
|
166
166
|
|
|
@@ -174,7 +174,7 @@ class WrappedRegressorLGB_GPU(WrappedRegressorLGB):
|
|
|
174
174
|
dictionary with the corresponding performance metrics.
|
|
175
175
|
"""
|
|
176
176
|
|
|
177
|
-
return self.wrapshap.shapBFE(surrogate_metrics=surrogate_metrics, top=top)
|
|
177
|
+
return self.wrapshap.shapBFE(surrogate_metrics=surrogate_metrics, top=top, plot=plot, time_info = time_info)
|
|
178
178
|
|
|
179
179
|
|
|
180
180
|
@wrapshap_required('wrapshap')
|