selective 1.2.0__tar.gz → 1.2.1__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.
Files changed (40) hide show
  1. {selective-1.2.0/selective.egg-info → selective-1.2.1}/PKG-INFO +1 -1
  2. {selective-1.2.0 → selective-1.2.1}/feature/_version.py +1 -1
  3. {selective-1.2.0 → selective-1.2.1}/feature/linear.py +27 -15
  4. {selective-1.2.0 → selective-1.2.1}/feature/text_based.py +1 -1
  5. {selective-1.2.0 → selective-1.2.1}/feature/utils.py +2 -6
  6. {selective-1.2.0 → selective-1.2.1/selective.egg-info}/PKG-INFO +1 -1
  7. {selective-1.2.0 → selective-1.2.1}/LICENSE.md +0 -0
  8. {selective-1.2.0 → selective-1.2.1}/MANIFEST.in +0 -0
  9. {selective-1.2.0 → selective-1.2.1}/NOTICES +0 -0
  10. {selective-1.2.0 → selective-1.2.1}/README.md +0 -0
  11. {selective-1.2.0 → selective-1.2.1}/feature/__init__.py +0 -0
  12. {selective-1.2.0 → selective-1.2.1}/feature/base.py +0 -0
  13. {selective-1.2.0 → selective-1.2.1}/feature/correlation.py +0 -0
  14. {selective-1.2.0 → selective-1.2.1}/feature/kl_divergence.py +0 -0
  15. {selective-1.2.0 → selective-1.2.1}/feature/selector.py +0 -0
  16. {selective-1.2.0 → selective-1.2.1}/feature/statistical.py +0 -0
  17. {selective-1.2.0 → selective-1.2.1}/feature/tree_based.py +0 -0
  18. {selective-1.2.0 → selective-1.2.1}/feature/variance.py +0 -0
  19. {selective-1.2.0 → selective-1.2.1}/requirements.txt +0 -0
  20. {selective-1.2.0 → selective-1.2.1}/selective.egg-info/SOURCES.txt +0 -0
  21. {selective-1.2.0 → selective-1.2.1}/selective.egg-info/dependency_links.txt +0 -0
  22. {selective-1.2.0 → selective-1.2.1}/selective.egg-info/requires.txt +0 -0
  23. {selective-1.2.0 → selective-1.2.1}/selective.egg-info/top_level.txt +0 -0
  24. {selective-1.2.0 → selective-1.2.1}/setup.cfg +0 -0
  25. {selective-1.2.0 → selective-1.2.1}/setup.py +0 -0
  26. {selective-1.2.0 → selective-1.2.1}/tests/test_base.py +0 -0
  27. {selective-1.2.0 → selective-1.2.1}/tests/test_benchmark.py +0 -0
  28. {selective-1.2.0 → selective-1.2.1}/tests/test_correlation.py +0 -0
  29. {selective-1.2.0 → selective-1.2.1}/tests/test_linear.py +0 -0
  30. {selective-1.2.0 → selective-1.2.1}/tests/test_parallel.py +0 -0
  31. {selective-1.2.0 → selective-1.2.1}/tests/test_stat_anova.py +0 -0
  32. {selective-1.2.0 → selective-1.2.1}/tests/test_stat_chi.py +0 -0
  33. {selective-1.2.0 → selective-1.2.1}/tests/test_stat_kl.py +0 -0
  34. {selective-1.2.0 → selective-1.2.1}/tests/test_stat_maximal.py +0 -0
  35. {selective-1.2.0 → selective-1.2.1}/tests/test_stat_mutual.py +0 -0
  36. {selective-1.2.0 → selective-1.2.1}/tests/test_stat_vif.py +0 -0
  37. {selective-1.2.0 → selective-1.2.1}/tests/test_text.py +0 -0
  38. {selective-1.2.0 → selective-1.2.1}/tests/test_tree.py +0 -0
  39. {selective-1.2.0 → selective-1.2.1}/tests/test_utils.py +0 -0
  40. {selective-1.2.0 → selective-1.2.1}/tests/test_variance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: selective
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: feature selection library
5
5
  Home-page: https://github.com/fidelity/selective
