From dc9c81b76d968f46083376b2f208a58193a8b032 Mon Sep 17 00:00:00 2001 From: Nico de Vos Date: Sat, 26 Feb 2022 10:13:59 -0800 Subject: [PATCH 1/6] fix encoding map type --- kmodes/util/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmodes/util/__init__.py b/kmodes/util/__init__.py index ae31179..22b1518 100644 --- a/kmodes/util/__init__.py +++ b/kmodes/util/__init__.py @@ -39,7 +39,7 @@ def encode_features(X, enc_map=None): else: fit = False - Xenc = np.zeros(X.shape, dtype='uint32') + Xenc = np.zeros(X.shape, dtype='int32') for ii in range(X.shape[1]): if fit: col_enc = {val: jj for jj, val in enumerate(np.unique(X[:, ii])) From f8ca5498a4603a54a6c5462b38ca41362fc8f16d Mon Sep 17 00:00:00 2001 From: Nico de Vos Date: Sat, 26 Feb 2022 10:23:40 -0800 Subject: [PATCH 2/6] use pytest instead of nose --- .travis.yml | 2 +- kmodes/tests/test_common.py | 6 +++--- kmodes/tests/test_kmodes.py | 10 ++++++++-- kmodes/tests/test_kprototypes.py | 3 +-- kmodes/util/tests/test_dissim.py | 19 +++++++++---------- kmodes/util/tests/test_util.py | 5 ++--- setup.py | 3 ++- 7 files changed, 26 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index d2e5db6..67624c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ install: # Run tests script: - - nosetests --with-coverage + - pytest --cov # Calculate coverage after_success: diff --git a/kmodes/tests/test_common.py b/kmodes/tests/test_common.py index 7a4b73a..c6e4caf 100644 --- a/kmodes/tests/test_common.py +++ b/kmodes/tests/test_common.py @@ -64,8 +64,8 @@ def test_all_estimator_no_base_class(): def test_all_estimators(): for name, Estimator in all_estimators(): - yield (_named_check(check_parameters_default_constructible, name), - name, Estimator()) + return (_named_check(check_parameters_default_constructible, name), + name, Estimator()) def test_non_meta_estimators(): @@ -79,4 +79,4 @@ def test_non_meta_estimators(): estimator = Estimator() for check in _yield_all_checks(estimator): if hasattr(check, '__name__') and check.__name__ in relevant_checks: - yield _named_check(check, name), name, estimator + return _named_check(check, name), name, estimator diff --git a/kmodes/tests/test_kmodes.py b/kmodes/tests/test_kmodes.py index 7ac867a..178ffa8 100644 --- a/kmodes/tests/test_kmodes.py +++ b/kmodes/tests/test_kmodes.py @@ -6,7 +6,6 @@ import unittest import numpy as np -from nose.tools import assert_equal from kmodes.kmodes import KModes from kmodes.util.dissim import ng_dissim, jaccard_dissim_binary, jaccard_dissim_label @@ -234,7 +233,14 @@ class TestKModes(unittest.TestCase): def test_pickle(self): obj = KModes() s = pickle.dumps(obj) - assert_equal(type(pickle.loads(s)), obj.__class__) + assert type(pickle.loads(s)) == obj.__class__ + + def test_pickle_fitted(self): + kmodes_huang = KModes(n_clusters=4, n_init=2, init='Huang', verbose=2, + random_state=42) + model = kmodes_huang.fit(SOYBEAN) + s = pickle.dumps(model) + assert type(pickle.loads(s)) == model.__class__ def test_kmodes_huang_soybean(self): kmodes_huang = KModes(n_clusters=4, n_init=2, init='Huang', verbose=2, diff --git a/kmodes/tests/test_kprototypes.py b/kmodes/tests/test_kprototypes.py index fa97256..c7bbcf1 100644 --- a/kmodes/tests/test_kprototypes.py +++ b/kmodes/tests/test_kprototypes.py @@ -6,7 +6,6 @@ import unittest import numpy as np -from nose.tools import assert_equal from kmodes import kprototypes from kmodes.tests.test_kmodes import assert_cluster_splits_equal @@ -39,7 +38,7 @@ class TestKProtoTypes(unittest.TestCase): def test_pickle(self): obj = kprototypes.KPrototypes() s = pickle.dumps(obj) - assert_equal(type(pickle.loads(s)), obj.__class__) + assert type(pickle.loads(s)) == obj.__class__ def test_kprotoypes_categoricals_stocks(self): # Number/index of categoricals does not make sense diff --git a/kmodes/util/tests/test_dissim.py b/kmodes/util/tests/test_dissim.py index ef55afa..bcd67b4 100644 --- a/kmodes/util/tests/test_dissim.py +++ b/kmodes/util/tests/test_dissim.py @@ -5,7 +5,6 @@ import unittest import numpy as np -from nose.tools import assert_equal from sklearn.utils._testing import assert_array_equal from kmodes.util.dissim import matching_dissim, euclidean_dissim, ng_dissim @@ -17,11 +16,11 @@ class TestDissimilarityMeasures(unittest.TestCase): def test_matching_dissim(self): a = np.array([[0, 1, 2, 0, 1, 2]]) b = np.array([[0, 1, 2, 0, 1, 0]]) - assert_equal(1, matching_dissim(a, b)) + assert 1 == matching_dissim(a, b) a = np.array([[np.NaN, 1, 2, 0, 1, 2]]) b = np.array([[0, 1, 2, 0, 1, 0]]) - assert_equal(2, matching_dissim(a, b)) + assert 2 == matching_dissim(a, b) a = np.array([['a', 'b', 'c', 'd']]) b = np.array([['a', 'b', 'c', 'd'], ['d', 'c', 'b', 'a']]) @@ -30,7 +29,7 @@ def test_matching_dissim(self): def test_jaccard_dissim_binary(self): a = np.array([[0, 1, 1, 0, 1, 1]]) b = np.array([[0, 1, 1, 0, 1, 0]]) - assert_equal(0.25, jaccard_dissim_binary(a, b)) + assert 0.25 == jaccard_dissim_binary(a, b) a = np.array([[0, 1, 1, 0, 1, 1]]) b = np.array([[0, np.NaN, 1, 0, 1, 0]]) @@ -46,17 +45,17 @@ def test_jaccard_dissim_binary(self): # test for dissimilarity = 0: sets are the same a = np.array([[1, 1, 0, 1, 1, 0]]) b = np.array([[1, 1, 0, 1, 1, 0]]) - assert_equal(0, jaccard_dissim_binary(a, b)) + assert 0 == jaccard_dissim_binary(a, b) # test for dissimilarity = 1: sets are completely different a = np.array([[0, 0, 1, 0, 0, 1]]) b = np.array([[1, 1, 0, 1, 1, 0]]) - assert_equal(1, jaccard_dissim_binary(a, b)) + assert 1 == jaccard_dissim_binary(a, b) def test_jaccard_dissim_label(self): a = np.array([[0, 1, 2, 0, 1, 2]]) b = np.array([[0, 1, 2, 0, 3, 0]]) - assert_equal(0.25, jaccard_dissim_label(a, b)) + assert 0.25 == jaccard_dissim_label(a, b) a = np.array([[np.NaN, 1, 2, 0, 1, 2]]) b = np.array([[0, 1, 2, 0, 1, 0]]) @@ -66,17 +65,17 @@ def test_jaccard_dissim_label(self): # test for dissimilarity = 0: sets are the same a = np.array([[1, 2, 0, 3, 1, 0]]) b = np.array([[1, 2, 0, 3, 1, 0]]) - assert_equal(0, jaccard_dissim_label(a, b)) + assert 0 == jaccard_dissim_label(a, b) # test for dissimilarity = 1: sets are completely different a = np.array([[1, 2, 0, 3, 1, 0]]) b = np.array([[5, 4, 6, 7, 8, 9]]) - assert_equal(1, jaccard_dissim_label(a, b)) + assert 1 == jaccard_dissim_label(a, b) def test_euclidian_dissim(self): a = np.array([[0., 1., 2., 0., 1., 2.]]) b = np.array([[3., 1., 3., 0., 1., 0.]]) - assert_equal(14., euclidean_dissim(a, b)) + assert 14. == euclidean_dissim(a, b) a = np.array([[np.NaN, 1., 2., 0., 1., 2.]]) b = np.array([[3., 1., 3., 0., 1., 0.]]) diff --git a/kmodes/util/tests/test_util.py b/kmodes/util/tests/test_util.py index efb01ca..d7cd118 100644 --- a/kmodes/util/tests/test_util.py +++ b/kmodes/util/tests/test_util.py @@ -5,7 +5,6 @@ import unittest import numpy as np -from nose.tools import assert_equal from sklearn.utils._testing import assert_array_equal from kmodes.util import get_max_value_key, encode_features, get_unique_rows, \ @@ -47,11 +46,11 @@ class TestUtils(unittest.TestCase): def test_get_max_value_key(self): max_key = get_max_value_key({'a': 3, 'b': 10, 'c': -1, 'd': 9.9}) - assert_equal('b', max_key) + assert 'b' == max_key # Make sure minimum key is consistently selected for equal values. max_key = get_max_value_key({'d': 10, 'c': 10, 'b': 10, 'a': 10}) - assert_equal('a', max_key) + assert 'a' == max_key def test_encode_features(self): X_enc, enc_map = encode_features(STOCKS_CAT) diff --git a/setup.py b/setup.py index 77bc60c..53880d6 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,8 @@ 'joblib>=0.11' ], extras_requires=[ - 'nose', + 'pytest', + 'pytest-cov', ], classifiers=['Development Status :: 3 - Alpha', 'Intended Audience :: Science/Research', From 14ffbe3e295c7ca42de968a63c26f3ed28eba889 Mon Sep 17 00:00:00 2001 From: Nico de Vos Date: Sat, 26 Feb 2022 10:24:08 -0800 Subject: [PATCH 3/6] support 3.10 --- .travis.yml | 1 + setup.py | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 67624c1..4ba0af7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ python: - "3.7" - "3.8" - "3.9" + - "3.10" cache: pip addons: apt: diff --git a/setup.py b/setup.py index 53880d6..d02b55d 100644 --- a/setup.py +++ b/setup.py @@ -43,5 +43,6 @@ 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Topic :: Scientific/Engineering'], ) From 449c0f669fabef37c2b0c2c8d28575c7f1eed345 Mon Sep 17 00:00:00 2001 From: Nico de Vos Date: Sat, 26 Feb 2022 10:34:56 -0800 Subject: [PATCH 4/6] add test --- kmodes/tests/test_kprototypes.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kmodes/tests/test_kprototypes.py b/kmodes/tests/test_kprototypes.py index c7bbcf1..a39441e 100644 --- a/kmodes/tests/test_kprototypes.py +++ b/kmodes/tests/test_kprototypes.py @@ -40,6 +40,12 @@ def test_pickle(self): s = pickle.dumps(obj) assert type(pickle.loads(s)) == obj.__class__ + def test_pickle_fitted(self): + kproto = kprototypes.KPrototypes(n_clusters=4, init='Cao', verbose=2) + model = kproto.fit(STOCKS[:, :2], categorical=1) + s = pickle.dumps(model) + assert type(pickle.loads(s)) == model.__class__ + def test_kprotoypes_categoricals_stocks(self): # Number/index of categoricals does not make sense kproto = kprototypes.KPrototypes(n_clusters=4, init='Cao', verbose=2) From 1d7e080b40f550c142e1b0cbe2383c89e9d1465c Mon Sep 17 00:00:00 2001 From: Nico de Vos Date: Sat, 26 Feb 2022 10:37:48 -0800 Subject: [PATCH 5/6] remove broken requires.io --- README.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.rst b/README.rst index 37e5f44..5f4ca5d 100644 --- a/README.rst +++ b/README.rst @@ -10,9 +10,6 @@ .. image:: https://api.codacy.com/project/badge/Grade/cb19f1f1093a44fa845ebfdaf76975f6 :alt: Codacy Badge :target: https://app.codacy.com/app/nicodv/kmodes?utm_source=github.com&utm_medium=referral&utm_content=nicodv/kmodes&utm_campaign=Badge_Grade_Dashboard -.. image:: https://requires.io/github/nicodv/kmodes/requirements.svg - :target: https://requires.io/github/nicodv/kmodes/requirements/ - :alt: Requirements Status .. image:: https://img.shields.io/pypi/pyversions/kmodes.svg :target: https://pypi.python.org/pypi/kmodes/ :alt: Supported Python versions From c131874943581d7fde699ed154cfb8fdfc682763 Mon Sep 17 00:00:00 2001 From: Nico de Vos Date: Sat, 26 Feb 2022 10:41:26 -0800 Subject: [PATCH 6/6] update badges --- README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 5f4ca5d..cbf8bd6 100644 --- a/README.rst +++ b/README.rst @@ -10,12 +10,12 @@ .. image:: https://api.codacy.com/project/badge/Grade/cb19f1f1093a44fa845ebfdaf76975f6 :alt: Codacy Badge :target: https://app.codacy.com/app/nicodv/kmodes?utm_source=github.com&utm_medium=referral&utm_content=nicodv/kmodes&utm_campaign=Badge_Grade_Dashboard +.. image:: https://img.shields.io/pypi/dm/kmodes.svg + :target: https://pypi.python.org/pypi/kmodes/ + :alt: Monthly downloads .. image:: https://img.shields.io/pypi/pyversions/kmodes.svg :target: https://pypi.python.org/pypi/kmodes/ :alt: Supported Python versions -.. image:: https://img.shields.io/github/stars/nicodv/kmodes.svg - :target: https://github.com/nicodv/kmodes/ - :alt: Github stars .. image:: https://img.shields.io/pypi/l/kmodes.svg :target: https://github.com/nicodv/kmodes/blob/master/LICENSE :alt: License