PyIAML 1.0.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.
- iaml/__init__.py +56 -0
- iaml/actionable.py +11 -0
- iaml/actionables/__init__.py +21 -0
- iaml/actionables/boosting/__init__.py +4 -0
- iaml/actionables/boosting/act_adaboost.py +59 -0
- iaml/actionables/cleaning/__init__.py +26 -0
- iaml/actionables/cleaning/act_categorical_imputer.py +124 -0
- iaml/actionables/cleaning/act_count_vectorizer.py +204 -0
- iaml/actionables/cleaning/act_drop_categorical_column.py +51 -0
- iaml/actionables/cleaning/act_drop_date_column.py +48 -0
- iaml/actionables/cleaning/act_drop_high_cardinality_categorical.py +337 -0
- iaml/actionables/cleaning/act_drop_numerical_column.py +75 -0
- iaml/actionables/cleaning/act_drop_textual_column.py +51 -0
- iaml/actionables/cleaning/act_encode_target_column.py +56 -0
- iaml/actionables/cleaning/act_frequency_encoder.py +127 -0
- iaml/actionables/cleaning/act_hashing_vectorizer.py +186 -0
- iaml/actionables/cleaning/act_knn_imputer.py +152 -0
- iaml/actionables/cleaning/act_mean_column.py +79 -0
- iaml/actionables/cleaning/act_mice.py +464 -0
- iaml/actionables/cleaning/act_missing_count_feature.py +109 -0
- iaml/actionables/cleaning/act_missing_indicator.py +124 -0
- iaml/actionables/cleaning/act_onehot.py +65 -0
- iaml/actionables/cleaning/act_ordinal_encoder.py +177 -0
- iaml/actionables/cleaning/act_rare_category_grouper.py +173 -0
- iaml/actionables/cleaning/act_simple_imputer.py +109 -0
- iaml/actionables/cleaning/act_split_date.py +68 -0
- iaml/actionables/cleaning/act_target_encoder.py +274 -0
- iaml/actionables/cleaning/act_text_normalizer.py +241 -0
- iaml/actionables/cleaning/act_tf_idf.py +80 -0
- iaml/actionables/cleaning/act_word2vec.py +150 -0
- iaml/actionables/features_precleaning/__init__.py +12 -0
- iaml/actionables/features_precleaning/act_coerce_numeric_strings.py +194 -0
- iaml/actionables/features_precleaning/act_date_converter.py +99 -0
- iaml/actionables/features_precleaning/act_drop_bad_quality_rows.py +77 -0
- iaml/actionables/features_precleaning/act_drop_duplicate_rows.py +131 -0
- iaml/actionables/features_precleaning/act_drop_high_missing_columns.py +94 -0
- iaml/actionables/features_precleaning/act_drop_id_like_columns.py +294 -0
- iaml/actionables/features_precleaning/act_normalize_column_names.py +157 -0
- iaml/actionables/features_precleaning/act_sentinel_to_na_n.py +270 -0
- iaml/actionables/features_precleaning/act_trim_space.py +79 -0
- iaml/actionables/features_preprocessing/__init__.py +18 -0
- iaml/actionables/features_preprocessing/act_cyclical_date_encoding.py +212 -0
- iaml/actionables/features_preprocessing/act_fast_ica.py +161 -0
- iaml/actionables/features_preprocessing/act_feature_agglomeration.py +90 -0
- iaml/actionables/features_preprocessing/act_k_bins_discretizer.py +207 -0
- iaml/actionables/features_preprocessing/act_k_means_features.py +296 -0
- iaml/actionables/features_preprocessing/act_kernel_pca.py +143 -0
- iaml/actionables/features_preprocessing/act_log_transformer.py +122 -0
- iaml/actionables/features_preprocessing/act_nystroem.py +100 -0
- iaml/actionables/features_preprocessing/act_pca.py +77 -0
- iaml/actionables/features_preprocessing/act_polynomial_features.py +86 -0
- iaml/actionables/features_preprocessing/act_power_transformer.py +106 -0
- iaml/actionables/features_preprocessing/act_quantile_transformer.py +114 -0
- iaml/actionables/features_preprocessing/act_rbf_sampler.py +88 -0
- iaml/actionables/features_preprocessing/act_select_percentile.py +112 -0
- iaml/actionables/features_preprocessing/act_sparse_random_projection.py +157 -0
- iaml/actionables/features_preprocessing/act_truncated_svd.py +137 -0
- iaml/actionables/features_selection/__init__.py +8 -0
- iaml/actionables/features_selection/act_permutation_importance_selector.py +421 -0
- iaml/actionables/features_selection/act_remove_high_correlated_column.py +70 -0
- iaml/actionables/features_selection/act_remove_low_variance_column.py +74 -0
- iaml/actionables/features_selection/act_rfe.py +214 -0
- iaml/actionables/features_selection/act_select_from_model.py +325 -0
- iaml/actionables/features_selection/act_select_k_best.py +181 -0
- iaml/actionables/features_selection/act_vif_selector.py +130 -0
- iaml/actionables/imbalance/__init__.py +10 -0
- iaml/actionables/imbalance/act_adasyn.py +150 -0
- iaml/actionables/imbalance/act_borderline_smote.py +171 -0
- iaml/actionables/imbalance/act_near_miss.py +158 -0
- iaml/actionables/imbalance/act_random_over_sampling.py +60 -0
- iaml/actionables/imbalance/act_random_under_sampler.py +135 -0
- iaml/actionables/imbalance/act_smote.py +162 -0
- iaml/actionables/imbalance/act_smote_tomek.py +182 -0
- iaml/actionables/imbalance/act_smoteenn.py +193 -0
- iaml/actionables/imbalance/act_tomek_links.py +138 -0
- iaml/actionables/normalize/__init__.py +6 -0
- iaml/actionables/normalize/act_max_abs_scaler.py +78 -0
- iaml/actionables/normalize/act_minmax_scaler.py +56 -0
- iaml/actionables/normalize/act_normalizer.py +95 -0
- iaml/actionables/normalize/act_robust_scaler.py +111 -0
- iaml/actionables/normalize/act_standard_scaler.py +55 -0
- iaml/actionables/predictors/__init__.py +6 -0
- iaml/actionables/predictors/_xgboost.py +16 -0
- iaml/actionables/predictors/classifier/__init__.py +26 -0
- iaml/actionables/predictors/classifier/act_bagging_classifier.py +113 -0
- iaml/actionables/predictors/classifier/act_bernoulli_nb.py +89 -0
- iaml/actionables/predictors/classifier/act_catboost_classifier.py +135 -0
- iaml/actionables/predictors/classifier/act_complement_nb.py +106 -0
- iaml/actionables/predictors/classifier/act_decision_tree_classifier.py +117 -0
- iaml/actionables/predictors/classifier/act_extra_trees_classifier.py +115 -0
- iaml/actionables/predictors/classifier/act_gaussian_nb.py +53 -0
- iaml/actionables/predictors/classifier/act_hist_gradient_boosting_classifier.py +144 -0
- iaml/actionables/predictors/classifier/act_knn.py +86 -0
- iaml/actionables/predictors/classifier/act_light_gbm_classifier.py +211 -0
- iaml/actionables/predictors/classifier/act_linear_discriminant_analysis.py +63 -0
- iaml/actionables/predictors/classifier/act_linear_svc.py +134 -0
- iaml/actionables/predictors/classifier/act_logistic_regression.py +92 -0
- iaml/actionables/predictors/classifier/act_mlp_classifier.py +107 -0
- iaml/actionables/predictors/classifier/act_multinomial_nb.py +76 -0
- iaml/actionables/predictors/classifier/act_passive_aggressive_classifier.py +141 -0
- iaml/actionables/predictors/classifier/act_quadratic_discriminant_analysis.py +72 -0
- iaml/actionables/predictors/classifier/act_randomforest.py +113 -0
- iaml/actionables/predictors/classifier/act_ridge_classifier.py +116 -0
- iaml/actionables/predictors/classifier/act_sgd_classifier.py +149 -0
- iaml/actionables/predictors/classifier/act_svm_svc.py +88 -0
- iaml/actionables/predictors/classifier/act_xgboost.py +111 -0
- iaml/actionables/predictors/regressor/__init__.py +27 -0
- iaml/actionables/predictors/regressor/act_ada_boost_regressor.py +75 -0
- iaml/actionables/predictors/regressor/act_ard_regression.py +95 -0
- iaml/actionables/predictors/regressor/act_catboost_regressor.py +134 -0
- iaml/actionables/predictors/regressor/act_decision_tree_regressor.py +111 -0
- iaml/actionables/predictors/regressor/act_elastic_net_regressor.py +109 -0
- iaml/actionables/predictors/regressor/act_extra_trees_regressor.py +113 -0
- iaml/actionables/predictors/regressor/act_gaussian_process_regressor.py +55 -0
- iaml/actionables/predictors/regressor/act_gboost_regressor.py +95 -0
- iaml/actionables/predictors/regressor/act_hist_gradient_boosting_regressor.py +105 -0
- iaml/actionables/predictors/regressor/act_huber_regressor.py +101 -0
- iaml/actionables/predictors/regressor/act_knn_regressor.py +86 -0
- iaml/actionables/predictors/regressor/act_lasso_regressor.py +103 -0
- iaml/actionables/predictors/regressor/act_light_gbm_regressor.py +201 -0
- iaml/actionables/predictors/regressor/act_linear_regression.py +43 -0
- iaml/actionables/predictors/regressor/act_mlp_regressor.py +104 -0
- iaml/actionables/predictors/regressor/act_poisson_regressor.py +111 -0
- iaml/actionables/predictors/regressor/act_quantile_regressor.py +87 -0
- iaml/actionables/predictors/regressor/act_randomforest_regressor.py +116 -0
- iaml/actionables/predictors/regressor/act_ransac_regressor.py +106 -0
- iaml/actionables/predictors/regressor/act_ridge_regressor.py +107 -0
- iaml/actionables/predictors/regressor/act_sgd_regressor.py +106 -0
- iaml/actionables/predictors/regressor/act_svm_svr.py +81 -0
- iaml/actionables/predictors/regressor/act_xgboost_regressor.py +97 -0
- iaml/actionables/predictors/survival/__init__.py +12 -0
- iaml/actionables/predictors/survival/act_aalen_additive_model.py +83 -0
- iaml/actionables/predictors/survival/act_cox.py +110 -0
- iaml/actionables/predictors/survival/act_coxnet_survival_analysis.py +134 -0
- iaml/actionables/predictors/survival/act_extra_survival_trees.py +101 -0
- iaml/actionables/predictors/survival/act_fast_survival_svm.py +102 -0
- iaml/actionables/predictors/survival/act_gradient_boosting_survival_analysis.py +93 -0
- iaml/actionables/predictors/survival/act_random_survival_forest.py +91 -0
- iaml/actionables/predictors/survival/act_survival_component_wise_gboost.py +80 -0
- iaml/actionables/predictors/survival/act_survival_tree.py +120 -0
- iaml/actionables/predictors/survival/act_survival_xgboost.py +9 -0
- iaml/actionables/predictors/survival/act_weibull_aft.py +230 -0
- iaml/cache.py +61 -0
- iaml/cache_keys.py +57 -0
- iaml/candidate.py +736 -0
- iaml/core_dispatcher.py +125 -0
- iaml/data_type.py +11 -0
- iaml/dataset.py +506 -0
- iaml/decorators/__init__.py +3 -0
- iaml/decorators/all.py +4 -0
- iaml/decorators/is_step.py +45 -0
- iaml/decorators/runner.py +100 -0
- iaml/explanation.py +112 -0
- iaml/iaml.py +1072 -0
- iaml/iaml_pipeline.py +600 -0
- iaml/logger.py +138 -0
- iaml/meta_explorer_step.py +62 -0
- iaml/meta_ordered_step.py +28 -0
- iaml/meta_partial_explorer_step.py +34 -0
- iaml/meta_singleton.py +24 -0
- iaml/metastep.py +211 -0
- iaml/metric.py +111 -0
- iaml/metric_plot.py +82 -0
- iaml/metrics/__init__.py +21 -0
- iaml/metrics/_classification.py +28 -0
- iaml/metrics/_survival_times.py +22 -0
- iaml/metrics/accuracy_metric.py +59 -0
- iaml/metrics/balanced_accuracy_metric.py +67 -0
- iaml/metrics/brier_score.py +90 -0
- iaml/metrics/classification_error_metric.py +66 -0
- iaml/metrics/concordance_index_ipcw.py +84 -0
- iaml/metrics/concordance_index_metric.py +67 -0
- iaml/metrics/cumulative_dynamic_auc.py +119 -0
- iaml/metrics/f1_score_metric.py +71 -0
- iaml/metrics/integrated_brier_score.py +98 -0
- iaml/metrics/integrated_brier_score_loss.py +41 -0
- iaml/metrics/mean_absolute_error_metric.py +46 -0
- iaml/metrics/mean_squared_error_metric.py +46 -0
- iaml/metrics/mean_squared_log_error_metric.py +49 -0
- iaml/metrics/median_absolute_error_metric.py +48 -0
- iaml/metrics/precision_metric.py +63 -0
- iaml/metrics/r2_score_metric.py +45 -0
- iaml/metrics/recall_metric.py +65 -0
- iaml/metrics/roc_auc_metric.py +50 -0
- iaml/metrics/specificity_metric.py +44 -0
- iaml/metrics/specificity_multiclass_metric.py +55 -0
- iaml/metrics/specificity_multilabel_metric.py +60 -0
- iaml/optimizers/__init__.py +5 -0
- iaml/optimizers/bayesian_optimizer.py +193 -0
- iaml/optimizers/genetic_optimizer.py +284 -0
- iaml/optimizers/optimizer.py +31 -0
- iaml/optimizers/random_optimizer.py +101 -0
- iaml/plot.py +138 -0
- iaml/plots/__init__.py +32 -0
- iaml/plots/bar_plot.py +141 -0
- iaml/plots/box_plot.py +166 -0
- iaml/plots/class_prediction_error_plot.py +37 -0
- iaml/plots/classification_report_plot.py +35 -0
- iaml/plots/confusion_matrix_plot.py +34 -0
- iaml/plots/correlation_heatmap_plot.py +201 -0
- iaml/plots/cumulative_hazard_plot.py +72 -0
- iaml/plots/density_plot.py +210 -0
- iaml/plots/histogram_plot.py +179 -0
- iaml/plots/kaplan_meier_comparison_plot.py +89 -0
- iaml/plots/line_plot.py +70 -0
- iaml/plots/missingness_heatmap_plot.py +203 -0
- iaml/plots/outlier_plot.py +217 -0
- iaml/plots/pair_plot.py +228 -0
- iaml/plots/precision_recall_curve_plot.py +86 -0
- iaml/plots/prediction_error_plot.py +34 -0
- iaml/plots/qq_plot.py +220 -0
- iaml/plots/residual_plot.py +38 -0
- iaml/plots/roc_dynamique_curve_plot.py +79 -0
- iaml/plots/rocauc_plot.py +96 -0
- iaml/plots/shap_plot.py +187 -0
- iaml/plots/target_distribution_plot.py +241 -0
- iaml/plots/violin_plot.py +206 -0
- iaml/predictor.py +139 -0
- iaml/reference.py +65 -0
- iaml/shared_cache.py +90 -0
- iaml/sklearn_preprocessor.py +74 -0
- iaml/splitters/__init__.py +3 -0
- iaml/splitters/kfold_splitter.py +32 -0
- iaml/splitters/random_splitter.py +26 -0
- iaml/stack.py +39 -0
- iaml/statistic.py +66 -0
- iaml/statistics/__init__.py +77 -0
- iaml/statistics/anova_statistic.py +80 -0
- iaml/statistics/cardinality_ratio_statistic.py +63 -0
- iaml/statistics/category_cooccurrence_statistic.py +79 -0
- iaml/statistics/chi_square_statistic.py +81 -0
- iaml/statistics/coef_variation_statistic.py +72 -0
- iaml/statistics/correlation_with_target.py +105 -0
- iaml/statistics/count.py +72 -0
- iaml/statistics/data_type_summary_statistic.py +74 -0
- iaml/statistics/duplicate_row_statistic.py +56 -0
- iaml/statistics/effect_size_statistic.py +129 -0
- iaml/statistics/entropy_statistic.py +69 -0
- iaml/statistics/event_rate_statistic.py +52 -0
- iaml/statistics/grouped_mean_statistic.py +60 -0
- iaml/statistics/iqr_statistic.py +66 -0
- iaml/statistics/kurtosis.py +50 -0
- iaml/statistics/mad_statistic.py +66 -0
- iaml/statistics/mean.py +61 -0
- iaml/statistics/median_statistic.py +61 -0
- iaml/statistics/minmax.py +60 -0
- iaml/statistics/missing_rate_statistic.py +62 -0
- iaml/statistics/mode.py +47 -0
- iaml/statistics/most_frequent_ratio.py +81 -0
- iaml/statistics/outlier_count_iqr_statistic.py +76 -0
- iaml/statistics/quantile.py +59 -0
- iaml/statistics/range.py +53 -0
- iaml/statistics/rare_category_rate.py +92 -0
- iaml/statistics/skewness.py +53 -0
- iaml/statistics/stdev.py +50 -0
- iaml/statistics/summary_table_statistic.py +60 -0
- iaml/statistics/time_by_group_statistic.py +83 -0
- iaml/statistics/time_summary_statistic.py +56 -0
- iaml/statistics/top_k_value_counts.py +68 -0
- iaml/statistics/unique_count_statistic.py +57 -0
- iaml/statistics/value_counts.py +63 -0
- iaml/statistics/variance.py +51 -0
- iaml/statistics/violin.py +63 -0
- iaml/step.py +600 -0
- iaml/step_cache.py +87 -0
- iaml/step_wrapper.py +79 -0
- iaml/timed_pool_executor.py +492 -0
- iaml/type_of_target.py +68 -0
- iaml/void_step.py +101 -0
- iaml/worker_manager.py +169 -0
- iaml/wrapper/__init__.py +4 -0
- iaml/wrapper/wrap_basic_gridsearch.py +68 -0
- iaml/wrapper/wrap_genetic_gridsearch.py +293 -0
- iaml/wrapper/wrap_iterative_gridsearch.py +399 -0
- pyiaml-1.0.0.dist-info/METADATA +802 -0
- pyiaml-1.0.0.dist-info/RECORD +279 -0
- pyiaml-1.0.0.dist-info/WHEEL +5 -0
- pyiaml-1.0.0.dist-info/licenses/LICENSE +674 -0
- pyiaml-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""
|
|
2
|
+
[STEP] Multinomial NB
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import textwrap
|
|
6
|
+
from sklearn.naive_bayes import MultinomialNB
|
|
7
|
+
from ....predictor import Predictor
|
|
8
|
+
from ....dataset import Dataset
|
|
9
|
+
from ....candidate import Candidate
|
|
10
|
+
from ....decorators.all import is_step
|
|
11
|
+
|
|
12
|
+
@is_step('predictor', 'tabular', 'classifier')
|
|
13
|
+
class ActMultinomialNB(Predictor):
|
|
14
|
+
"""
|
|
15
|
+
[STEP] Multinomial NB
|
|
16
|
+
"""
|
|
17
|
+
name = "Multinomial NB"
|
|
18
|
+
_usage = "Use when non-negative counts or frequencies drive class signal and you want a fast baseline vs ActComplementNB or ActBernoulliNb. Applicable to tabular bag-of-words or count features for binary or multiclass targets. Avoid when features include negatives, strong feature interactions, or need nonlinear splits."
|
|
19
|
+
_description = textwrap.dedent('''\
|
|
20
|
+
MultinomialNB is a machine learning algorithm that models
|
|
21
|
+
the relationship between input features and a categorical output variable
|
|
22
|
+
using a multinomial distribution.''')
|
|
23
|
+
_description_long = textwrap.dedent('''\
|
|
24
|
+
MultinomialNB is a type of naive Bayes algorithm that models
|
|
25
|
+
the relationship between input features and a categorical output variable using
|
|
26
|
+
a multinomial distribution. It works by assuming that the input features are
|
|
27
|
+
independent and follow a multinomial distribution, where each feature is represented
|
|
28
|
+
by the number of times it appears in a document or bag-of-words representation.''')
|
|
29
|
+
refs = [
|
|
30
|
+
{
|
|
31
|
+
'year': 2008,
|
|
32
|
+
'name': 'Introduction to Information Retrieval',
|
|
33
|
+
'authors': [
|
|
34
|
+
'Christopher D. Manning',
|
|
35
|
+
'Prabhakar Raghaban',
|
|
36
|
+
'Hinrich Schütze'
|
|
37
|
+
],
|
|
38
|
+
'doi': "https://doi.org/10.1017/CBO9780511809071",
|
|
39
|
+
'publisher': 'Cambridge University Press'
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
def __init__(self):
|
|
43
|
+
self.configuration = {
|
|
44
|
+
'alpha': {
|
|
45
|
+
'description': textwrap.dedent('''\
|
|
46
|
+
Additive (Laplace/Lidstone) smoothing parameter (set
|
|
47
|
+
alpha=0 and force_alpha=True, for no smoothing).'''),
|
|
48
|
+
'default': 1.0,
|
|
49
|
+
'range': [0.01, 100.0]
|
|
50
|
+
},
|
|
51
|
+
'fit_prior': {
|
|
52
|
+
'description': textwrap.dedent('''\
|
|
53
|
+
Whether to learn class prior probabilities or not. If
|
|
54
|
+
false, a uniform prior will be used.'''),
|
|
55
|
+
'default': True,
|
|
56
|
+
'categorical': [True, False]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
self.model: MultinomialNB = None
|
|
61
|
+
|
|
62
|
+
def fit(self, dataset: Dataset): # pylint: disable=unused-argument
|
|
63
|
+
self.model = MultinomialNB(**self.passthrough_parameters())
|
|
64
|
+
|
|
65
|
+
self.model.fit(dataset.X, dataset.y)
|
|
66
|
+
|
|
67
|
+
return self
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def suitable(self, dataset: Dataset) -> bool:
|
|
71
|
+
# Negative values are not supported
|
|
72
|
+
return not((dataset.X < 0).any().any()) \
|
|
73
|
+
and dataset.type_of_target in ['binary', 'multiclass']
|
|
74
|
+
|
|
75
|
+
def priorize(self, candidate: Candidate = None) -> float:
|
|
76
|
+
return 0.5 # neutral
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""[STEP] Passive Aggressive Classifier"""
|
|
2
|
+
import textwrap
|
|
3
|
+
from typing import Any
|
|
4
|
+
import numpy as np
|
|
5
|
+
from sklearn.linear_model import PassiveAggressiveClassifier
|
|
6
|
+
from ....predictor import Predictor
|
|
7
|
+
from ....dataset import Dataset
|
|
8
|
+
from ....candidate import Candidate
|
|
9
|
+
from ....data_type import DataType
|
|
10
|
+
from ....decorators.all import is_step
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@is_step('predictor', 'tabular', 'classifier')
|
|
14
|
+
class ActPassiveAggressiveClassifier(Predictor):
|
|
15
|
+
"""[STEP] Passive Aggressive Classifier"""
|
|
16
|
+
|
|
17
|
+
name: str = "Passive Aggressive Classifier"
|
|
18
|
+
_usage: str = "Use when you need a fast online linear classifier for large or streaming data. Applicable to numeric tabular binary/multiclass or multilabel targets. Avoid when patterns are nonlinear or categorical-heavy; prefer ActDecisionTreeClassifier or ActExtraTreesClassifier."
|
|
19
|
+
_description: str = textwrap.dedent('''\
|
|
20
|
+
PassiveAggressiveClassifier is an online linear classifier that updates
|
|
21
|
+
only on misclassified samples, making it suitable for streaming or
|
|
22
|
+
large-scale data.''')
|
|
23
|
+
_description_long: str = textwrap.dedent('''\
|
|
24
|
+
PassiveAggressiveClassifier is an online learning algorithm that performs
|
|
25
|
+
aggressive updates when samples are misclassified and stays passive otherwise.
|
|
26
|
+
It learns a linear decision boundary efficiently with hinge-style losses and
|
|
27
|
+
supports multiclass problems with a one-vs-rest strategy.''')
|
|
28
|
+
refs: list[dict[str, Any]] = [
|
|
29
|
+
{
|
|
30
|
+
'year': 2006,
|
|
31
|
+
'name': 'Online Passive-Aggressive Algorithms',
|
|
32
|
+
'authors': [
|
|
33
|
+
'Koby Crammer',
|
|
34
|
+
'Ofer Dekel',
|
|
35
|
+
'Joseph Keshet',
|
|
36
|
+
'Shai Shalev-Shwartz',
|
|
37
|
+
'Yoram Singer'
|
|
38
|
+
],
|
|
39
|
+
'doi': 'https://doi.org/10.5555/1248547.1248566',
|
|
40
|
+
'publisher': 'Advances in Neural Information Processing Systems 19'
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
def __init__(self):
|
|
45
|
+
self.configuration = {
|
|
46
|
+
'C': {
|
|
47
|
+
'description': 'Maximum step size (regularization strength).',
|
|
48
|
+
'default': 1.0,
|
|
49
|
+
'range': [1e-03, 100.0]
|
|
50
|
+
},
|
|
51
|
+
'loss': {
|
|
52
|
+
'description': 'The loss function to be used.',
|
|
53
|
+
'default': 'hinge',
|
|
54
|
+
'categorical': ['hinge', 'squared_hinge']
|
|
55
|
+
},
|
|
56
|
+
'max_iter': {
|
|
57
|
+
'description': 'Maximum number of passes over the training data.',
|
|
58
|
+
'default': 1000,
|
|
59
|
+
'range': [100, 5000]
|
|
60
|
+
},
|
|
61
|
+
'tol': {
|
|
62
|
+
'description': 'The stopping criterion.',
|
|
63
|
+
'default': 0.001,
|
|
64
|
+
'range': [1e-05, 0.1]
|
|
65
|
+
},
|
|
66
|
+
'fit_intercept': {
|
|
67
|
+
'description': 'Whether to fit the intercept term.',
|
|
68
|
+
'default': True,
|
|
69
|
+
'categorical': [True, False]
|
|
70
|
+
},
|
|
71
|
+
'shuffle': {
|
|
72
|
+
'description': 'Whether to shuffle the training data after each epoch.',
|
|
73
|
+
'default': True,
|
|
74
|
+
'categorical': [True, False]
|
|
75
|
+
},
|
|
76
|
+
'class_weight': {
|
|
77
|
+
'description': textwrap.dedent('''\
|
|
78
|
+
The "balanced" mode uses values of y to adjust weights inversely
|
|
79
|
+
proportional to class frequencies.'''),
|
|
80
|
+
'default': None,
|
|
81
|
+
'categorical': [None, 'balanced']
|
|
82
|
+
},
|
|
83
|
+
'average': {
|
|
84
|
+
'description': textwrap.dedent('''\
|
|
85
|
+
When set to True, computes the averaged weights across all updates.'''),
|
|
86
|
+
'default': False,
|
|
87
|
+
'categorical': [True, False]
|
|
88
|
+
},
|
|
89
|
+
'random_state': {
|
|
90
|
+
'description': 'Random state for reproducibility.',
|
|
91
|
+
'default': 42
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
self.model: PassiveAggressiveClassifier = None
|
|
95
|
+
self.columns: list[str] = []
|
|
96
|
+
self.target_type: str | None = None
|
|
97
|
+
|
|
98
|
+
def _select_features(self, X):
|
|
99
|
+
if self.columns and hasattr(X, 'columns'):
|
|
100
|
+
return X[self.columns]
|
|
101
|
+
return X
|
|
102
|
+
|
|
103
|
+
def _decision_function_proba(self, scores: np.ndarray) -> np.ndarray:
|
|
104
|
+
if scores.ndim == 1:
|
|
105
|
+
probs_pos = 1.0 / (1.0 + np.exp(-scores))
|
|
106
|
+
return np.column_stack([1.0 - probs_pos, probs_pos])
|
|
107
|
+
if self.target_type == 'multilabel-indicator':
|
|
108
|
+
return 1.0 / (1.0 + np.exp(-scores))
|
|
109
|
+
max_scores = np.max(scores, axis=1, keepdims=True)
|
|
110
|
+
exp_scores = np.exp(scores - max_scores)
|
|
111
|
+
return exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
|
|
112
|
+
|
|
113
|
+
def fit(self, dataset: Dataset): # pylint: disable=unused-argument
|
|
114
|
+
self.columns = dataset.get_columns_names_by_type(DataType.NUMERIC)
|
|
115
|
+
if not self.columns:
|
|
116
|
+
self.columns = dataset.features
|
|
117
|
+
|
|
118
|
+
self.target_type = dataset.type_of_target
|
|
119
|
+
self.model = PassiveAggressiveClassifier(**self.passthrough_parameters())
|
|
120
|
+
self.model.fit(self._select_features(dataset.X), dataset.y)
|
|
121
|
+
return self
|
|
122
|
+
|
|
123
|
+
def predict(self, X):
|
|
124
|
+
return super().predict(self._select_features(X))
|
|
125
|
+
|
|
126
|
+
def predict_proba(self, X):
|
|
127
|
+
if self.model is None:
|
|
128
|
+
raise AttributeError("Model is not fitted")
|
|
129
|
+
scores = self.model.decision_function(self._select_features(X))
|
|
130
|
+
return self._decision_function_proba(np.asarray(scores))
|
|
131
|
+
|
|
132
|
+
def score(self, X, y=None, *args, **kwargs):
|
|
133
|
+
return self.model.score(self._select_features(X), y, *args, **kwargs)
|
|
134
|
+
|
|
135
|
+
def suitable(self, dataset: Dataset) -> bool:
|
|
136
|
+
return dataset.type_of_target in \
|
|
137
|
+
['binary', 'multiclass', 'multilabel-indicator'] \
|
|
138
|
+
and bool(dataset.get_columns_names_by_type(DataType.NUMERIC))
|
|
139
|
+
|
|
140
|
+
def priorize(self, candidate: Candidate = None) -> float:
|
|
141
|
+
return 0.5 # neutral
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""
|
|
2
|
+
[STEP] Quadratic Discriminant Analysis
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import textwrap
|
|
6
|
+
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
|
|
7
|
+
from ....predictor import Predictor
|
|
8
|
+
from ....dataset import Dataset
|
|
9
|
+
from ....candidate import Candidate
|
|
10
|
+
from ....decorators.all import is_step
|
|
11
|
+
|
|
12
|
+
@is_step('predictor', 'tabular', 'classifier')
|
|
13
|
+
class ActQuadraticDiscriminantAnalysis(Predictor):
|
|
14
|
+
"""
|
|
15
|
+
[STEP] Quadratic Discriminant Analysis
|
|
16
|
+
"""
|
|
17
|
+
name = "Quadratic Discriminant Analysis"
|
|
18
|
+
_usage = "Use when class covariances differ and you want a fast probabilistic baseline vs ActDecisionTreeClassifier or ActExtraTreesClassifier. Applicable to tabular numeric features for binary or multiclass targets. Avoid when data are highly non-Gaussian, sparse, or p>>n."
|
|
19
|
+
_description = textwrap.dedent('''\
|
|
20
|
+
QuadraticDiscriminantAnalysis is a machine learning algorithm
|
|
21
|
+
that models the relationship between input features and a categorical
|
|
22
|
+
output variable using a quadratic function.''')
|
|
23
|
+
_description_long = textwrap.dedent('''\
|
|
24
|
+
QuadraticDiscriminantAnalysis is a type of discriminant analysis
|
|
25
|
+
algorithm that models the relationship between input features and a categorical output
|
|
26
|
+
variable using a quadratic function.
|
|
27
|
+
It works by estimating the covariance matrices of the classes and using
|
|
28
|
+
them to calculate the probability density functions for each class.
|
|
29
|
+
The class with the highest probability density function is then used to make
|
|
30
|
+
the prediction.''')
|
|
31
|
+
refs = [
|
|
32
|
+
{
|
|
33
|
+
'year': 1965,
|
|
34
|
+
'name': 'Geometrical and Statistical Properties of Systems of Linear Inequalities \
|
|
35
|
+
with Applications in Pattern Recognition',
|
|
36
|
+
'authors': ['Thomas M. Cover'],
|
|
37
|
+
'doi': 'https://doi.org/10.1109/PGEC.1965.264137',
|
|
38
|
+
'publisher': 'IEEE Transactions on Electronic Computers Vol.EC-14 page 326--334'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
'year': 2016,
|
|
42
|
+
'name': 'Linear vs. quadratic discriminant analysis classifier: a tutorial',
|
|
43
|
+
'authors': ['Alaa Tharwat'],
|
|
44
|
+
'doi': 'https://www.inderscienceonline.com/doi/abs/10.1504/IJAPR.2016.079050',
|
|
45
|
+
'publisher': 'International Journal of Applied Pattern Recognition \
|
|
46
|
+
Vol.3, No.2 page 145--180'
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
def __init__(self):
|
|
51
|
+
self.configuration = {
|
|
52
|
+
'reg_param': {
|
|
53
|
+
'description': 'Regularizes the per-class covariance estimates by transforming S2',
|
|
54
|
+
'default': 0.0001,
|
|
55
|
+
'range': [0.0001, 1.0]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
self.model: QuadraticDiscriminantAnalysis = None
|
|
59
|
+
|
|
60
|
+
def fit(self, dataset: Dataset): # pylint: disable=unused-argument
|
|
61
|
+
self.model = QuadraticDiscriminantAnalysis(**self.passthrough_parameters())
|
|
62
|
+
|
|
63
|
+
self.model.fit(dataset.X, dataset.y)
|
|
64
|
+
|
|
65
|
+
return self
|
|
66
|
+
|
|
67
|
+
def suitable(self, dataset: Dataset) -> bool:
|
|
68
|
+
return dataset.type_of_target in \
|
|
69
|
+
['binary', 'multiclass', 'multilabel-indicator']
|
|
70
|
+
|
|
71
|
+
def priorize(self, candidate: Candidate = None) -> float:
|
|
72
|
+
return 0.5 # neutral
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""[STEP] Random Forest"""
|
|
2
|
+
import textwrap
|
|
3
|
+
from typing import Any
|
|
4
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
5
|
+
from ....data_type import DataType
|
|
6
|
+
from ....predictor import Predictor
|
|
7
|
+
from ....dataset import Dataset
|
|
8
|
+
from ....candidate import Candidate
|
|
9
|
+
from ....decorators.all import is_step
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@is_step('predictor', 'tabular', 'classifier')
|
|
13
|
+
class ActRandomForest(Predictor):
|
|
14
|
+
"""[STEP] Random Forest"""
|
|
15
|
+
|
|
16
|
+
name: str = "Random Forest"
|
|
17
|
+
_usage: str = "Use when you need a solid tabular classifier baseline and prefer it over ActExtraTreesClassifier for stability. Applicable to binary, multiclass, or multilabel tabular data with tree-ready features. Avoid when data is extremely sparse text or you need native categorical handling."
|
|
18
|
+
_description: str = textwrap.dedent('''\
|
|
19
|
+
RandomForestClassifier is a machine learning algorithm that models
|
|
20
|
+
the relationship between input features and a categorical output variable using
|
|
21
|
+
a collection of decision trees.''')
|
|
22
|
+
_description_long: str = textwrap.dedent('''\
|
|
23
|
+
RandomForestClassifier is a type of ensemble learning algorithm that
|
|
24
|
+
models the relationship between input features and a categorical output variable using
|
|
25
|
+
a collection of decision trees. It works by building multiple decision trees on random
|
|
26
|
+
subsets of the input features and data, and then using a majority vote to make
|
|
27
|
+
the final prediction.''')
|
|
28
|
+
refs: tuple[dict[str, Any]] = [
|
|
29
|
+
{
|
|
30
|
+
'year': 2001,
|
|
31
|
+
'name': 'Random Forests',
|
|
32
|
+
'authors': ['Leo Breiman'],
|
|
33
|
+
'doi': 'https://doi.org/10.1023/A:1010933404324',
|
|
34
|
+
'publisher': 'Machine Learning Vol.45 page 5--32'
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
self.configuration = {
|
|
40
|
+
'max_depth': {
|
|
41
|
+
'description': 'Max depth of each tree',
|
|
42
|
+
'default': 15,
|
|
43
|
+
'range': [1, 100]
|
|
44
|
+
},
|
|
45
|
+
'n_estimators': {
|
|
46
|
+
'description': 'Number of threes',
|
|
47
|
+
'default': 100,
|
|
48
|
+
'range': [1, 500]
|
|
49
|
+
},
|
|
50
|
+
'random_state': {
|
|
51
|
+
'description': 'random_state',
|
|
52
|
+
'default': 42
|
|
53
|
+
},
|
|
54
|
+
'min_samples_leaf': {
|
|
55
|
+
'description': 'The minimum number of samples required to be at a leaf node.',
|
|
56
|
+
'default': 1,
|
|
57
|
+
'range': [1, 15]
|
|
58
|
+
},
|
|
59
|
+
'max_features': {
|
|
60
|
+
'description': 'The number of features to consider when looking for the best split',
|
|
61
|
+
'default': 1.0,
|
|
62
|
+
'range': [0.1, 1.0]
|
|
63
|
+
},
|
|
64
|
+
'min_samples_split': {
|
|
65
|
+
'description': 'The minimum number of samples required to split an internal node',
|
|
66
|
+
'default': 2,
|
|
67
|
+
'range': [2, 20]
|
|
68
|
+
},
|
|
69
|
+
'bootstrap': {
|
|
70
|
+
'description': textwrap.dedent('''\
|
|
71
|
+
Whether bootstrap samples are used when building trees. If
|
|
72
|
+
False, the whole dataset is used to build each tree.'''),
|
|
73
|
+
'default': False
|
|
74
|
+
},
|
|
75
|
+
'criterion': {
|
|
76
|
+
'description': 'The function to measure the quality of a split.',
|
|
77
|
+
'default': "gini",
|
|
78
|
+
'categorical': ['gini', 'entropy', 'log_loss']
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
self.model: RandomForestClassifier = None
|
|
82
|
+
self.columns: list[str] = []
|
|
83
|
+
|
|
84
|
+
def _select_features(self, X):
|
|
85
|
+
if self.columns and hasattr(X, 'columns'):
|
|
86
|
+
return X[self.columns]
|
|
87
|
+
return X
|
|
88
|
+
|
|
89
|
+
def fit(self, dataset: Dataset): # pylint: disable=unused-argument
|
|
90
|
+
self.columns = dataset.get_columns_names_by_type(DataType.NUMERIC)
|
|
91
|
+
if not self.columns:
|
|
92
|
+
self.columns = dataset.features
|
|
93
|
+
|
|
94
|
+
self.model = RandomForestClassifier(**self.passthrough_parameters())
|
|
95
|
+
self.model.fit(self._select_features(dataset.X), dataset.y)
|
|
96
|
+
return self
|
|
97
|
+
|
|
98
|
+
def predict(self, X):
|
|
99
|
+
return super().predict(self._select_features(X))
|
|
100
|
+
|
|
101
|
+
def predict_proba(self, X):
|
|
102
|
+
return super().predict_proba(self._select_features(X))
|
|
103
|
+
|
|
104
|
+
def score(self, X, y=None, *args, **kwargs):
|
|
105
|
+
return self.model.score(self._select_features(X), y, *args, **kwargs)
|
|
106
|
+
|
|
107
|
+
def suitable(self, dataset: Dataset) -> bool:
|
|
108
|
+
return dataset.type_of_target in \
|
|
109
|
+
['binary', 'multiclass', 'multilabel-indicator'] \
|
|
110
|
+
and bool(dataset.get_columns_names_by_type(DataType.NUMERIC))
|
|
111
|
+
|
|
112
|
+
def priorize(self, candidate: Candidate = None) -> float:
|
|
113
|
+
return 0.5 # neutral
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""[STEP] Ridge Classifier"""
|
|
2
|
+
import textwrap
|
|
3
|
+
from typing import Any
|
|
4
|
+
from sklearn.linear_model import RidgeClassifier
|
|
5
|
+
from ....predictor import Predictor
|
|
6
|
+
from ....dataset import Dataset
|
|
7
|
+
from ....candidate import Candidate
|
|
8
|
+
from ....data_type import DataType
|
|
9
|
+
from ....decorators.all import is_step
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@is_step('predictor', 'tabular', 'classifier')
|
|
13
|
+
class ActRidgeClassifier(Predictor):
|
|
14
|
+
"""[STEP] Ridge Classifier"""
|
|
15
|
+
|
|
16
|
+
name: str = "Ridge Classifier"
|
|
17
|
+
_usage: str = "Use when you need a fast linear L2 baseline on numeric tabular data, vs ActDecisionTreeClassifier or ActExtraTreesClassifier. Applicable to binary/multiclass targets with mostly numeric features. Avoid when data is mostly categorical, highly nonlinear, or ActCatBoost fits better."
|
|
18
|
+
_description: str = textwrap.dedent('''\
|
|
19
|
+
RidgeClassifier is a linear classifier that applies L2
|
|
20
|
+
regularization to reduce sensitivity to noisy features.''')
|
|
21
|
+
_description_long: str = textwrap.dedent('''\
|
|
22
|
+
RidgeClassifier fits a linear decision boundary by solving a
|
|
23
|
+
regularized least squares problem. The L2 penalty stabilizes
|
|
24
|
+
coefficients when features are correlated and improves robustness
|
|
25
|
+
to noise in tabular datasets.''')
|
|
26
|
+
refs: list[dict[str, Any]] = [
|
|
27
|
+
{
|
|
28
|
+
'year': 1970,
|
|
29
|
+
'name': 'Ridge Regression: Biased Estimation for Nonorthogonal Problems',
|
|
30
|
+
'authors': [
|
|
31
|
+
'Arthur E. Hoerl',
|
|
32
|
+
'Robert W. Kennard'
|
|
33
|
+
],
|
|
34
|
+
'doi': 'https://doi.org/10.2307/1267351',
|
|
35
|
+
'publisher': 'Technometrics Vol. 12, No. 1, page 55--67'
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
def __init__(self):
|
|
40
|
+
self.configuration = {
|
|
41
|
+
'alpha': {
|
|
42
|
+
'description': 'Regularization strength.',
|
|
43
|
+
'default': 1.0,
|
|
44
|
+
'range': [1e-04, 100.0]
|
|
45
|
+
},
|
|
46
|
+
'fit_intercept': {
|
|
47
|
+
'description': 'Whether to fit the intercept term.',
|
|
48
|
+
'default': True,
|
|
49
|
+
'categorical': [True, False]
|
|
50
|
+
},
|
|
51
|
+
'solver': {
|
|
52
|
+
'description': 'Solver to use in the ridge optimization.',
|
|
53
|
+
'default': 'auto',
|
|
54
|
+
'categorical': [
|
|
55
|
+
'auto',
|
|
56
|
+
'svd',
|
|
57
|
+
'cholesky',
|
|
58
|
+
'lsqr',
|
|
59
|
+
'sparse_cg',
|
|
60
|
+
'sag',
|
|
61
|
+
'saga',
|
|
62
|
+
'lbfgs'
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
'tol': {
|
|
66
|
+
'description': 'Stopping criterion for iterative solvers.',
|
|
67
|
+
'default': 0.0001,
|
|
68
|
+
'range': [1e-05, 0.1]
|
|
69
|
+
},
|
|
70
|
+
'max_iter': {
|
|
71
|
+
'description': 'Maximum number of iterations for iterative solvers.',
|
|
72
|
+
'default': 1000,
|
|
73
|
+
'range': [50, 5000]
|
|
74
|
+
},
|
|
75
|
+
'class_weight': {
|
|
76
|
+
'description': textwrap.dedent('''\
|
|
77
|
+
The "balanced" mode uses values of y to adjust weights inversely
|
|
78
|
+
proportional to class frequencies.'''),
|
|
79
|
+
'default': None,
|
|
80
|
+
'categorical': [None, 'balanced']
|
|
81
|
+
},
|
|
82
|
+
'random_state': {
|
|
83
|
+
'description': 'Random state for solvers that use randomness.',
|
|
84
|
+
'default': 42
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
self.model: RidgeClassifier = None
|
|
88
|
+
self.columns: list[str] = []
|
|
89
|
+
|
|
90
|
+
def _select_features(self, X):
|
|
91
|
+
if self.columns and hasattr(X, 'columns'):
|
|
92
|
+
return X[self.columns]
|
|
93
|
+
return X
|
|
94
|
+
|
|
95
|
+
def fit(self, dataset: Dataset): # pylint: disable=unused-argument
|
|
96
|
+
self.columns = dataset.get_columns_names_by_type(DataType.NUMERIC)
|
|
97
|
+
if not self.columns:
|
|
98
|
+
self.columns = dataset.features
|
|
99
|
+
|
|
100
|
+
self.model = RidgeClassifier(**self.passthrough_parameters())
|
|
101
|
+
self.model.fit(self._select_features(dataset.X), dataset.y)
|
|
102
|
+
return self
|
|
103
|
+
|
|
104
|
+
def predict(self, X):
|
|
105
|
+
return super().predict(self._select_features(X))
|
|
106
|
+
|
|
107
|
+
def score(self, X, y=None, *args, **kwargs):
|
|
108
|
+
return self.model.score(self._select_features(X), y, *args, **kwargs)
|
|
109
|
+
|
|
110
|
+
def suitable(self, dataset: Dataset) -> bool:
|
|
111
|
+
return dataset.type_of_target in \
|
|
112
|
+
['binary', 'multiclass', 'multilabel-indicator'] \
|
|
113
|
+
and bool(dataset.get_columns_names_by_type(DataType.NUMERIC))
|
|
114
|
+
|
|
115
|
+
def priorize(self, candidate: Candidate = None) -> float:
|
|
116
|
+
return 0.5 # neutral
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""[STEP] SGD Classifier"""
|
|
2
|
+
import textwrap
|
|
3
|
+
from typing import Any
|
|
4
|
+
import numpy as np
|
|
5
|
+
from sklearn.linear_model import SGDClassifier
|
|
6
|
+
from ....predictor import Predictor
|
|
7
|
+
from ....dataset import Dataset
|
|
8
|
+
from ....candidate import Candidate
|
|
9
|
+
from ....data_type import DataType
|
|
10
|
+
from ....decorators.all import is_step
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@is_step('predictor', 'tabular', 'classifier')
|
|
14
|
+
class ActSGDClassifier(Predictor):
|
|
15
|
+
"""[STEP] SGD Classifier"""
|
|
16
|
+
|
|
17
|
+
name: str = "SGD Classifier"
|
|
18
|
+
_description: str = textwrap.dedent('''\
|
|
19
|
+
SGDClassifier is a linear classifier optimized with stochastic gradient
|
|
20
|
+
descent, suitable for large-scale classification tasks.''')
|
|
21
|
+
_description_long: str = textwrap.dedent('''\
|
|
22
|
+
SGDClassifier learns a linear decision boundary using stochastic gradient
|
|
23
|
+
descent. It supports hinge loss (linear SVM) and logistic loss for
|
|
24
|
+
probabilistic classification, making it efficient on large datasets.''')
|
|
25
|
+
_usage: str = "Use when you need a fast linear classifier for large numeric tabular data, as a baseline vs ActDecisionTreeClassifier or ActExtraTreesClassifier. Applicable to binary, multiclass, or multilabel targets with numeric features. Avoid when data are mostly categorical or require complex nonlinear boundaries."
|
|
26
|
+
refs: list[dict[str, Any]] = [
|
|
27
|
+
{
|
|
28
|
+
'year': 2010,
|
|
29
|
+
'name': 'Large-Scale Machine Learning with Stochastic Gradient Descent',
|
|
30
|
+
'authors': [
|
|
31
|
+
'Leon Bottou'
|
|
32
|
+
],
|
|
33
|
+
'doi': 'https://doi.org/10.1145/1796439.1796440',
|
|
34
|
+
'publisher': 'Proceedings of COMPSTAT 2010'
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
self.configuration = {
|
|
40
|
+
'loss': {
|
|
41
|
+
'description': 'The loss function to be used.',
|
|
42
|
+
'default': 'log_loss',
|
|
43
|
+
'categorical': ['log_loss', 'hinge']
|
|
44
|
+
},
|
|
45
|
+
'penalty': {
|
|
46
|
+
'description': 'The penalty (regularization term) to be used.',
|
|
47
|
+
'default': 'l2',
|
|
48
|
+
'categorical': ['l2', 'l1', 'elasticnet']
|
|
49
|
+
},
|
|
50
|
+
'alpha': {
|
|
51
|
+
'description': 'Constant that multiplies the regularization term.',
|
|
52
|
+
'default': 0.0001,
|
|
53
|
+
'range': [1e-07, 0.1]
|
|
54
|
+
},
|
|
55
|
+
'l1_ratio': {
|
|
56
|
+
'description': 'The Elastic Net mixing parameter.',
|
|
57
|
+
'default': 0.15,
|
|
58
|
+
'range': [1e-09, 1.0]
|
|
59
|
+
},
|
|
60
|
+
'max_iter': {
|
|
61
|
+
'description': 'Maximum number of passes over the training data.',
|
|
62
|
+
'default': 1000,
|
|
63
|
+
'range': [100, 5000]
|
|
64
|
+
},
|
|
65
|
+
'tol': {
|
|
66
|
+
'description': 'The stopping criterion.',
|
|
67
|
+
'default': 0.001,
|
|
68
|
+
'range': [1e-05, 0.1]
|
|
69
|
+
},
|
|
70
|
+
'learning_rate': {
|
|
71
|
+
'description': 'Learning rate schedule.',
|
|
72
|
+
'default': 'optimal',
|
|
73
|
+
'categorical': ['optimal', 'invscaling', 'constant', 'adaptive']
|
|
74
|
+
},
|
|
75
|
+
'eta0': {
|
|
76
|
+
'description': textwrap.dedent('''\
|
|
77
|
+
The initial learning rate for the "constant", "invscaling"
|
|
78
|
+
or "adaptive" schedules.'''),
|
|
79
|
+
'default': 0.01,
|
|
80
|
+
'range': [1e-07, 0.1]
|
|
81
|
+
},
|
|
82
|
+
'class_weight': {
|
|
83
|
+
'description': textwrap.dedent('''\
|
|
84
|
+
The "balanced" mode uses values of y to adjust weights inversely
|
|
85
|
+
proportional to class frequencies.'''),
|
|
86
|
+
'default': None,
|
|
87
|
+
'categorical': [None, 'balanced']
|
|
88
|
+
},
|
|
89
|
+
'average': {
|
|
90
|
+
'description': textwrap.dedent('''\
|
|
91
|
+
When set to True, computes the averaged SGD weights across
|
|
92
|
+
all updates and stores the result in the coef_ attribute.'''),
|
|
93
|
+
'default': False
|
|
94
|
+
},
|
|
95
|
+
'random_state': {
|
|
96
|
+
'description': 'Random state for reproducibility.',
|
|
97
|
+
'default': 42
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
self.model: SGDClassifier = None
|
|
101
|
+
self.columns: list[str] = []
|
|
102
|
+
self.target_type: str | None = None
|
|
103
|
+
|
|
104
|
+
def _select_features(self, X):
|
|
105
|
+
if self.columns and hasattr(X, 'columns'):
|
|
106
|
+
return X[self.columns]
|
|
107
|
+
return X
|
|
108
|
+
|
|
109
|
+
def _decision_function_proba(self, scores: np.ndarray) -> np.ndarray:
|
|
110
|
+
if scores.ndim == 1:
|
|
111
|
+
probs_pos = 1.0 / (1.0 + np.exp(-scores))
|
|
112
|
+
return np.column_stack([1.0 - probs_pos, probs_pos])
|
|
113
|
+
if self.target_type == 'multilabel-indicator':
|
|
114
|
+
return 1.0 / (1.0 + np.exp(-scores))
|
|
115
|
+
max_scores = np.max(scores, axis=1, keepdims=True)
|
|
116
|
+
exp_scores = np.exp(scores - max_scores)
|
|
117
|
+
return exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
|
|
118
|
+
|
|
119
|
+
def fit(self, dataset: Dataset): # pylint: disable=unused-argument
|
|
120
|
+
self.columns = dataset.get_columns_names_by_type(DataType.NUMERIC)
|
|
121
|
+
if not self.columns:
|
|
122
|
+
self.columns = dataset.features
|
|
123
|
+
|
|
124
|
+
self.target_type = dataset.type_of_target
|
|
125
|
+
self.model = SGDClassifier(**self.passthrough_parameters())
|
|
126
|
+
self.model.fit(self._select_features(dataset.X), dataset.y)
|
|
127
|
+
return self
|
|
128
|
+
|
|
129
|
+
def predict(self, X):
|
|
130
|
+
return super().predict(self._select_features(X))
|
|
131
|
+
|
|
132
|
+
def predict_proba(self, X):
|
|
133
|
+
if self.model is None:
|
|
134
|
+
raise AttributeError("Model is not fitted")
|
|
135
|
+
if getattr(self.model, 'loss', None) in ['log_loss', 'modified_huber']:
|
|
136
|
+
return self.model.predict_proba(self._select_features(X))
|
|
137
|
+
scores = self.model.decision_function(self._select_features(X))
|
|
138
|
+
return self._decision_function_proba(np.asarray(scores))
|
|
139
|
+
|
|
140
|
+
def score(self, X, y=None, *args, **kwargs):
|
|
141
|
+
return self.model.score(self._select_features(X), y, *args, **kwargs)
|
|
142
|
+
|
|
143
|
+
def suitable(self, dataset: Dataset) -> bool:
|
|
144
|
+
return dataset.type_of_target in \
|
|
145
|
+
['binary', 'multiclass', 'multilabel-indicator'] \
|
|
146
|
+
and bool(dataset.get_columns_names_by_type(DataType.NUMERIC))
|
|
147
|
+
|
|
148
|
+
def priorize(self, candidate: Candidate = None) -> float:
|
|
149
|
+
return 0.5 # neutral
|