From c17baae2d87b65cdf7a52a277d4fef1e16b980a3 Mon Sep 17 00:00:00 2001 From: "naman.mistry" <65106237+namanmistry@users.noreply.github.com> Date: Fri, 19 May 2023 07:57:33 +0530 Subject: [PATCH 1/3] added new argument support feature_range --- .../exhaustive_feature_selector.py | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/mlxtend/feature_selection/exhaustive_feature_selector.py b/mlxtend/feature_selection/exhaustive_feature_selector.py index 523c4ba19..7dc402a7b 100644 --- a/mlxtend/feature_selection/exhaustive_feature_selector.py +++ b/mlxtend/feature_selection/exhaustive_feature_selector.py @@ -169,8 +169,8 @@ class ExhaustiveFeatureSelector(BaseEstimator, MetaEstimatorMixin): def __init__( self, estimator, - min_features=1, - max_features=1, + min_features=None, + max_features=None, print_progress=True, scoring="accuracy", cv=5, @@ -179,11 +179,13 @@ def __init__( clone_estimator=True, fixed_features=None, feature_groups=None, + feature_range = None ): self.estimator = estimator self.min_features = min_features self.max_features = max_features self.pre_dispatch = pre_dispatch + self.feature_range = feature_range # Want to raise meaningful error message if a # cross-validation generator is inputted if isinstance(cv, types.GeneratorType): @@ -401,8 +403,26 @@ def fit(self, X, y, groups=None, **fit_params): # candidates in the following lines are the non-fixed-features candidates # (the fixed features will be added later to each combination) - min_num_candidates = self.min_features - len(self.fixed_features_group_set) - max_num_candidates = self.max_features - len(self.fixed_features_group_set) + + if self.min_features == None and self.max_features == None: + if self.feature_range == None: + min_num_candidates = 1 + max_num_candidates = 1 + elif self.feature_range == "all": + min_num_candidates = 1 + max_num_candidates = X.shape[1] + else: + try: + min_num_candidates = self.feature_range[0] + max_num_candidates = self.feature_range[1] + except ValueError: + raise ValueError( + """feature_range should be of tuple type. First argument should be + minimum number of feature and second argument shoulf be maximum number of feature""" + ) + else: + min_num_candidates = self.min_features - len(self.fixed_features_group_set) + max_num_candidates = self.max_features - len(self.fixed_features_group_set) candidates = chain.from_iterable( combinations(non_fixed_groups, r=i) for i in range(min_num_candidates, max_num_candidates + 1) From b0ea077fb6f4907fb786618d93a31aef54dda247 Mon Sep 17 00:00:00 2001 From: "naman.mistry" <65106237+namanmistry@users.noreply.github.com> Date: Fri, 19 May 2023 08:22:22 +0530 Subject: [PATCH 2/3] added new feature feature_range --- docs/sources/CHANGELOG.md | 2 +- mlxtend/feature_selection/exhaustive_feature_selector.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/sources/CHANGELOG.md b/docs/sources/CHANGELOG.md index 093dad1d2..89686f5fe 100755 --- a/docs/sources/CHANGELOG.md +++ b/docs/sources/CHANGELOG.md @@ -21,7 +21,7 @@ The CHANGELOG for the current development version is available at - Address NumPy deprecations to make mlxtend compatible to NumPy 1.24 - Changed the signature of the `LinearRegression` model of sklearn in the test removing the `normalize` parameter as it is deprecated. ([#1036](https://github.com/rasbt/mlxtend/issues/1036)) - +- Added a new parameter called `feature_range` in the class `ExhaustiveFeatureSelector` ##### New Features and Enhancements - Document how to use `SequentialFeatureSelector` and multiclass ROC AUC. diff --git a/mlxtend/feature_selection/exhaustive_feature_selector.py b/mlxtend/feature_selection/exhaustive_feature_selector.py index 7dc402a7b..8893f5055 100644 --- a/mlxtend/feature_selection/exhaustive_feature_selector.py +++ b/mlxtend/feature_selection/exhaustive_feature_selector.py @@ -179,7 +179,7 @@ def __init__( clone_estimator=True, fixed_features=None, feature_groups=None, - feature_range = None + feature_range=None ): self.estimator = estimator self.min_features = min_features @@ -403,9 +403,8 @@ def fit(self, X, y, groups=None, **fit_params): # candidates in the following lines are the non-fixed-features candidates # (the fixed features will be added later to each combination) - - if self.min_features == None and self.max_features == None: - if self.feature_range == None: + if self.min_features is None and self.max_features is None: + if self.feature_range is None: min_num_candidates = 1 max_num_candidates = 1 elif self.feature_range == "all": From 7d1a00c4dad90a2cf655b6aec7b49675b3115756 Mon Sep 17 00:00:00 2001 From: "naman.mistry" <65106237+namanmistry@users.noreply.github.com> Date: Fri, 19 May 2023 08:24:03 +0530 Subject: [PATCH 3/3] Added new parameter feature_range --- docs/sources/CHANGELOG.md | 2 +- mlxtend/feature_selection/exhaustive_feature_selector.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/sources/CHANGELOG.md b/docs/sources/CHANGELOG.md index 89686f5fe..093dad1d2 100755 --- a/docs/sources/CHANGELOG.md +++ b/docs/sources/CHANGELOG.md @@ -21,7 +21,7 @@ The CHANGELOG for the current development version is available at - Address NumPy deprecations to make mlxtend compatible to NumPy 1.24 - Changed the signature of the `LinearRegression` model of sklearn in the test removing the `normalize` parameter as it is deprecated. ([#1036](https://github.com/rasbt/mlxtend/issues/1036)) -- Added a new parameter called `feature_range` in the class `ExhaustiveFeatureSelector` + ##### New Features and Enhancements - Document how to use `SequentialFeatureSelector` and multiclass ROC AUC. diff --git a/mlxtend/feature_selection/exhaustive_feature_selector.py b/mlxtend/feature_selection/exhaustive_feature_selector.py index 8893f5055..7dc402a7b 100644 --- a/mlxtend/feature_selection/exhaustive_feature_selector.py +++ b/mlxtend/feature_selection/exhaustive_feature_selector.py @@ -179,7 +179,7 @@ def __init__( clone_estimator=True, fixed_features=None, feature_groups=None, - feature_range=None + feature_range = None ): self.estimator = estimator self.min_features = min_features @@ -403,8 +403,9 @@ def fit(self, X, y, groups=None, **fit_params): # candidates in the following lines are the non-fixed-features candidates # (the fixed features will be added later to each combination) - if self.min_features is None and self.max_features is None: - if self.feature_range is None: + + if self.min_features == None and self.max_features == None: + if self.feature_range == None: min_num_candidates = 1 max_num_candidates = 1 elif self.feature_range == "all":