wrapevofs 0.2.0__py3-none-any.whl
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.
- wrapevofs/__init__.py +63 -0
- wrapevofs/_scoring.py +35 -0
- wrapevofs/_version.py +5 -0
- wrapevofs/artifacts.py +193 -0
- wrapevofs/cli.py +158 -0
- wrapevofs/config.py +306 -0
- wrapevofs/locking.py +663 -0
- wrapevofs/pipeline.py +360 -0
- wrapevofs/preprocessing.py +153 -0
- wrapevofs/selectors/__init__.py +16 -0
- wrapevofs/selectors/_result.py +27 -0
- wrapevofs/selectors/boruta_rf.py +70 -0
- wrapevofs/selectors/genetic_rf.py +1348 -0
- wrapevofs/selectors/rfecv_target.py +162 -0
- wrapevofs/selectors/svm_l1_wrapper.py +112 -0
- wrapevofs/selectors/xgboost_wrapper.py +105 -0
- wrapevofs/split.py +115 -0
- wrapevofs/validation.py +98 -0
- wrapevofs-0.2.0.dist-info/METADATA +140 -0
- wrapevofs-0.2.0.dist-info/RECORD +24 -0
- wrapevofs-0.2.0.dist-info/WHEEL +5 -0
- wrapevofs-0.2.0.dist-info/entry_points.txt +2 -0
- wrapevofs-0.2.0.dist-info/licenses/LICENSE +29 -0
- wrapevofs-0.2.0.dist-info/top_level.txt +1 -0
wrapevofs/__init__.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Public API for wrapevofs."""
|
|
2
|
+
|
|
3
|
+
from wrapevofs._version import (
|
|
4
|
+
ARTIFACT_SCHEMA_VERSION,
|
|
5
|
+
CONFIG_SCHEMA_VERSION,
|
|
6
|
+
__version__,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from wrapevofs.config import (
|
|
10
|
+
BorutaRFWrapperConfig,
|
|
11
|
+
FirstStageConfig,
|
|
12
|
+
GAConfig,
|
|
13
|
+
LockingConfig,
|
|
14
|
+
PipelineConfig,
|
|
15
|
+
PreprocessingConfig,
|
|
16
|
+
RFECVConfig,
|
|
17
|
+
ScoringConfig,
|
|
18
|
+
SplitConfig,
|
|
19
|
+
SVML1WrapperConfig,
|
|
20
|
+
XGBoostWrapperConfig,
|
|
21
|
+
)
|
|
22
|
+
from wrapevofs.pipeline import WrapEvoPipeline, PipelineResult, PreparedData
|
|
23
|
+
from wrapevofs.locking import (
|
|
24
|
+
LockingCandidate,
|
|
25
|
+
LockingResult,
|
|
26
|
+
lock_representative_run,
|
|
27
|
+
score_candidate_feature_sets,
|
|
28
|
+
)
|
|
29
|
+
from wrapevofs.preprocessing import TabularPreprocessor
|
|
30
|
+
from wrapevofs.validation import validate_locking_artifact_directory
|
|
31
|
+
from wrapevofs.selectors.genetic_rf import GASolution, GeneticRFResult, run_genetic_rf
|
|
32
|
+
from wrapevofs.split import parse_split_ratio, train_test_split_frame
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"ARTIFACT_SCHEMA_VERSION",
|
|
36
|
+
"BorutaRFWrapperConfig",
|
|
37
|
+
"CONFIG_SCHEMA_VERSION",
|
|
38
|
+
"FirstStageConfig",
|
|
39
|
+
"GAConfig",
|
|
40
|
+
"LockingConfig",
|
|
41
|
+
"LockingCandidate",
|
|
42
|
+
"LockingResult",
|
|
43
|
+
"GASolution",
|
|
44
|
+
"WrapEvoPipeline",
|
|
45
|
+
"GeneticRFResult",
|
|
46
|
+
"PipelineConfig",
|
|
47
|
+
"PipelineResult",
|
|
48
|
+
"PreparedData",
|
|
49
|
+
"PreprocessingConfig",
|
|
50
|
+
"RFECVConfig",
|
|
51
|
+
"ScoringConfig",
|
|
52
|
+
"SVML1WrapperConfig",
|
|
53
|
+
"SplitConfig",
|
|
54
|
+
"TabularPreprocessor",
|
|
55
|
+
"XGBoostWrapperConfig",
|
|
56
|
+
"parse_split_ratio",
|
|
57
|
+
"train_test_split_frame",
|
|
58
|
+
"validate_locking_artifact_directory",
|
|
59
|
+
"run_genetic_rf",
|
|
60
|
+
"lock_representative_run",
|
|
61
|
+
"score_candidate_feature_sets",
|
|
62
|
+
"__version__",
|
|
63
|
+
]
|
wrapevofs/_scoring.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Scoring helpers shared by wrapper and RFECV selectors."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def unique_classes(y: Any) -> np.ndarray:
|
|
11
|
+
"""Return sorted unique class labels from a pandas or numpy target vector."""
|
|
12
|
+
|
|
13
|
+
values = y.to_numpy() if hasattr(y, "to_numpy") else y
|
|
14
|
+
return np.unique(np.asarray(values))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def infer_problem_type(y: Any) -> str:
|
|
18
|
+
"""Infer whether a classification target is binary or multiclass."""
|
|
19
|
+
|
|
20
|
+
classes = unique_classes(y)
|
|
21
|
+
return "binary" if len(classes) <= 2 else "multiclass"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def resolve_auto_scoring(
|
|
25
|
+
scoring: str,
|
|
26
|
+
y: Any,
|
|
27
|
+
*,
|
|
28
|
+
binary: str,
|
|
29
|
+
multiclass: str,
|
|
30
|
+
) -> str:
|
|
31
|
+
"""Resolve ``scoring='auto'`` from the observed number of target classes."""
|
|
32
|
+
|
|
33
|
+
if scoring != "auto":
|
|
34
|
+
return scoring
|
|
35
|
+
return binary if infer_problem_type(y) == "binary" else multiclass
|
wrapevofs/_version.py
ADDED
wrapevofs/artifacts.py
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"""Artifact writing helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from dataclasses import asdict, is_dataclass
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
import pandas as pd
|
|
12
|
+
|
|
13
|
+
from wrapevofs.pipeline import PipelineResult, PreparedData
|
|
14
|
+
from wrapevofs._version import ARTIFACT_SCHEMA_VERSION, __version__
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _json_default(value: Any) -> Any:
|
|
18
|
+
if is_dataclass(value):
|
|
19
|
+
return asdict(value)
|
|
20
|
+
if hasattr(value, "tolist"):
|
|
21
|
+
return value.tolist()
|
|
22
|
+
return str(value)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def save_prepared_data(prepared: PreparedData, output_dir: str | Path) -> None:
|
|
26
|
+
output = Path(output_dir)
|
|
27
|
+
output.mkdir(parents=True, exist_ok=True)
|
|
28
|
+
prepared.X_train.to_csv(output / "X_train.csv", index=False)
|
|
29
|
+
prepared.X_test.to_csv(output / "X_test.csv", index=False)
|
|
30
|
+
prepared.y_train.to_frame("target").to_csv(output / "y_train.csv", index=False)
|
|
31
|
+
prepared.y_test.to_frame("target").to_csv(output / "y_test.csv", index=False)
|
|
32
|
+
with (output / "preprocessing_report.json").open("w", encoding="utf-8") as handle:
|
|
33
|
+
json.dump(asdict(prepared.preprocessor.report), handle, indent=2)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def save_pipeline_result(result: PipelineResult, output_dir: str | Path) -> None:
|
|
37
|
+
output = Path(output_dir)
|
|
38
|
+
output.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
with (output / "software_metadata.json").open("w", encoding="utf-8") as handle:
|
|
40
|
+
json.dump(
|
|
41
|
+
{
|
|
42
|
+
"software_name": "wrapevofs",
|
|
43
|
+
"software_version": __version__,
|
|
44
|
+
"artifact_schema_version": ARTIFACT_SCHEMA_VERSION,
|
|
45
|
+
},
|
|
46
|
+
handle,
|
|
47
|
+
indent=2,
|
|
48
|
+
)
|
|
49
|
+
save_prepared_data(result.prepared, output / "preprocessed")
|
|
50
|
+
for name, selection in result.first_stage.items():
|
|
51
|
+
method_dir = output / "first_stage" / name
|
|
52
|
+
method_dir.mkdir(parents=True, exist_ok=True)
|
|
53
|
+
selection.feature_table.to_csv(method_dir / "feature_table.csv", index=False)
|
|
54
|
+
pd.DataFrame({"feature": selection.selected_features}).to_csv(
|
|
55
|
+
method_dir / "selected_features.csv",
|
|
56
|
+
index=False,
|
|
57
|
+
)
|
|
58
|
+
np.save(
|
|
59
|
+
method_dir / "selected_features.npy",
|
|
60
|
+
np.asarray(selection.selected_features, dtype=str),
|
|
61
|
+
)
|
|
62
|
+
with (method_dir / "metadata.json").open("w", encoding="utf-8") as handle:
|
|
63
|
+
json.dump(selection.metadata, handle, indent=2, default=_json_default)
|
|
64
|
+
|
|
65
|
+
for name, target in result.rfecv_targets.items():
|
|
66
|
+
method_dir = output / "rfecv" / name
|
|
67
|
+
method_dir.mkdir(parents=True, exist_ok=True)
|
|
68
|
+
target.score_table.to_csv(method_dir / "score_table.csv", index=False)
|
|
69
|
+
summary = {
|
|
70
|
+
"target_k": target.target_k,
|
|
71
|
+
"target_score": target.target_score,
|
|
72
|
+
"global_best_k": target.global_best_k,
|
|
73
|
+
"global_best_score": target.global_best_score,
|
|
74
|
+
"selected_features_at_target": target.selected_features_at_target,
|
|
75
|
+
"metadata": target.metadata,
|
|
76
|
+
}
|
|
77
|
+
np.save(
|
|
78
|
+
method_dir / "target_features.npy",
|
|
79
|
+
np.asarray(target.selected_features_at_target, dtype=str),
|
|
80
|
+
)
|
|
81
|
+
np.save(
|
|
82
|
+
method_dir / "global_best_features.npy",
|
|
83
|
+
np.asarray(target.selected_features_at_global_best, dtype=str),
|
|
84
|
+
)
|
|
85
|
+
with (method_dir / "summary.json").open("w", encoding="utf-8") as handle:
|
|
86
|
+
json.dump(summary, handle, indent=2, default=_json_default)
|
|
87
|
+
|
|
88
|
+
final_feature_sets: dict[str, list[Any]] = {}
|
|
89
|
+
best_feature_sets: dict[str, list[str]] = {}
|
|
90
|
+
for name, ga_result in result.ga_results.items():
|
|
91
|
+
method_dir = output / "ga" / name
|
|
92
|
+
method_dir.mkdir(parents=True, exist_ok=True)
|
|
93
|
+
rows = []
|
|
94
|
+
for solution in ga_result.top_solutions:
|
|
95
|
+
rows.append(
|
|
96
|
+
{
|
|
97
|
+
"rank": solution.rank,
|
|
98
|
+
"run_id": solution.run_id,
|
|
99
|
+
"score": solution.score,
|
|
100
|
+
"base_score": solution.base_score,
|
|
101
|
+
"n_features": solution.n_features,
|
|
102
|
+
"selected_features": "|".join(solution.selected_features),
|
|
103
|
+
"raw_objective": solution.raw_objective,
|
|
104
|
+
"legacy_truncated_fitness": solution.legacy_truncated_fitness,
|
|
105
|
+
"target_deviation": solution.target_deviation,
|
|
106
|
+
"penalty_amount": solution.penalty_amount,
|
|
107
|
+
"stable_mask_hash": solution.stable_mask_hash,
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
pd.DataFrame(rows).to_csv(method_dir / "top_solutions.csv", index=False)
|
|
111
|
+
if not ga_result.history.empty:
|
|
112
|
+
ga_result.history.to_csv(method_dir / "history.csv", index=False)
|
|
113
|
+
top_feature_sets = np.asarray(
|
|
114
|
+
[np.asarray(item.selected_features, dtype=str) for item in ga_result.top_solutions],
|
|
115
|
+
dtype=object,
|
|
116
|
+
)
|
|
117
|
+
top_masks = np.asarray([item.mask for item in ga_result.top_solutions], dtype=bool)
|
|
118
|
+
np.save(method_dir / "top_feature_sets.npy", top_feature_sets, allow_pickle=True)
|
|
119
|
+
np.save(method_dir / "top_masks.npy", top_masks)
|
|
120
|
+
np.save(
|
|
121
|
+
method_dir / "scores.npy",
|
|
122
|
+
np.asarray([item.score for item in ga_result.top_solutions], dtype=float),
|
|
123
|
+
)
|
|
124
|
+
if ga_result.top_solutions:
|
|
125
|
+
np.save(
|
|
126
|
+
method_dir / "best_feature_set.npy",
|
|
127
|
+
np.asarray(ga_result.best_solution.selected_features, dtype=str),
|
|
128
|
+
)
|
|
129
|
+
np.save(method_dir / "best_mask.npy", ga_result.best_solution.mask)
|
|
130
|
+
best_feature_sets[name] = ga_result.best_solution.selected_features
|
|
131
|
+
final_feature_sets[name] = [
|
|
132
|
+
solution.selected_features for solution in ga_result.top_solutions
|
|
133
|
+
]
|
|
134
|
+
summary = {
|
|
135
|
+
"name": ga_result.name,
|
|
136
|
+
"target_k": ga_result.target_k,
|
|
137
|
+
"best_score": ga_result.best_solution.score if ga_result.top_solutions else None,
|
|
138
|
+
"best_n_features": (
|
|
139
|
+
ga_result.best_solution.n_features if ga_result.top_solutions else None
|
|
140
|
+
),
|
|
141
|
+
"metadata": ga_result.metadata,
|
|
142
|
+
"warnings": ga_result.warnings,
|
|
143
|
+
}
|
|
144
|
+
with (method_dir / "summary.json").open("w", encoding="utf-8") as handle:
|
|
145
|
+
json.dump(summary, handle, indent=2, default=_json_default)
|
|
146
|
+
|
|
147
|
+
locked_feature_sets: dict[str, list[str]] = {}
|
|
148
|
+
for name, locking_result in result.locking_results.items():
|
|
149
|
+
method_dir = output / "locking" / name
|
|
150
|
+
method_dir.mkdir(parents=True, exist_ok=True)
|
|
151
|
+
locking_result.candidate_audit.to_csv(
|
|
152
|
+
method_dir / "locking_candidate_audit.csv",
|
|
153
|
+
index=False,
|
|
154
|
+
)
|
|
155
|
+
locking_result.pairwise_jaccard.to_csv(
|
|
156
|
+
method_dir / "pairwise_jaccard.csv",
|
|
157
|
+
index=False,
|
|
158
|
+
)
|
|
159
|
+
pd.DataFrame({"feature": locking_result.selected_features}).to_csv(
|
|
160
|
+
method_dir / "selected_features.csv",
|
|
161
|
+
index=False,
|
|
162
|
+
)
|
|
163
|
+
np.save(
|
|
164
|
+
method_dir / "selected_features.npy",
|
|
165
|
+
np.asarray(locking_result.selected_features, dtype=str),
|
|
166
|
+
)
|
|
167
|
+
with (method_dir / "summary.json").open("w", encoding="utf-8") as handle:
|
|
168
|
+
json.dump(locking_result.metadata, handle, indent=2, default=_json_default)
|
|
169
|
+
locked_feature_sets[name] = list(locking_result.selected_features)
|
|
170
|
+
|
|
171
|
+
if locked_feature_sets:
|
|
172
|
+
final_feature_sets = locked_feature_sets
|
|
173
|
+
np.save(output / "locked_feature_sets.npy", locked_feature_sets, allow_pickle=True)
|
|
174
|
+
elif not final_feature_sets:
|
|
175
|
+
if result.rfecv_targets:
|
|
176
|
+
final_feature_sets = {
|
|
177
|
+
name: target.selected_features_at_target
|
|
178
|
+
for name, target in result.rfecv_targets.items()
|
|
179
|
+
}
|
|
180
|
+
else:
|
|
181
|
+
final_feature_sets = {
|
|
182
|
+
name: selection.selected_features
|
|
183
|
+
for name, selection in result.first_stage.items()
|
|
184
|
+
}
|
|
185
|
+
if best_feature_sets:
|
|
186
|
+
np.save(output / "best_feature_sets.npy", best_feature_sets, allow_pickle=True)
|
|
187
|
+
np.save(output / "final_feature_sets.npy", final_feature_sets, allow_pickle=True)
|
|
188
|
+
|
|
189
|
+
exported_warnings = list(result.warnings)
|
|
190
|
+
for name, ga_result in result.ga_results.items():
|
|
191
|
+
exported_warnings.extend(f"{name}: {message}" for message in ga_result.warnings)
|
|
192
|
+
with (output / "warnings.json").open("w", encoding="utf-8") as handle:
|
|
193
|
+
json.dump(exported_warnings, handle, indent=2)
|
wrapevofs/cli.py
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""Command-line entry point."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import pandas as pd
|
|
9
|
+
|
|
10
|
+
from wrapevofs.artifacts import save_pipeline_result
|
|
11
|
+
from wrapevofs.config import PipelineConfig
|
|
12
|
+
from wrapevofs.pipeline import WrapEvoPipeline
|
|
13
|
+
from wrapevofs._version import __version__
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
17
|
+
parser = argparse.ArgumentParser(prog="wrapevofs")
|
|
18
|
+
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
|
19
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
20
|
+
|
|
21
|
+
run = subparsers.add_parser("run", help="Run preprocessing through RFECV target discovery.")
|
|
22
|
+
run.add_argument("--csv", required=True, help="Input CSV containing features and target.")
|
|
23
|
+
run.add_argument("--target", required=True, help="Target column name.")
|
|
24
|
+
run.add_argument("--out", required=True, help="Output directory.")
|
|
25
|
+
run.add_argument("--config", help="YAML config path.")
|
|
26
|
+
run.add_argument("--ratio", help="Override split ratio, for example 7:3, 6:4, 8:2.")
|
|
27
|
+
run.add_argument("--impute", choices=["median", "mean", "zero"], help="Override imputation strategy.")
|
|
28
|
+
run.add_argument(
|
|
29
|
+
"--rfecv-max-features",
|
|
30
|
+
type=int,
|
|
31
|
+
help="Override RFECV compact cap for all wrapper branches.",
|
|
32
|
+
)
|
|
33
|
+
run.add_argument("--xgb-rfecv-max", type=int, help="RFECV compact cap for the xgboost branch.")
|
|
34
|
+
run.add_argument("--svm-rfecv-max", type=int, help="RFECV compact cap for the svm_l1 branch.")
|
|
35
|
+
run.add_argument("--boruta-rfecv-max", type=int, help="RFECV compact cap for the boruta_rf branch.")
|
|
36
|
+
run.add_argument("--methods", help="Comma-separated methods: svm_l1,xgboost,boruta_rf.")
|
|
37
|
+
run.add_argument("--drop-columns", help="Comma-separated non-feature columns to drop.")
|
|
38
|
+
run.add_argument(
|
|
39
|
+
"--ga-backend",
|
|
40
|
+
choices=["auto", "cpu", "gpu"],
|
|
41
|
+
help="Override GA Random Forest evaluator backend.",
|
|
42
|
+
)
|
|
43
|
+
run.add_argument(
|
|
44
|
+
"--ga-fitness-mode",
|
|
45
|
+
choices=["legacy_zero_truncated_linear", "untruncated_shifted_linear"],
|
|
46
|
+
help="GA ranking objective; archived configurations use the legacy mode.",
|
|
47
|
+
)
|
|
48
|
+
run.add_argument(
|
|
49
|
+
"--locking-strategy",
|
|
50
|
+
choices=["top_k_jaccard_medoid", "regret_constrained_medoid"],
|
|
51
|
+
help="Enable development-only representative-run locking with this strategy.",
|
|
52
|
+
)
|
|
53
|
+
run.add_argument(
|
|
54
|
+
"--locking-tolerance-mode",
|
|
55
|
+
choices=["absolute", "relative", "best_run_se_scaled", "one_se"],
|
|
56
|
+
help="Regret eligibility mode for regret-constrained locking.",
|
|
57
|
+
)
|
|
58
|
+
run.add_argument("--regret-tolerance", type=float, help="Development-CV regret tolerance.")
|
|
59
|
+
run.add_argument(
|
|
60
|
+
"--minimum-pool-size",
|
|
61
|
+
type=int,
|
|
62
|
+
help="Compatibility option; strict regret-constrained locking requires 1.",
|
|
63
|
+
)
|
|
64
|
+
run.add_argument(
|
|
65
|
+
"--unified-metric",
|
|
66
|
+
choices=["accuracy", "balanced_accuracy", "roc_auc", "macro_ovr_auroc"],
|
|
67
|
+
help="Apply one compatible metric across RFECV, GA, and locking.",
|
|
68
|
+
)
|
|
69
|
+
run.add_argument("--run-ga", action="store_true", help="Continue from RFECV target discovery into GA-RF.")
|
|
70
|
+
run.add_argument(
|
|
71
|
+
"--resume",
|
|
72
|
+
action="store_true",
|
|
73
|
+
help=(
|
|
74
|
+
"Resume GA state from each branch checkpoint directory. Fails on "
|
|
75
|
+
"missing, corrupt, version-, configuration-, feature-, or input-mismatched state."
|
|
76
|
+
),
|
|
77
|
+
)
|
|
78
|
+
return parser
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def main(argv: list[str] | None = None) -> int:
|
|
82
|
+
args = build_parser().parse_args(argv)
|
|
83
|
+
if args.command == "run":
|
|
84
|
+
config = PipelineConfig.from_yaml(args.config) if args.config else PipelineConfig()
|
|
85
|
+
if args.ratio:
|
|
86
|
+
config.split.ratio = args.ratio
|
|
87
|
+
if args.impute:
|
|
88
|
+
config.preprocessing.impute_strategy = args.impute
|
|
89
|
+
if args.rfecv_max_features is not None:
|
|
90
|
+
config.rfecv.max_features_to_consider = args.rfecv_max_features
|
|
91
|
+
for method in config.rfecv.method_max_features_to_consider:
|
|
92
|
+
config.rfecv.method_max_features_to_consider[method] = args.rfecv_max_features
|
|
93
|
+
if args.xgb_rfecv_max is not None:
|
|
94
|
+
config.rfecv.method_max_features_to_consider["xgboost"] = args.xgb_rfecv_max
|
|
95
|
+
if args.svm_rfecv_max is not None:
|
|
96
|
+
config.rfecv.method_max_features_to_consider["svm_l1"] = args.svm_rfecv_max
|
|
97
|
+
if args.boruta_rfecv_max is not None:
|
|
98
|
+
config.rfecv.method_max_features_to_consider["boruta_rf"] = args.boruta_rfecv_max
|
|
99
|
+
if args.ga_backend:
|
|
100
|
+
config.ga.backend = args.ga_backend
|
|
101
|
+
if args.ga_fitness_mode:
|
|
102
|
+
config.ga.fitness_mode = args.ga_fitness_mode
|
|
103
|
+
if args.locking_strategy:
|
|
104
|
+
config.locking.enabled = True
|
|
105
|
+
config.locking.strategy = args.locking_strategy
|
|
106
|
+
if args.locking_tolerance_mode:
|
|
107
|
+
config.locking.tolerance_mode = args.locking_tolerance_mode
|
|
108
|
+
if args.regret_tolerance is not None:
|
|
109
|
+
config.locking.regret_tolerance = args.regret_tolerance
|
|
110
|
+
if args.minimum_pool_size is not None:
|
|
111
|
+
config.locking.minimum_pool_size = args.minimum_pool_size
|
|
112
|
+
if args.unified_metric:
|
|
113
|
+
config.scoring.unified_metric = args.unified_metric
|
|
114
|
+
if args.resume:
|
|
115
|
+
if not args.run_ga:
|
|
116
|
+
raise SystemExit("--resume requires --run-ga.")
|
|
117
|
+
config.ga.resume_from_checkpoint = True
|
|
118
|
+
methods = args.methods.split(",") if args.methods else None
|
|
119
|
+
drop_columns = args.drop_columns.split(",") if args.drop_columns else None
|
|
120
|
+
|
|
121
|
+
df = pd.read_csv(args.csv)
|
|
122
|
+
output_dir = Path(args.out)
|
|
123
|
+
if args.run_ga:
|
|
124
|
+
config.ga.checkpoint_dir = str(output_dir)
|
|
125
|
+
pipeline = WrapEvoPipeline(config)
|
|
126
|
+
if args.run_ga:
|
|
127
|
+
result = pipeline.run_until_rfecv(
|
|
128
|
+
df=df,
|
|
129
|
+
target_column=args.target,
|
|
130
|
+
drop_columns=drop_columns,
|
|
131
|
+
methods=methods,
|
|
132
|
+
)
|
|
133
|
+
save_pipeline_result(result, output_dir)
|
|
134
|
+
result.ga_results = pipeline.run_ga(
|
|
135
|
+
result.prepared,
|
|
136
|
+
result.first_stage,
|
|
137
|
+
result.rfecv_targets,
|
|
138
|
+
)
|
|
139
|
+
result.locking_results = pipeline.run_locking(
|
|
140
|
+
result.prepared,
|
|
141
|
+
result.first_stage,
|
|
142
|
+
result.ga_results,
|
|
143
|
+
)
|
|
144
|
+
result.warnings = list(pipeline.warnings)
|
|
145
|
+
else:
|
|
146
|
+
result = pipeline.run_until_rfecv(
|
|
147
|
+
df=df,
|
|
148
|
+
target_column=args.target,
|
|
149
|
+
drop_columns=drop_columns,
|
|
150
|
+
methods=methods,
|
|
151
|
+
)
|
|
152
|
+
save_pipeline_result(result, output_dir)
|
|
153
|
+
return 0
|
|
154
|
+
return 1
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
if __name__ == "__main__":
|
|
158
|
+
raise SystemExit(main())
|