6
6
  Author: FMR LLC
@@ -2,4 +2,4 @@
2
2
  # Copyright FMR LLC <opensource@fidelity.com>
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- __version__ = "1.2.0"
5
+ __version__ = "1.2.1"
@@ -3,18 +3,18 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
  from typing import NoReturn, Tuple
6
-
6
+ import numpy as np
7
7
  import pandas as pd
8
8
  from sklearn.linear_model import LinearRegression, Lasso, Ridge
9
9
  from sklearn.linear_model import LogisticRegression, RidgeClassifier
10
-
10
+ from sklearn.multiclass import OneVsRestClassifier
11
11
  from feature.base import _BaseSupervisedSelector, _BaseDispatcher
12
12
  from feature.utils import Num, get_task_string
13
13
 
14
14
 
15
15
  class _Linear(_BaseSupervisedSelector, _BaseDispatcher):
16
16
 
17
- def __init__(self, seed: int, num_features: Num, regularization: str, alpha:Num):
17
+ def __init__(self, seed: int, num_features: Num, regularization: str, alpha: Num):
18
18
  super().__init__(seed)
19
19
 
20
20
  self.num_features = num_features # this could be int or float
@@ -28,20 +28,17 @@ class _Linear(_BaseSupervisedSelector, _BaseDispatcher):
28
28
  self.factory = {"regression_none": LinearRegression(),
29
29
  "regression_lasso": Lasso(random_state=self.seed),
30
30
  "regression_ridge": Ridge(random_state=self.seed),
31
- # "classification_none": LogisticRegression(penalty="none"), # won't converge most times
32
- "classification_none": LogisticRegression(random_state=self.seed,
33
- multi_class="auto", solver="liblinear"),
34
- "classification_lasso": LogisticRegression(random_state=self.seed, penalty='l1',
35
- multi_class="auto", solver="liblinear"),
31
+ "classification_none": OneVsRestClassifier(
32
+ LogisticRegression(random_state=self.seed, solver="liblinear")),
33
+ "classification_lasso": OneVsRestClassifier(
34
+ LogisticRegression(random_state=self.seed, penalty='l1', solver="liblinear")),
36
35
  "classification_ridge": RidgeClassifier(random_state=self.seed)}
37
36
 
38
37
  def get_model_args(self, selection_method) -> Tuple:
39
-
40
38
  # Pack model argument
41
39
  return selection_method.regularization
42
40
 
43
41
  def dispatch_model(self, labels: pd.Series, *args):
44
-
45
42
  # Unpack model argument
46
43
  regularization = args[0]
47
44
 
@@ -49,7 +46,18 @@ class _Linear(_BaseSupervisedSelector, _BaseDispatcher):
49
46
  self.imp = self.factory.get(get_task_string(labels) + regularization)
50
47
 
51
48
  def fit(self, data: pd.DataFrame, labels: pd.Series) -> NoReturn:
49
+ """
50
+ Fits the underlying linear model to the data and calculates absolute feature importances.
51
+
52
+ This method identifies the appropriate model context (regression vs. classification),
53
+ fits it to the training data, and extracts the coefficient weights. For multi-class
54
+ classifiers, it computes a global score by averaging the class-specific absolute weights.
52
55
 
56
+ :param data: The input features dataframe of shape (n_samples, n_features).
57
+ :param labels: The target labels series. Automatically determines whether the task
58
+ is regression or classification.
59
+
60
+ """
53
61
  # Fit linear model
54
62
  self.imp.fit(X=data, y=labels)
55
63
 
@@ -60,15 +68,19 @@ class _Linear(_BaseSupervisedSelector, _BaseDispatcher):
60
68
  # But that does not necessarily mean they are more important
61
69
  # See more discussion here:
62
70
  # https://scikit-learn.org/stable/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#sphx-glr-auto-examples-inspection-plot-linear-model-coefficient-interpretation-py
