Skip to content

Commit

Permalink
Update for modern versions of sklearn and numpy
Browse files Browse the repository at this point in the history
  • Loading branch information
manuel-calzolari committed Aug 19, 2023
1 parent b119bad commit 12ee9b2
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 16 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ Dependencies

sklearn-genetic requires:

- Python (>= 3.6)
- scikit-learn (>= 0.23)
- Python (>= 3.7)
- scikit-learn (>= 1.0)
- deap (>= 1.0.2)
- numpy
- multiprocess
Expand Down
4 changes: 2 additions & 2 deletions docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Dependencies

sklearn-genetic requires:

- Python (>= 3.6)
- scikit-learn (>= 0.23)
- Python (>= 3.7)
- scikit-learn (>= 1.0)
- deap (>= 1.0.2)
- numpy
- multiprocess
Expand Down
29 changes: 21 additions & 8 deletions genetic_selection/gscv.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import multiprocess
import numpy as np
from sklearn.utils import check_X_y
from sklearn.utils.metaestimators import if_delegate_has_method
from sklearn.utils.metaestimators import available_if
from sklearn.base import BaseEstimator
from sklearn.base import MetaEstimatorMixin
from sklearn.base import clone
Expand Down Expand Up @@ -122,7 +122,7 @@ def _evalFunction(individual, estimator, X, y, groups, cv, scorer, fit_params, m
individual_tuple = tuple(individual)
if caching and individual_tuple in scores_cache:
return scores_cache[individual_tuple][0], individual_sum, scores_cache[individual_tuple][1]
X_selected = X[:, np.array(individual, dtype=np.bool)]
X_selected = X[:, np.array(individual, dtype=bool)]
scores = cross_val_score(estimator=estimator, X=X_selected, y=y, groups=groups, scoring=scorer,
cv=cv, fit_params=fit_params)
scores_mean = np.mean(scores)
Expand All @@ -132,6 +132,19 @@ def _evalFunction(individual, estimator, X, y, groups, cv, scorer, fit_params, m
return scores_mean, individual_sum, scores_std


def _estimator_has(attr):
"""Check if we can delegate a method to the underlying estimator.
First, we check the first fitted estimator if available, otherwise we
check the unfitted estimator.
"""
return lambda self: (
hasattr(self.estimator_, attr)
if hasattr(self, "estimator_")
else hasattr(self.estimator, attr)
)


class GeneticSelectionCV(BaseEstimator, MetaEstimatorMixin, SelectorMixin):
"""Feature selection with genetic algorithm.
Expand Down Expand Up @@ -348,7 +361,7 @@ def _fit(self, X, y, groups=None):
pool.join()

# Set final attributes
support_ = np.array(hof, dtype=np.bool)[0]
support_ = np.array(hof, dtype=bool)[0]
self.estimator_ = clone(self.estimator)
self.estimator_.fit(X[:, support_], y)

Expand All @@ -358,7 +371,7 @@ def _fit(self, X, y, groups=None):

return self

@if_delegate_has_method(delegate='estimator')
@available_if(_estimator_has("predict"))
def predict(self, X):
"""Reduce X to the selected features and then predict using the underlying estimator.
Expand All @@ -374,7 +387,7 @@ def predict(self, X):
"""
return self.estimator_.predict(self.transform(X))

@if_delegate_has_method(delegate='estimator')
@available_if(_estimator_has("score"))
def score(self, X, y):
"""Reduce X to the selected features and return the score of the underlying estimator.
Expand All @@ -391,14 +404,14 @@ def score(self, X, y):
def _get_support_mask(self):
return self.support_

@if_delegate_has_method(delegate='estimator')
@available_if(_estimator_has("decision_function"))
def decision_function(self, X):
return self.estimator_.decision_function(self.transform(X))

@if_delegate_has_method(delegate='estimator')
@available_if(_estimator_has("predict_proba"))
def predict_proba(self, X):
return self.estimator_.predict_proba(self.transform(X))

@if_delegate_has_method(delegate='estimator')
@available_if(_estimator_has("predict_log_proba"))
def predict_log_proba(self, X):
return self.estimator_.predict_log_proba(self.transform(X))
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
scikit-learn>=0.23
scikit-learn>=1.0
deap>=1.0.2
numpy
multiprocess
8 changes: 5 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
'Topic :: Scientific/Engineering',
'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
],
packages=find_packages(),
python_requires='>=3.6',
install_requires=['scikit-learn>=0.23', 'deap>=1.0.2', 'numpy', 'multiprocess'],
python_requires='>=3.7',
install_requires=['scikit-learn>=1.0', 'deap>=1.0.2', 'numpy', 'multiprocess'],
)

0 comments on commit 12ee9b2

Please sign in to comment.