From 625c451bcc20f9d23263d5b0f48cfb375ff92310 Mon Sep 17 00:00:00 2001 From: hayesall Date: Sat, 12 Nov 2022 14:24:07 -0500 Subject: [PATCH 01/11] =?UTF-8?q?=F0=9F=91=BD=EF=B8=8F=20Replace=20`stats.?= =?UTF-8?q?mode`=20calls=20with=20`fixes`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- imblearn/over_sampling/_smote/base.py | 4 ++-- .../_prototype_selection/_edited_nearest_neighbours.py | 4 ++-- .../_prototype_selection/_neighbourhood_cleaning_rule.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imblearn/over_sampling/_smote/base.py b/imblearn/over_sampling/_smote/base.py index 6249dc876..5a57dab3a 100644 --- a/imblearn/over_sampling/_smote/base.py +++ b/imblearn/over_sampling/_smote/base.py @@ -12,7 +12,6 @@ import numpy as np from scipy import sparse -from scipy import stats from sklearn.preprocessing import OneHotEncoder, OrdinalEncoder from sklearn.utils import check_random_state @@ -20,6 +19,7 @@ from sklearn.utils import check_array from sklearn.utils.sparsefuncs_fast import csr_mean_variance_axis0 from sklearn.utils.sparsefuncs_fast import csc_mean_variance_axis0 +from sklearn.utils.fixes import _mode from ..base import BaseOverSampler from ...metrics.pairwise import ValueDifferenceMetric @@ -786,7 +786,7 @@ def _make_samples(self, X_class, klass, y_dtype, nn_indices, n_samples): # where for each feature individually, each category generated is the # most common category X_new = np.squeeze( - stats.mode(X_class[nn_indices[samples_indices]], axis=1).mode, axis=1 + _mode(X_class[nn_indices[samples_indices]], axis=1).mode, axis=1 ) y_new = np.full(n_samples, fill_value=klass, dtype=y_dtype) return X_new, y_new diff --git a/imblearn/under_sampling/_prototype_selection/_edited_nearest_neighbours.py b/imblearn/under_sampling/_prototype_selection/_edited_nearest_neighbours.py index d06a867be..0173bcd40 100644 --- a/imblearn/under_sampling/_prototype_selection/_edited_nearest_neighbours.py +++ b/imblearn/under_sampling/_prototype_selection/_edited_nearest_neighbours.py @@ -9,9 +9,9 @@ from collections import Counter import numpy as np -from scipy.stats import mode from sklearn.utils import _safe_indexing +from sklearn.utils.fixes import _mode from ..base import BaseCleaningSampler from ...utils import check_neighbors_object @@ -155,7 +155,7 @@ def _fit_resample(self, X, y): nnhood_idx = self.nn_.kneighbors(X_class, return_distance=False)[:, 1:] nnhood_label = y[nnhood_idx] if self.kind_sel == "mode": - nnhood_label, _ = mode(nnhood_label, axis=1) + nnhood_label, _ = _mode(nnhood_label, axis=1) nnhood_bool = np.ravel(nnhood_label) == y_class elif self.kind_sel == "all": nnhood_label = nnhood_label == target_class diff --git a/imblearn/under_sampling/_prototype_selection/_neighbourhood_cleaning_rule.py b/imblearn/under_sampling/_prototype_selection/_neighbourhood_cleaning_rule.py index 3cb3d5320..8320fd366 100644 --- a/imblearn/under_sampling/_prototype_selection/_neighbourhood_cleaning_rule.py +++ b/imblearn/under_sampling/_prototype_selection/_neighbourhood_cleaning_rule.py @@ -7,9 +7,9 @@ from collections import Counter import numpy as np -from scipy.stats import mode from sklearn.utils import _safe_indexing +from sklearn.utils.fixes import _mode from ..base import BaseCleaningSampler from ._edited_nearest_neighbours import EditedNearestNeighbours @@ -182,7 +182,7 @@ def _fit_resample(self, X, y): nnhood_idx = self.nn_.kneighbors(X_class, return_distance=False)[:, 1:] nnhood_label = y[nnhood_idx] if self.kind_sel == "mode": - nnhood_label_majority, _ = mode(nnhood_label, axis=1) + nnhood_label_majority, _ = _mode(nnhood_label, axis=1) nnhood_bool = np.ravel(nnhood_label_majority) == y_class elif self.kind_sel == "all": nnhood_label_majority = nnhood_label == class_minority From 321a6d3c6bff596ca43fd428e188d852944f2609 Mon Sep 17 00:00:00 2001 From: hayesall Date: Sat, 12 Nov 2022 14:41:01 -0500 Subject: [PATCH 02/11] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20`SKLEARN=5FMI?= =?UTF-8?q?N=5FVERSION=3D1.1.3`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- imblearn/_min_dependencies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imblearn/_min_dependencies.py b/imblearn/_min_dependencies.py index a9e0d41eb..7cf2b3c56 100644 --- a/imblearn/_min_dependencies.py +++ b/imblearn/_min_dependencies.py @@ -4,7 +4,7 @@ NUMPY_MIN_VERSION = "1.17.3" SCIPY_MIN_VERSION = "1.3.2" PANDAS_MIN_VERSION = "1.0.5" -SKLEARN_MIN_VERSION = "1.1.0" +SKLEARN_MIN_VERSION = "1.1.3" TENSORFLOW_MIN_VERSION = "2.4.3" KERAS_MIN_VERSION = "2.4.3" JOBLIB_MIN_VERSION = "1.0.0" From 6cfc3f1c3771d9e0c3f7d7a68ee178aba6c50622 Mon Sep 17 00:00:00 2001 From: hayesall Date: Sat, 12 Nov 2022 15:12:42 -0500 Subject: [PATCH 03/11] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20`JOBLIB=5FMIN?= =?UTF-8?q?=5FVERSION=3D1.1.1`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compat with scikit-learn --- imblearn/_min_dependencies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imblearn/_min_dependencies.py b/imblearn/_min_dependencies.py index 7cf2b3c56..72976f2b1 100644 --- a/imblearn/_min_dependencies.py +++ b/imblearn/_min_dependencies.py @@ -7,7 +7,7 @@ SKLEARN_MIN_VERSION = "1.1.3" TENSORFLOW_MIN_VERSION = "2.4.3" KERAS_MIN_VERSION = "2.4.3" -JOBLIB_MIN_VERSION = "1.0.0" +JOBLIB_MIN_VERSION = "1.1.1" THREADPOOLCTL_MIN_VERSION = "2.0.0" PYTEST_MIN_VERSION = "5.0.1" From 06dbbee9ada3440c64e5405b0976bb0e9cb6d339 Mon Sep 17 00:00:00 2001 From: hayesall Date: Sat, 12 Nov 2022 15:35:45 -0500 Subject: [PATCH 04/11] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20minimum=20num?= =?UTF-8?q?py=20version=20in=20`py37=5Fconda=5Fdefaults=5Fopenblas`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4605d2ced..949c903ec 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -146,7 +146,7 @@ jobs: CONDA_CHANNEL: 'conda-forge' PYTHON_VERSION: '3.8' BLAS: 'openblas' - NUMPY_VERSION: '1.19.5' # we cannot get an older version of the dependencies resolution + NUMPY_VERSION: '1.21.0' # we cannot get an older version of the dependencies resolution SCIPY_VERSION: 'min' SKLEARN_VERSION: 'min' MATPLOTLIB_VERSION: 'none' From 9db0b2025707a352fdd17c2c302adb792a6708ea Mon Sep 17 00:00:00 2001 From: hayesall Date: Fri, 2 Dec 2022 13:13:13 -0500 Subject: [PATCH 05/11] =?UTF-8?q?=F0=9F=91=BD=EF=B8=8F=20Pin=20flake8=20to?= =?UTF-8?q?=205.0.4=20in=20azure=20pipelines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d701c8c5d..5ed7959ff 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -45,7 +45,7 @@ jobs: versionSpec: '3.9' - bash: | # Include pytest compatibility with mypy - pip install pytest flake8 mypy==0.782 black==22.3 + pip install pytest flake8==5.0.4 mypy==0.782 black==22.3 displayName: Install linters - bash: | black --check --diff . From ec50f5b0123c4dfa0c5e5259a163b2776f1c5a84 Mon Sep 17 00:00:00 2001 From: hayesall Date: Fri, 2 Dec 2022 13:37:33 -0500 Subject: [PATCH 06/11] =?UTF-8?q?=E2=9C=A8=20Add=20alternative=20with=20im?= =?UTF-8?q?blearn.fixes.=5Fmode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- imblearn/over_sampling/_smote/base.py | 2 +- .../_edited_nearest_neighbours.py | 3 ++- .../_neighbourhood_cleaning_rule.py | 3 ++- imblearn/utils/fixes.py | 26 +++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 imblearn/utils/fixes.py diff --git a/imblearn/over_sampling/_smote/base.py b/imblearn/over_sampling/_smote/base.py index 5a57dab3a..2221cb9ab 100644 --- a/imblearn/over_sampling/_smote/base.py +++ b/imblearn/over_sampling/_smote/base.py @@ -19,7 +19,6 @@ from sklearn.utils import check_array from sklearn.utils.sparsefuncs_fast import csr_mean_variance_axis0 from sklearn.utils.sparsefuncs_fast import csc_mean_variance_axis0 -from sklearn.utils.fixes import _mode from ..base import BaseOverSampler from ...metrics.pairwise import ValueDifferenceMetric @@ -29,6 +28,7 @@ from ...utils._docstring import _n_jobs_docstring from ...utils._docstring import _random_state_docstring from ...utils._validation import _deprecate_positional_args +from ...utils.fixes import _mode class BaseSMOTE(BaseOverSampler): diff --git a/imblearn/under_sampling/_prototype_selection/_edited_nearest_neighbours.py b/imblearn/under_sampling/_prototype_selection/_edited_nearest_neighbours.py index 0173bcd40..87c1ce284 100644 --- a/imblearn/under_sampling/_prototype_selection/_edited_nearest_neighbours.py +++ b/imblearn/under_sampling/_prototype_selection/_edited_nearest_neighbours.py @@ -11,13 +11,14 @@ import numpy as np from sklearn.utils import _safe_indexing -from sklearn.utils.fixes import _mode from ..base import BaseCleaningSampler from ...utils import check_neighbors_object from ...utils import Substitution from ...utils._docstring import _n_jobs_docstring from ...utils._validation import _deprecate_positional_args +from ...utils.fixes import _mode + SEL_KIND = ("all", "mode") diff --git a/imblearn/under_sampling/_prototype_selection/_neighbourhood_cleaning_rule.py b/imblearn/under_sampling/_prototype_selection/_neighbourhood_cleaning_rule.py index 8320fd366..80735253d 100644 --- a/imblearn/under_sampling/_prototype_selection/_neighbourhood_cleaning_rule.py +++ b/imblearn/under_sampling/_prototype_selection/_neighbourhood_cleaning_rule.py @@ -9,7 +9,6 @@ import numpy as np from sklearn.utils import _safe_indexing -from sklearn.utils.fixes import _mode from ..base import BaseCleaningSampler from ._edited_nearest_neighbours import EditedNearestNeighbours @@ -17,6 +16,8 @@ from ...utils import Substitution from ...utils._docstring import _n_jobs_docstring from ...utils._validation import _deprecate_positional_args +from ...utils.fixes import _mode + SEL_KIND = ("all", "mode") diff --git a/imblearn/utils/fixes.py b/imblearn/utils/fixes.py new file mode 100644 index 000000000..f5f162354 --- /dev/null +++ b/imblearn/utils/fixes.py @@ -0,0 +1,26 @@ +"""Compatibility fixes for older version of python, numpy and scipy +If you add content to this file, please give the version of the package +at which the fix is no longer needed. + +Backdated from scikit-learn. +""" +# Authors: Emmanuelle Gouillart +# Gael Varoquaux +# Fabian Pedregosa +# Lars Buitinck +# +# License: BSD 3 clause + +from sklearn.externals._packaging.version import parse as parse_version +import scipy +import scipy.stats + + +sp_version = parse_version(scipy.__version__) + + +# TODO: Remove when SciPy 1.9 is the minimum supported version +def _mode(a, axis=0): + if sp_version >= parse_version("1.9.0"): + return scipy.stats.mode(a, axis=axis, keepdims=True) + return scipy.stats.mode(a, axis=axis) From cb7763f9531e5e603993a85de35982d29c9be1cb Mon Sep 17 00:00:00 2001 From: hayesall Date: Fri, 2 Dec 2022 14:03:38 -0500 Subject: [PATCH 07/11] =?UTF-8?q?=F0=9F=93=8C=20Un-bump=20sklearn=20and=20?= =?UTF-8?q?joblib?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- imblearn/_min_dependencies.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imblearn/_min_dependencies.py b/imblearn/_min_dependencies.py index 72976f2b1..a9e0d41eb 100644 --- a/imblearn/_min_dependencies.py +++ b/imblearn/_min_dependencies.py @@ -4,10 +4,10 @@ NUMPY_MIN_VERSION = "1.17.3" SCIPY_MIN_VERSION = "1.3.2" PANDAS_MIN_VERSION = "1.0.5" -SKLEARN_MIN_VERSION = "1.1.3" +SKLEARN_MIN_VERSION = "1.1.0" TENSORFLOW_MIN_VERSION = "2.4.3" KERAS_MIN_VERSION = "2.4.3" -JOBLIB_MIN_VERSION = "1.1.1" +JOBLIB_MIN_VERSION = "1.0.0" THREADPOOLCTL_MIN_VERSION = "2.0.0" PYTEST_MIN_VERSION = "5.0.1" From f1adb7fddcec59b000e2f800813ac873df4846ba Mon Sep 17 00:00:00 2001 From: hayesall Date: Fri, 2 Dec 2022 15:21:10 -0500 Subject: [PATCH 08/11] =?UTF-8?q?=F0=9F=94=A5=20Drop=20`-Werror::FutureWar?= =?UTF-8?q?ning`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build_tools/azure/test_script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_tools/azure/test_script.sh b/build_tools/azure/test_script.sh index 57136b41c..e9109e953 100755 --- a/build_tools/azure/test_script.sh +++ b/build_tools/azure/test_script.sh @@ -36,7 +36,7 @@ fi if [[ -n "$CHECK_WARNINGS" ]]; then # numpy's 1.19.0's tostring() deprecation is ignored until scipy and joblib removes its usage - TEST_CMD="$TEST_CMD -Werror::DeprecationWarning -Werror::FutureWarning -Wignore:tostring:DeprecationWarning" + TEST_CMD="$TEST_CMD -Werror::DeprecationWarning -Wignore:tostring:DeprecationWarning" # numpy's 1.20's np.object deprecationg is ignored until tensorflow removes its usage TEST_CMD="$TEST_CMD -Wignore:\`np.object\`:DeprecationWarning" From 26be29e0713b550981c249105d18972986aa7938 Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Sat, 3 Dec 2022 00:09:58 +0100 Subject: [PATCH 09/11] iter --- azure-pipelines.yml | 2 +- build_tools/azure/test_script.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1c1c87cd0..e733ed93f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -45,7 +45,7 @@ jobs: versionSpec: '3.9' - bash: | # Include pytest compatibility with mypy - pip install pytest flake8==5.0.4 mypy==0.782 black==22.3 + pip install pytest flake8 mypy==0.782 black==22.3 displayName: Install linters - bash: | black --check --diff . diff --git a/build_tools/azure/test_script.sh b/build_tools/azure/test_script.sh index e9109e953..57136b41c 100755 --- a/build_tools/azure/test_script.sh +++ b/build_tools/azure/test_script.sh @@ -36,7 +36,7 @@ fi if [[ -n "$CHECK_WARNINGS" ]]; then # numpy's 1.19.0's tostring() deprecation is ignored until scipy and joblib removes its usage - TEST_CMD="$TEST_CMD -Werror::DeprecationWarning -Wignore:tostring:DeprecationWarning" + TEST_CMD="$TEST_CMD -Werror::DeprecationWarning -Werror::FutureWarning -Wignore:tostring:DeprecationWarning" # numpy's 1.20's np.object deprecationg is ignored until tensorflow removes its usage TEST_CMD="$TEST_CMD -Wignore:\`np.object\`:DeprecationWarning" From 14fcd35cf05f65759995647812732db733e1ac9c Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Sat, 3 Dec 2022 00:12:13 +0100 Subject: [PATCH 10/11] iter --- imblearn/utils/fixes.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/imblearn/utils/fixes.py b/imblearn/utils/fixes.py index f5f162354..ce8d52831 100644 --- a/imblearn/utils/fixes.py +++ b/imblearn/utils/fixes.py @@ -1,20 +1,14 @@ -"""Compatibility fixes for older version of python, numpy and scipy -If you add content to this file, please give the version of the package -at which the fix is no longer needed. +"""Compatibility fixes for older version of python, numpy, scipy, and +scikit-learn. -Backdated from scikit-learn. +If you add content to this file, please give the version of the package at +which the fix is no longer needed. """ -# Authors: Emmanuelle Gouillart -# Gael Varoquaux -# Fabian Pedregosa -# Lars Buitinck -# -# License: BSD 3 clause -from sklearn.externals._packaging.version import parse as parse_version import scipy import scipy.stats +from sklearn.utils.fixes import parse_version sp_version = parse_version(scipy.__version__) From 85f372da176ef4f6009f0ece96845eb8aa5a1979 Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Sat, 3 Dec 2022 00:36:27 +0100 Subject: [PATCH 11/11] iter --- build_tools/azure/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_tools/azure/install.sh b/build_tools/azure/install.sh index 250d56dea..8d60203f7 100755 --- a/build_tools/azure/install.sh +++ b/build_tools/azure/install.sh @@ -68,7 +68,7 @@ elif [[ "$DISTRIB" == "conda-pip-latest" ]]; then python -m pip install -U pip python -m pip install pandas matplotlib - python -m pip install --pre scikit-learn + python -m pip install scikit-learn elif [[ "$DISTRIB" == "conda-pip-latest-tensorflow" ]]; then make_conda "python=$PYTHON_VERSION"