63
- self.abs_scores = abs(self.imp.coef_)
64
-
65
71
  # LogisticRegression/RidgeClassifier returns a coef_ array of (n_classes, n_features)
66
72
  # These coefficients map the importance of the feature for a specific class.
67
73
  # One approach is to average the importances
68
- if isinstance(self.imp, LogisticRegression) or isinstance(self.imp, RidgeClassifier):
69
- self.abs_scores = abs(self.imp.coef_.mean(0))
74
+ if isinstance(self.imp, OneVsRestClassifier):
75
+ coefficients = np.vstack([estimator.coef_ for estimator in self.imp.estimators_])
76
+ else:
77
+ coefficients = np.asarray(self.imp.coef_)
70
78
 
71
- def transform(self, data: pd.DataFrame) -> pd.DataFrame:
79
+ if isinstance(self.imp, (LogisticRegression, OneVsRestClassifier, RidgeClassifier)):
80
+ self.abs_scores = np.abs(coefficients.mean(0))
81
+ else:
82
+ self.abs_scores = np.abs(coefficients)
72
83
 
84
+ def transform(self, data: pd.DataFrame) -> pd.DataFrame:
73
85
  # Select top-k from data based on abs_scores and num_features
74
86
  return self.get_top_k(data, self.abs_scores)
@@ -647,7 +647,7 @@ def process_category_data(input_df: pd.DataFrame, categories: List[str]) -> pd.D
647
647
  matrix = (input_df.labels.str.split('|', expand=True)
648
648
  .stack()
649
649
  .str.get_dummies()
650
- .groupby(level=0, axis=0)
650
+ .groupby(level=0)
651
651
  .sum()).T
652
652
 
653
653
  check_true(matrix.ndim == 2, ValueError("Process Data Error: matrix should 2D"))
@@ -16,7 +16,6 @@ from sklearn.feature_selection import SelectKBest, SelectPercentile
16
16
  from sklearn.impute import SimpleImputer
17
17
  from sklearn.preprocessing import StandardScaler
18
18
 
19
-
20
19
  Num = Union[int, float]
21
20
  """Num type is defined as integer or float."""
22
21
 
@@ -52,7 +51,6 @@ def get_data_label(sklearn_dataset):
52
51
 
53
52
 
54
53
  def get_task_string(labels: pd.Series):
55
-
56
54
  if labels is None:
57
55
  return "unsupervised_"
58
56
 
@@ -65,7 +63,6 @@ def is_classification(labels: pd.Series):
65
63
 
66
64
 
67
65
  def get_selector(score_func, k: Union[int, float]):
68
-
69
66
  # Top K or Top Percentile
70
67
  if isinstance(k, int):
71
68
  return SelectKBest(score_func, k=k)
@@ -131,7 +128,6 @@ class DataTransformer:
131
128
  """
132
129
 
133
130
  def __init__(self):
134
-
135
131
  # Imputation
136
132
  self.imp = SimpleImputer(strategy='median')
137
133
 
@@ -206,7 +202,7 @@ def reduce_memory(df: pd.DataFrame, verbose=True) -> pd.DataFrame:
206
202
 
207
203
  # Print current column type
208
204
  if verbose:
209
- print(20*"=")
205
+ print(20 * "=")
210
206
  print("Column ", i, ":", col)
211
207
  print("dtype_before: ", df[col].dtype)
212
208
 
@@ -255,7 +251,7 @@ def reduce_memory(df: pd.DataFrame, verbose=True) -> pd.DataFrame:
255
251
  # Print new column type
256
252
  if verbose:
257
253
  print("dtype_after: ", df[col].dtype)
258
- print(20*"=")
254
+ print(20 * "=")
259
255
 
260
256
  memory_after = df.memory_usage().sum() / 1024 ** 2
261
257
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: selective
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: feature selection library
5
5
  Home-page: https://github.com/fidelity/selective
6
6
  Author: FMR LLC
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes