Skip to content

Commit

Permalink
added tests for FuzzyInductor and linked to correct readthedocs site
Browse files Browse the repository at this point in the history
  • Loading branch information
dariomalchiodi committed Oct 19, 2024
1 parent 6e14e1f commit 53b61c8
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# mulearn

[![Documentation Status](https://readthedocs.org/projects/mulearn-mr/badge/?version=latest)](https://mulearn-mr.readthedocs.io/en/latest/?badge=latest)
[![Documentation Status](https://readthedocs.org/projects/mulearn/badge/?version=latest)](https://mulearn.readthedocs.io/en/latest/?badge=latest)

> A python package for inducing membership functions from labeled data
Expand Down
1 change: 1 addition & 0 deletions environment_rtd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies:
#- jupyter_client=6.1
#- jupyter_core=4.7
#- keras-preprocessing=1.1
- json_fix
- markdown=3.3
#- matplotlib=3.3
#- matplotlib-base=3.3
Expand Down
16 changes: 12 additions & 4 deletions mulearn/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '1.0.2'
__version__ = '1.0.3'


import copy
Expand Down Expand Up @@ -53,16 +53,25 @@ def __init__(self,
self.solver = solver
self.random_state = random_state
self.estimated_membership_ = None
self.x_to_sq_dist_ = None
self.chis_ = None
self.gram_ = None
self.fixed_term_ = None
self.train_error_ = None

def __repr__(self, **kwargs):
return f"FuzzyInductor(c={self.c}, k={self.k}, f={self.fuzzifier}, " \
f"solver={self.solver})"

def __eq__(self, other):
"""Check equality w.r.t. other objects."""
equal = (type(self) is type(other) and \
self.c == other.c and self.k == other.k and \
self.fuzzifier == other.fuzzifier)
if 'chis_' in self.__dict__:
if 'chis_' not in other.__dict__:
return False
else:
return equal and (self.chis_ == other.chis_)

def x_to_sq_dist(self, X_new):
X_new = np.array(X_new)
t1 = self.k.compute(X_new, X_new)
Expand Down Expand Up @@ -122,7 +131,6 @@ def fit(self, X, y, warm_start=False):

if len(chi_sq_radius) == 0:
self.estimated_membership_ = None
self.train_error_ = np.inf
self.chis_ = None
logger.warning('No support vectors found')
return self
Expand Down
2 changes: 1 addition & 1 deletion mulearn/fuzzifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def __str__(self):

def __eq__(self, other):
"""Check fuzzifier equality w.r.t. other objects."""
return type(self) == type(other)
return type(self) is type(other) and self.__dict__ == other.__dict__

def __ne__(self, other):
"""Check fuzzifier inequality w.r.t. other objects."""
Expand Down
8 changes: 6 additions & 2 deletions mulearn/kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __str__(self):

def __eq__(self, other):
"""Check kernel equality w.r.t. other objects."""
return type(self) == type(other)
return type(self) is type(other) and self.__dict__ == other.__dict__

def __ne__(self, other):
"""Check kernel inequality w.r.t. other objects."""
Expand Down Expand Up @@ -134,7 +134,11 @@ def compute(self, arg_1, arg_2):
"""
return (np.sum(np.array(arg_1) * np.array(arg_2),
axis=1) + 1) ** self.degree


def __eq__(self, other):
"""Check kernel equality w.r.t. other objects."""
return type(self) == type(other) and self.degree == other.degree

def __repr__(self):
"""Return the python representation of the kernel."""
return f"PolynomialKernel({self.degree})"
Expand Down
4 changes: 4 additions & 0 deletions mulearn/optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ def solve(self, xs, mus, c, k):
for ch, l, u in zip(chis, -c * (1 - mus), c * mus)] # noqa

return chis_opt

def __eq__(self, other):
"""Check solver equality w.r.t. other objects."""
return type(self) is type(other) and self.__dict__ == other.__dict__


class GurobiSolver(Solver):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ dynamic = ['version']

[project.urls]
Homepage = "https://github.com/dariomalchiodi/mulearn"
Documentation = "https://mulearn-mr.readthedocs.io/"
Documentation = "https://mulearn.readthedocs.io/"
Issues = "https://github.com/dariomalchiodi/mulearn/issues"

[tool.setuptools]
Expand Down
9 changes: 9 additions & 0 deletions tests/test_fuzzifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import numpy as np
import unittest

from sklearn.datasets import load_iris

from mulearn import FuzzyInductor
import mulearn.fuzzifier as fuzz

Expand Down Expand Up @@ -138,6 +140,13 @@ def test_compute(self):
for t, r in zip(target[t], result):
self.assertAlmostEqual(t, r)

class TestFuzzifierSerialization(unittest.TestCase):
def test_dump(self):
X, y = load_iris()

def test_serialization(self):
pass


if __name__ == '__main__':
unittest.main()
62 changes: 62 additions & 0 deletions tests/test_fuzzy_inductor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import logging
import os
import pickle
import unittest
import warnings

from sklearn.datasets import load_iris
import sklearn.metrics as metrics

from mulearn import FuzzyInductor
from mulearn.kernel import LinearKernel, PolynomialKernel, GaussianKernel
from mulearn.kernel import HomogeneousPolynomialKernel, HyperbolicKernel


class TestCrispFuzzifier(unittest.TestCase):
def setUp(self):
d = load_iris()
self.X = d['data']
y = d['target']
y[y==2] = 0
self.y = y

def test_serialization(self):
fi = FuzzyInductor()
fi.fit(self.X, self.y)
s = pickle.dumps(fi)
fi_clone = pickle.loads(s)

self.assertEqual(fi, fi_clone)

def test_persistence(self):
fi = FuzzyInductor()
fi.fit(self.X, self.y)

with open('object.pickle', 'wb') as f:
pickle.dump(fi, f)

with open('object.pickle', 'rb') as f:
fi_clone = pickle.load(f)

os.remove('object.pickle')

self.assertEqual(fi, fi_clone)

def test_fit(self):
kernel = [LinearKernel(), PolynomialKernel(2),
GaussianKernel(.1), HyperbolicKernel()]
scores = [0.3679416879198661, 0.3954864950288751,
3.858380026406454e-08, 0.5]
logging.disable(logging.WARNING)
with warnings.catch_warnings():
warnings.simplefilter("ignore", RuntimeWarning)
for k, s in zip(kernel, scores):
fi = FuzzyInductor(k=k)
fi.fit(self.X, self.y)
y_hat = fi.predict(self.X)
rmse = metrics.root_mean_squared_error(self.y, y_hat)
self.assertAlmostEqual(s, rmse)
logging.disable(logging.NOTSET)

if __name__ == '__main__':
unittest.main()

0 comments on commit 53b61c8

Please sign in to comment.