test:

This commit is contained in:
2022-12-21 19:05:24 +01:00
parent 9db16d9d3c
commit 2775698063
10 changed files with 71 additions and 209 deletions

View File

@@ -14,8 +14,8 @@ cdef extern from "../cppmdlp/CPPFImdlp.h" namespace "mdlp":
cdef class CFImdlp:
cdef CPPFImdlp *thisptr
def __cinit__(self, proposal):
self.thisptr = new CPPFImdlp(proposal)
def __cinit__(self, algorithm):
self.thisptr = new CPPFImdlp(algorithm)
def __dealloc__(self):
del self.thisptr
def fit(self, X, y):

View File

@@ -7,23 +7,22 @@ from joblib import Parallel, delayed
class FImdlp(TransformerMixin, BaseEstimator):
def __init__(self, n_jobs=-1, proposal=0):
def __init__(self, algorithm=0, n_jobs=-1):
self.algorithm = algorithm
self.n_jobs = n_jobs
self.proposal = proposal
"""Fayyad - Irani MDLP discretization algorithm based implementation.
Parameters
----------
algorithm : int, default=0
The type of algorithm to use computing the cut points.
0 - Definitive implementation
1 - Alternative proposal
n_jobs : int, default=-1
The number of jobs to run in parallel. :meth:`fit` and
:meth:`transform`, are parallelized over the features. ``-1`` means
using all cores available.
proposal : int, default=0
The type of algorithm to use computing the cut points.
0 - Normal implementation
1 - JA Proposal
2 - Original proposal
Attributes
----------
@@ -100,7 +99,7 @@ class FImdlp(TransformerMixin, BaseEstimator):
def _fit_discretizer(self, feature):
if feature in self.features_:
self.discretizer_[feature] = CFImdlp(proposal=self.proposal)
self.discretizer_[feature] = CFImdlp(algorithm=self.algorithm)
self.discretizer_[feature].fit(self.X_[:, feature], self.y_)
self.cut_points_[feature] = self.discretizer_[
feature
@@ -136,7 +135,10 @@ class FImdlp(TransformerMixin, BaseEstimator):
raise ValueError(
"Shape of input is different from what was seen in `fit`"
)
result = np.zeros_like(X, dtype=np.int32) - 1
if len(self.features_) == self.n_features_:
result = np.zeros_like(X, dtype=np.int32) - 1
else:
result = np.zeros_like(X) - 1
Parallel(n_jobs=self.n_jobs, prefer="threads")(
delayed(self._discretize_feature)(feature, X[:, feature], result)
for feature in range(self.n_features_)

View File

@@ -14,47 +14,41 @@ class FImdlpTest(unittest.TestCase):
def test_init(self):
clf = FImdlp()
self.assertEqual(-1, clf.n_jobs)
self.assertEqual(0, clf.proposal)
clf = FImdlp(proposal=1, n_jobs=7)
self.assertEqual(1, clf.proposal)
self.assertEqual(0, clf.algorithm)
clf = FImdlp(algorithm=1, n_jobs=7)
self.assertEqual(1, clf.algorithm)
self.assertEqual(7, clf.n_jobs)
def test_fit_proposal(self):
clf = FImdlp(proposal=1)
def test_fit_definitive(self):
clf = FImdlp(algorithm=0)
clf.fit([[1, 2], [3, 4]], [1, 2])
self.assertEqual(clf.n_features_, 2)
self.assertListEqual(clf.X_.tolist(), [[1, 2], [3, 4]])
self.assertListEqual(clf.y_.tolist(), [1, 2])
self.assertListEqual([[], []], clf.get_cut_points())
self.assertListEqual([[2.0], [3.0]], clf.get_cut_points())
X, y = load_iris(return_X_y=True)
clf.fit(X, y)
self.assertEqual(clf.n_features_, 4)
self.assertTrue(np.array_equal(X, clf.X_))
self.assertTrue(np.array_equal(y, clf.y_))
expected = [
[
4.900000095367432,
5.0,
5.099999904632568,
5.400000095367432,
5.699999809265137,
],
[2.6999998092651367, 2.9000000953674316, 3.1999998092651367],
[2.3499999046325684, 4.5, 4.800000190734863],
[0.75, 1.399999976158142, 1.5, 1.7000000476837158],
[5.449999809265137, 6.25],
[2.8499999046325684, 3.0, 3.049999952316284, 3.3499999046325684],
[2.450000047683716, 4.75, 5.050000190734863],
[0.800000011920929, 1.4500000476837158, 1.75],
]
self.assertListEqual(expected, clf.get_cut_points())
self.assertListEqual([0, 1, 2, 3], clf.features_)
clf.fit(X, y, features=[0, 2, 3])
self.assertListEqual([0, 2, 3], clf.features_)
def test_fit_original(self):
clf = FImdlp(proposal=0)
def test_fit_alternative(self):
clf = FImdlp(algorithm=1)
clf.fit([[1, 2], [3, 4]], [1, 2])
self.assertEqual(clf.n_features_, 2)
self.assertListEqual(clf.X_.tolist(), [[1, 2], [3, 4]])
self.assertListEqual(clf.y_.tolist(), [1, 2])
self.assertListEqual([[], []], clf.get_cut_points())
self.assertListEqual([[2], [3]], clf.get_cut_points())
X, y = load_iris(return_X_y=True)
clf.fit(X, y)
self.assertEqual(clf.n_features_, 4)
@@ -62,10 +56,10 @@ class FImdlpTest(unittest.TestCase):
self.assertTrue(np.array_equal(y, clf.y_))
expected = [
[5.5, 5.800000190734863],
[2.9000000953674316, 3.3499999046325684],
[2.450000047683716, 4.800000190734863],
[0.800000011920929, 1.7999999523162842],
[5.449999809265137, 5.75],
[2.8499999046325684, 3.3499999046325684],
[2.450000047683716, 4.75],
[0.800000011920929, 1.75],
]
self.assertListEqual(expected, clf.get_cut_points())
self.assertListEqual([0, 1, 2, 3], clf.features_)
@@ -89,45 +83,58 @@ class FImdlpTest(unittest.TestCase):
def test_fit_features(self):
clf = FImdlp()
clf.fit([[1, 2], [3, 4]], [1, 2], features=[0])
res = clf.transform([[1, 2], [3, 4]])
self.assertListEqual(res.tolist(), [[0, 2], [0, 4]])
clf.fit([[1, -2], [3, 4]], [1, 2], features=[0])
res = clf.transform([[1, -2], [3, 4]])
self.assertListEqual(res.tolist(), [[0, -2], [1, 4]])
X, y = load_iris(return_X_y=True)
X_expected = X[:, [0, 2]].copy()
clf.fit(X, y, features=[1, 3])
X_computed = clf.transform(X)
self.assertListEqual(
X_expected[:, 0].tolist(), X_computed[:, 0].tolist()
)
self.assertListEqual(
X_expected[:, 1].tolist(), X_computed[:, 2].tolist()
)
self.assertEqual(X_computed.dtype, np.float64)
def test_transform_original(self):
clf = FImdlp(proposal=0)
def test_transform_definitive(self):
clf = FImdlp(algorithm=0)
clf.fit([[1, 2], [3, 4]], [1, 2])
self.assertEqual(
clf.transform([[1, 2], [3, 4]]).tolist(), [[0, 0], [0, 0]]
clf.transform([[1, 2], [3, 4]]).tolist(), [[0, 0], [1, 1]]
)
X, y = load_iris(return_X_y=True)
clf.fit(X, y)
self.assertEqual(clf.n_features_, 4)
self.assertTrue(np.array_equal(X, clf.X_))
self.assertTrue(np.array_equal(y, clf.y_))
X_transformed = clf.transform(X)
self.assertListEqual(
clf.transform(X).tolist(), clf.fit(X, y).transform(X).tolist()
X_transformed.tolist(), clf.fit(X, y).transform(X).tolist()
)
self.assertEqual(X_transformed.dtype, np.int32)
expected = [
[0, 0, 1, 1],
[2, 1, 1, 1],
[1, 0, 1, 1],
[1, 1, 1, 1],
[1, 0, 1, 1],
[0, 0, 1, 1],
[1, 0, 1, 1],
[1, 1, 1, 1],
[1, 0, 1, 1],
[1, 1, 1, 1],
]
self.assertTrue(np.array_equal(clf.transform(X[90:97]), expected))
with self.assertRaises(ValueError):
clf.transform([[1, 2, 3], [4, 5, 6]])
with self.assertRaises(sklearn.exceptions.NotFittedError):
clf = FImdlp(proposal=0)
clf = FImdlp(algorithm=0)
clf.transform([[1, 2], [3, 4]])
def test_transform_proposal(self):
clf = FImdlp(proposal=1)
def test_transform_alternative(self):
clf = FImdlp(algorithm=1)
clf.fit([[1, 2], [3, 4]], [1, 2])
self.assertEqual(
clf.transform([[1, 2], [3, 4]]).tolist(), [[0, 0], [0, 0]]
clf.transform([[1, 2], [3, 4]]).tolist(), [[0, 0], [1, 1]]
)
X, y = load_iris(return_X_y=True)
clf.fit(X, y)
@@ -138,17 +145,17 @@ class FImdlpTest(unittest.TestCase):
clf.transform(X).tolist(), clf.fit(X, y).transform(X).tolist()
)
expected = [
[4, 0, 1, 1],
[5, 2, 2, 2],
[5, 0, 1, 1],
[1, 0, 1, 1],
[4, 1, 1, 1],
[5, 2, 1, 1],
[5, 1, 1, 1],
[2, 1, 1, 1],
[2, 0, 1, 1],
[0, 0, 1, 1],
[1, 0, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
]
self.assertTrue(np.array_equal(clf.transform(X[90:97]), expected))
with self.assertRaises(ValueError):
clf.transform([[1, 2, 3], [4, 5, 6]])
with self.assertRaises(sklearn.exceptions.NotFittedError):
clf = FImdlp(proposal=1)
clf = FImdlp(algorithm=1)
clf.transform([[1, 2], [3, 4]])