ex-fuzzy 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ex_fuzzy-1.0.0/PKG-INFO +77 -0
- ex_fuzzy-1.0.0/README.md +57 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/__init__.py +10 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/centroid.py +192 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/classifiers.py +209 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/cognitive_maps.py +217 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/eval_rules.py +397 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/eval_tools.py +67 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/evolutionary_fit.py +913 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/fuzzy_sets.py +442 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/maintenance.py +161 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/persistence.py +88 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/rule_mining.py +247 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/rules.py +1083 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/temporal.py +682 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/utils.py +539 -0
- ex_fuzzy-1.0.0/ex_fuzzy/ex_fuzzy/vis_rules.py +404 -0
- ex_fuzzy-1.0.0/ex_fuzzy.egg-info/PKG-INFO +77 -0
- ex_fuzzy-1.0.0/ex_fuzzy.egg-info/SOURCES.txt +22 -0
- ex_fuzzy-1.0.0/ex_fuzzy.egg-info/dependency_links.txt +1 -0
- ex_fuzzy-1.0.0/ex_fuzzy.egg-info/requires.txt +6 -0
- ex_fuzzy-1.0.0/ex_fuzzy.egg-info/top_level.txt +1 -0
- ex_fuzzy-1.0.0/setup.cfg +4 -0
- ex_fuzzy-1.0.0/setup.py +51 -0
ex_fuzzy-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: ex_fuzzy
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Library to perform explainable AI using fuzzy logic.
|
|
5
|
+
Home-page:
|
|
6
|
+
Download-URL:
|
|
7
|
+
Maintainer: Javier Fumanal Idocin
|
|
8
|
+
Maintainer-email: javierfumanalidocin@gmail.com
|
|
9
|
+
License: GPL-3.0
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# Ex-Fuzzy
|
|
22
|
+
ex-Fuzzy is a fuzzy toolbox library for Python with special focus in its accesibility to use and visualization of results. In this way, we focus on the ex(-Fuzzy)plainable capacities of approximate reasoning.
|
|
23
|
+
|
|
24
|
+
Some of the tools available in this library include:
|
|
25
|
+
|
|
26
|
+
- Support for approximate reasoning using fuzzy association rules, for both classification and regression problems. This includes rule base optimization using genetic algorithms and rule visualization.
|
|
27
|
+
- Precomputed and optimized fuzzy variables and their correspondent linguistic variables (i.e low, medium, high).
|
|
28
|
+
- Support for various kinds of fuzzy sets, including classic fuzzy sets, IV-fuzzy sets and General Type 2 fuzzy sets.
|
|
29
|
+
|
|
30
|
+
## Main Characteristics
|
|
31
|
+
|
|
32
|
+
### Easy to use
|
|
33
|
+
|
|
34
|
+
ex-Fuzzy is designed to be easy to use. Linguistic variables can be precomputed and optimized without any understading of its implementation. Choosing one kind of fuzzy set only requires to set one flag.
|
|
35
|
+
|
|
36
|
+
### Reusable code
|
|
37
|
+
|
|
38
|
+
Code is designed so that some parts can be easily extendable, so that some use cases, like research, can be also supported. The rule base optimization is done using a Genetic Algorithm, but almost any other pymoo search algorithm will do. Fuzzy sets can be extended with ease, just as the kind of partitions, membership functions, etc.
|
|
39
|
+
|
|
40
|
+
### Sci-py like interface
|
|
41
|
+
|
|
42
|
+
ex-Fuzzy is built taking into account the actual machine-learing frameworks used in Python. Training amd sing a rule base classifier works exactly as sci-kit learn classifier. Parameters such as the number of rules or antecedents are also built
|
|
43
|
+
|
|
44
|
+
### Visualization
|
|
45
|
+
|
|
46
|
+
Use plots to visualize any kind of fuzzy sets, and use graphs to visualize rules or print them on screen.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
<p align="center">
|
|
50
|
+
<img src="https://user-images.githubusercontent.com/12574757/210235257-17b22ede-762b-406c-880a-497e06964f17.png" width="350" title="Fuzzy graph">
|
|
51
|
+
<img src="https://user-images.githubusercontent.com/12574757/210235264-be98fff9-d1b6-4f3b-8b93-b11e0466a48c.png" width="350" title="Type 1 example">
|
|
52
|
+
<img src="https://github.com/Fuminides/exFuzzy/assets/12574757/b37e2f4e-0e19-4d4b-a504-b121e41c9399" width="350" title="Type 2 example">
|
|
53
|
+
<img src="https://github.com/Fuminides/exFuzzy/assets/12574757/8e3c036f-2ab7-4281-8ef8-b8891fbf354a" width="350" title="General Type 2 example">
|
|
54
|
+
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
## Dependencies
|
|
58
|
+
|
|
59
|
+
- Numpy
|
|
60
|
+
- Pandas
|
|
61
|
+
- Matplotlib
|
|
62
|
+
- Networkx
|
|
63
|
+
- Pymoo
|
|
64
|
+
|
|
65
|
+
## Installation
|
|
66
|
+
|
|
67
|
+
You can install ex-Fuzzy using pip, from the PyPi repository, with the following command:
|
|
68
|
+
|
|
69
|
+
`pip install ex-fuzzy`
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
## Contributors
|
|
73
|
+
Javier Fumanal Idocin, Javier Andreu-Perez
|
|
74
|
+
|
|
75
|
+
All rights reserved, 2021-2024
|
|
76
|
+
|
|
77
|
+
|
ex_fuzzy-1.0.0/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Ex-Fuzzy
|
|
2
|
+
ex-Fuzzy is a fuzzy toolbox library for Python with special focus in its accesibility to use and visualization of results. In this way, we focus on the ex(-Fuzzy)plainable capacities of approximate reasoning.
|
|
3
|
+
|
|
4
|
+
Some of the tools available in this library include:
|
|
5
|
+
|
|
6
|
+
- Support for approximate reasoning using fuzzy association rules, for both classification and regression problems. This includes rule base optimization using genetic algorithms and rule visualization.
|
|
7
|
+
- Precomputed and optimized fuzzy variables and their correspondent linguistic variables (i.e low, medium, high).
|
|
8
|
+
- Support for various kinds of fuzzy sets, including classic fuzzy sets, IV-fuzzy sets and General Type 2 fuzzy sets.
|
|
9
|
+
|
|
10
|
+
## Main Characteristics
|
|
11
|
+
|
|
12
|
+
### Easy to use
|
|
13
|
+
|
|
14
|
+
ex-Fuzzy is designed to be easy to use. Linguistic variables can be precomputed and optimized without any understading of its implementation. Choosing one kind of fuzzy set only requires to set one flag.
|
|
15
|
+
|
|
16
|
+
### Reusable code
|
|
17
|
+
|
|
18
|
+
Code is designed so that some parts can be easily extendable, so that some use cases, like research, can be also supported. The rule base optimization is done using a Genetic Algorithm, but almost any other pymoo search algorithm will do. Fuzzy sets can be extended with ease, just as the kind of partitions, membership functions, etc.
|
|
19
|
+
|
|
20
|
+
### Sci-py like interface
|
|
21
|
+
|
|
22
|
+
ex-Fuzzy is built taking into account the actual machine-learing frameworks used in Python. Training amd sing a rule base classifier works exactly as sci-kit learn classifier. Parameters such as the number of rules or antecedents are also built
|
|
23
|
+
|
|
24
|
+
### Visualization
|
|
25
|
+
|
|
26
|
+
Use plots to visualize any kind of fuzzy sets, and use graphs to visualize rules or print them on screen.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="https://user-images.githubusercontent.com/12574757/210235257-17b22ede-762b-406c-880a-497e06964f17.png" width="350" title="Fuzzy graph">
|
|
31
|
+
<img src="https://user-images.githubusercontent.com/12574757/210235264-be98fff9-d1b6-4f3b-8b93-b11e0466a48c.png" width="350" title="Type 1 example">
|
|
32
|
+
<img src="https://github.com/Fuminides/exFuzzy/assets/12574757/b37e2f4e-0e19-4d4b-a504-b121e41c9399" width="350" title="Type 2 example">
|
|
33
|
+
<img src="https://github.com/Fuminides/exFuzzy/assets/12574757/8e3c036f-2ab7-4281-8ef8-b8891fbf354a" width="350" title="General Type 2 example">
|
|
34
|
+
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
## Dependencies
|
|
38
|
+
|
|
39
|
+
- Numpy
|
|
40
|
+
- Pandas
|
|
41
|
+
- Matplotlib
|
|
42
|
+
- Networkx
|
|
43
|
+
- Pymoo
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
You can install ex-Fuzzy using pip, from the PyPi repository, with the following command:
|
|
48
|
+
|
|
49
|
+
`pip install ex-fuzzy`
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Contributors
|
|
53
|
+
Javier Fumanal Idocin, Javier Andreu-Perez
|
|
54
|
+
|
|
55
|
+
All rights reserved, 2021-2024
|
|
56
|
+
|
|
57
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from . import centroid
|
|
2
|
+
from . import eval_rules
|
|
3
|
+
from . import eval_tools
|
|
4
|
+
from . import evolutionary_fit
|
|
5
|
+
from . import fuzzy_sets
|
|
6
|
+
from . import rules
|
|
7
|
+
from . import vis_rules
|
|
8
|
+
from . import utils
|
|
9
|
+
from . import persistence
|
|
10
|
+
from . import maintenance
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
This is the source file that contains functions to compute centroids for the case of IV fuzzy sets,
|
|
4
|
+
which are commonly used when using the IV-T2 fuzzy sets.
|
|
5
|
+
"""
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def center_of_masses(z: np.array, w: np.array) -> np.array:
|
|
10
|
+
'''
|
|
11
|
+
Computes the ponderated centroid with normalized weighting.
|
|
12
|
+
|
|
13
|
+
:param z: Vector of the referencial values.
|
|
14
|
+
:param w: Vector of the fuzzy memberships.
|
|
15
|
+
:return: The ponderated sum.
|
|
16
|
+
'''
|
|
17
|
+
return z @ w / np.sum(w)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def compute_centroid_t2_l(z: np.array, memberships: np.array) -> float:
|
|
21
|
+
'''
|
|
22
|
+
Computes the Karnik and Mendel algorithm to find the centroid of an IV fuzzy set.
|
|
23
|
+
|
|
24
|
+
:param z: Vector of the referencial values.
|
|
25
|
+
:param memberships: vector of the fuzzy memberships.
|
|
26
|
+
:return: The centroid.
|
|
27
|
+
'''
|
|
28
|
+
centros = np.mean(memberships, axis=1)
|
|
29
|
+
w = centros
|
|
30
|
+
|
|
31
|
+
yhat = center_of_masses(z, w)
|
|
32
|
+
|
|
33
|
+
yhat_2 = None
|
|
34
|
+
|
|
35
|
+
while(yhat != yhat_2):
|
|
36
|
+
try:
|
|
37
|
+
k = np.argwhere((z - yhat) >= 0)[-1][0]
|
|
38
|
+
k = min(len(centros)-1, k)
|
|
39
|
+
except IndexError:
|
|
40
|
+
k = 0
|
|
41
|
+
|
|
42
|
+
# k_vector = np.argwhere((z - yhat) > 0)
|
|
43
|
+
# k = k_vector[0][0] + 1
|
|
44
|
+
w[0:k] = memberships[:, 1][:k]
|
|
45
|
+
w[k:] = memberships[:, 0][k:]
|
|
46
|
+
|
|
47
|
+
yhat_2 = yhat
|
|
48
|
+
yhat = center_of_masses(z, w)
|
|
49
|
+
|
|
50
|
+
return yhat
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def compute_centroid_t2_r(z: np.array, memberships: np.array) -> float:
|
|
54
|
+
'''
|
|
55
|
+
Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set.
|
|
56
|
+
|
|
57
|
+
:param z: Vector of the referencial values.
|
|
58
|
+
:param memberships: vector of the fuzzy memberships.
|
|
59
|
+
:return: The lowest membership of the centroid.
|
|
60
|
+
'''
|
|
61
|
+
centros = np.mean(memberships, axis=1)
|
|
62
|
+
w = centros
|
|
63
|
+
|
|
64
|
+
yhat = center_of_masses(z, w)
|
|
65
|
+
|
|
66
|
+
yhat_2 = None
|
|
67
|
+
|
|
68
|
+
while(yhat != yhat_2):
|
|
69
|
+
try:
|
|
70
|
+
k = np.argwhere((z - yhat) >= 0)[-1][0]
|
|
71
|
+
k = min(len(centros)-1, k)
|
|
72
|
+
except IndexError:
|
|
73
|
+
k = 0
|
|
74
|
+
|
|
75
|
+
w[0:k+1] = memberships[:, 0][:k+1]
|
|
76
|
+
w[k+1:] = memberships[:, 1][k+1:]
|
|
77
|
+
|
|
78
|
+
yhat_2 = yhat
|
|
79
|
+
yhat = center_of_masses(z, w)
|
|
80
|
+
|
|
81
|
+
return yhat
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def consequent_centroid_r(antecedent_memberships: np.array, centroids_r: np.array) -> float:
|
|
85
|
+
'''
|
|
86
|
+
Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set
|
|
87
|
+
using the centroids of the consequents and the antecedents memeberships.
|
|
88
|
+
|
|
89
|
+
:param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships.
|
|
90
|
+
:param centroids_r: M sized vector. Contains the referencial values.
|
|
91
|
+
:return: the IV centroid.
|
|
92
|
+
'''
|
|
93
|
+
|
|
94
|
+
memberships_left = antecedent_memberships[:, 0]
|
|
95
|
+
memberships_right = antecedent_memberships[:, 1]
|
|
96
|
+
initial_f = (memberships_left + memberships_right) / 2
|
|
97
|
+
|
|
98
|
+
yhat = center_of_masses(centroids_r, initial_f)
|
|
99
|
+
yhat2 = None
|
|
100
|
+
|
|
101
|
+
while(yhat != yhat2):
|
|
102
|
+
try:
|
|
103
|
+
r_R = np.argwhere((yhat - centroids_r) >= 0)[-1][0]
|
|
104
|
+
r_R = min(len(centroids_r)-1, r_R)
|
|
105
|
+
except IndexError:
|
|
106
|
+
r_R = 0
|
|
107
|
+
|
|
108
|
+
new_memberships = initial_f
|
|
109
|
+
new_memberships[0:r_R+1] = memberships_left[0:r_R+1]
|
|
110
|
+
new_memberships[r_R+1:] = memberships_right[r_R+1:]
|
|
111
|
+
|
|
112
|
+
yhat2 = yhat
|
|
113
|
+
if np.sum(new_memberships) == 0:
|
|
114
|
+
yhat = 0
|
|
115
|
+
else:
|
|
116
|
+
yhat = center_of_masses(centroids_r, new_memberships)
|
|
117
|
+
|
|
118
|
+
return yhat2
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def consequent_centroid_l(antecedent_memberships: np.array, centroids_l: np.array) -> float:
|
|
122
|
+
'''
|
|
123
|
+
Computes the Karnik and Mendel algorithm to find the left component of a centroid of an IV fuzzy set
|
|
124
|
+
using the centroids of the consequents and the antecedents memeberships.
|
|
125
|
+
|
|
126
|
+
:param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships.
|
|
127
|
+
:param centroids_r: M sized vector. Contains the referencial values.
|
|
128
|
+
:return: the IV centroid.
|
|
129
|
+
'''
|
|
130
|
+
|
|
131
|
+
memberships_left = antecedent_memberships[:, 0]
|
|
132
|
+
memberships_right = antecedent_memberships[:, 1]
|
|
133
|
+
initial_f = (memberships_left + memberships_right) / 2
|
|
134
|
+
|
|
135
|
+
# (memberships_right * centroids_r) / np.sum(memberships_right)
|
|
136
|
+
yhat = center_of_masses(centroids_l, initial_f)
|
|
137
|
+
yhat2 = -100
|
|
138
|
+
|
|
139
|
+
#R = np.where(yhat - centroids_r)[0]
|
|
140
|
+
while(yhat != yhat2):
|
|
141
|
+
try:
|
|
142
|
+
r_R = np.argwhere((yhat - centroids_l) >= 0)[-1][0]
|
|
143
|
+
r_R = min(len(centroids_l)-1, r_R)
|
|
144
|
+
except IndexError:
|
|
145
|
+
r_R = 0
|
|
146
|
+
|
|
147
|
+
new_memberships = initial_f
|
|
148
|
+
new_memberships[0:r_R+1] = memberships_right[0:r_R+1]
|
|
149
|
+
new_memberships[r_R+1:] = memberships_left[r_R+1:]
|
|
150
|
+
yhat2 = yhat
|
|
151
|
+
if np.sum(new_memberships) == 0:
|
|
152
|
+
yhat = 0
|
|
153
|
+
else:
|
|
154
|
+
yhat = center_of_masses(centroids_l, new_memberships)
|
|
155
|
+
|
|
156
|
+
return yhat2
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def compute_centroid_iv(z: np.array, memberships: np.array) -> np.array:
|
|
160
|
+
'''
|
|
161
|
+
Computes Karnik and Mendel algorithm to find the centroid of a iv fuzzy set.
|
|
162
|
+
|
|
163
|
+
:param z: Vector of the referencial values.
|
|
164
|
+
:param memberships: vector of the fuzzy memberships.
|
|
165
|
+
:return: The centroid.
|
|
166
|
+
'''
|
|
167
|
+
res = np.zeros((2,))
|
|
168
|
+
res[0] = compute_centroid_t2_l(z, memberships)
|
|
169
|
+
res[1] = compute_centroid_t2_r(z, memberships)
|
|
170
|
+
return res
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def consequent_centroid(antecedent_memberships: np.array, centroids: np.array) -> np.array:
|
|
174
|
+
'''
|
|
175
|
+
Computes Karnik and Mendel algorithm to find the centroid of a consequent iv fuzzy set given the centroids of the consequents
|
|
176
|
+
and the antecedents memberships.
|
|
177
|
+
|
|
178
|
+
:param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships.
|
|
179
|
+
:param centroids: M x 2 matrix. M rules and iv dimension (2). Vector of centroids.
|
|
180
|
+
:return: The centroid.
|
|
181
|
+
'''
|
|
182
|
+
centroids_l = centroids[:, 0]
|
|
183
|
+
centroids_r = centroids[:, 1]
|
|
184
|
+
res = np.zeros((2,))
|
|
185
|
+
|
|
186
|
+
res[0] = consequent_centroid_l(antecedent_memberships, centroids_l)
|
|
187
|
+
res[1] = consequent_centroid_r(antecedent_memberships, centroids_r)
|
|
188
|
+
|
|
189
|
+
return res
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Module that contains classifiers that uses two step genetic optimization and rule mining based on the support of the candidate rules.
|
|
3
|
+
|
|
4
|
+
'''
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
from sklearn.base import ClassifierMixin
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
from . import fuzzy_sets as fs
|
|
11
|
+
from . import evolutionary_fit as evf
|
|
12
|
+
from . import rule_mining as rm
|
|
13
|
+
from . import utils
|
|
14
|
+
from . import maintenance as mnt
|
|
15
|
+
except:
|
|
16
|
+
import fuzzy_sets as fs
|
|
17
|
+
import evolutionary_fit as evf
|
|
18
|
+
import rule_mining as rm
|
|
19
|
+
import utils
|
|
20
|
+
import maintenance as mnt
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class RuleMineClassifier(ClassifierMixin):
|
|
24
|
+
"""A classifier that works by mining a set of candidate rules with a minimum support, confidence and lift, and then using a genetic algorithm that chooses
|
|
25
|
+
the optimal combination of those rules."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0,
|
|
28
|
+
verbose=False, n_class: int=None, runner: int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None:
|
|
29
|
+
'''
|
|
30
|
+
Inits the optimizer with the corresponding parameters.
|
|
31
|
+
|
|
32
|
+
:param nRules: number of rules to optimize.
|
|
33
|
+
:param nAnts: max number of antecedents to use.
|
|
34
|
+
:param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used.
|
|
35
|
+
:param tolerance: tolerance for the support/dominance score of the rules.
|
|
36
|
+
:param verbose: if True, prints the progress of the optimization.
|
|
37
|
+
:param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically.
|
|
38
|
+
:param runner: number of threads to use.
|
|
39
|
+
:param linguistic_variables: linguistic variables per antecedent.
|
|
40
|
+
'''
|
|
41
|
+
if mnt.save_usage_flag:
|
|
42
|
+
mnt.usage_data[mnt.usage_categories.Classification]['data_mining'] += 1
|
|
43
|
+
|
|
44
|
+
self.nAnts = nAnts
|
|
45
|
+
self.fl_classifier = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables,
|
|
46
|
+
fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class)
|
|
47
|
+
self.fuzzy_type = fuzzy_type
|
|
48
|
+
self.tolerance = tolerance
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50):
|
|
52
|
+
'''
|
|
53
|
+
Trains the model with the given data.
|
|
54
|
+
|
|
55
|
+
:param X: samples to train.
|
|
56
|
+
:param y: labels for each sample.
|
|
57
|
+
'''
|
|
58
|
+
fuzzy_vars = utils.construct_partitions(X, self.fuzzy_type)
|
|
59
|
+
candidate_rules = rm.multiclass_mine_rulebase(X, y, fuzzy_vars, self.tolerance, max_depth=self.nAnts)
|
|
60
|
+
self.fl_classifier.fit(X, y, checkpoints=0, candidate_rules=candidate_rules, n_gen=n_gen, pop_size=pop_size)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def predict(self, X: np.array) -> np.array:
|
|
64
|
+
'''
|
|
65
|
+
Predict for each sample the corresponding class.
|
|
66
|
+
|
|
67
|
+
:param X: samples to predict.
|
|
68
|
+
:return: a class for each sample.
|
|
69
|
+
'''
|
|
70
|
+
# Make predictions using the fitted model
|
|
71
|
+
y_pred = self.fl_classifier.predict(X)
|
|
72
|
+
|
|
73
|
+
return y_pred
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier:
|
|
77
|
+
# Returns the classifier that performs the final predictions
|
|
78
|
+
return self.fl_classifier
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class FuzzyRulesClassifier(ClassifierMixin):
|
|
83
|
+
"""A classifier that works by performing a double optimization process. First, it creates a candidate rule base using genetic optimization
|
|
84
|
+
and then uses it as a basis to obtain a better one that satisfies the constrain of antecedents and number of rules."""
|
|
85
|
+
|
|
86
|
+
def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0,
|
|
87
|
+
verbose=False, n_class: int=None, runner: int=1, expansion_factor:int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None:
|
|
88
|
+
'''
|
|
89
|
+
Inits the optimizer with the corresponding parameters.
|
|
90
|
+
|
|
91
|
+
:param nRules: number of rules to optimize.
|
|
92
|
+
:param nAnts: max number of antecedents to use.
|
|
93
|
+
:param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used.
|
|
94
|
+
:param tolerance: tolerance for the dominance score of the rules.
|
|
95
|
+
:param verbose: if True, prints the progress of the optimization.
|
|
96
|
+
:param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically.
|
|
97
|
+
:param runner: number of threads to use.
|
|
98
|
+
:param expansion_factor: if > 1, it will compute inthe first optimization process n times the nRules parameters. (So that the search space for the second step is bigger)
|
|
99
|
+
:param linguistic_variables: linguistic variables per antecedent.
|
|
100
|
+
'''
|
|
101
|
+
if mnt.save_usage_flag:
|
|
102
|
+
mnt.usage_data[mnt.usage_categories.Classification]['double_go'] += 1
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
self.fl_classifier1 = evf.BaseFuzzyRulesClassifier(nRules=nRules* 1, linguistic_variables=linguistic_variables, nAnts=nAnts, # We give this one more number rules so that then the second optimization has a bigger search space
|
|
106
|
+
fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class)
|
|
107
|
+
self.fl_classifier2 = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables, nAnts=nAnts,
|
|
108
|
+
fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class)
|
|
109
|
+
self.fuzzy_type = fuzzy_type
|
|
110
|
+
self.tolerance = tolerance
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50, checkpoints:int=0, n_runner:int=1):
|
|
114
|
+
'''
|
|
115
|
+
Trains the model with the given data.
|
|
116
|
+
|
|
117
|
+
:param X: samples to train.
|
|
118
|
+
:param y: labels for each sample.
|
|
119
|
+
:param n_gen: number of generations to compute in the genetic optimization.
|
|
120
|
+
:param pop_size: number of subjects per generation.
|
|
121
|
+
:param checkpoints: if bigger than 0, will save the best subject per x generations in a text file.
|
|
122
|
+
:param n_runner: number of threds to use.
|
|
123
|
+
'''
|
|
124
|
+
self.fl_classifier1.fit(X, y, n_gen, pop_size, checkpoints)
|
|
125
|
+
self.phase1_rules = self.fl_classifier1.rule_base
|
|
126
|
+
self.fl_classifier2.fit(X, y, n_gen, pop_size, checkpoints, initial_rules=self.phase1_rules, n_runner=n_runner)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def predict(self, X: np.array) -> np.array:
|
|
130
|
+
'''
|
|
131
|
+
Predcit for each sample the correspondent class.
|
|
132
|
+
|
|
133
|
+
:param X: samples to predict.
|
|
134
|
+
:return: a class for each sample.
|
|
135
|
+
'''
|
|
136
|
+
# Make predictions using the fitted model
|
|
137
|
+
y_pred = self.fl_classifier2.predict(X)
|
|
138
|
+
|
|
139
|
+
return y_pred
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier:
|
|
143
|
+
# Returns the classifier that performs the final predictions
|
|
144
|
+
return self.fl_classifier2
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class RuleFineTuneClassifier(ClassifierMixin):
|
|
148
|
+
"""A classifier that works by mining a set of candidate rules with a minimum support and then uses a two step genetic optimization that chooses
|
|
149
|
+
the optimal combination of those rules and fine tunes them."""
|
|
150
|
+
|
|
151
|
+
def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0,
|
|
152
|
+
verbose=False, n_class: int=None, runner: int=1, expansion_factor:int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None:
|
|
153
|
+
'''
|
|
154
|
+
Inits the optimizer with the corresponding parameters.
|
|
155
|
+
|
|
156
|
+
:param nRules: number of rules to optimize.
|
|
157
|
+
:param nAnts: max number of antecedents to use.
|
|
158
|
+
:param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used.
|
|
159
|
+
:param tolerance: tolerance for the dominance score of the rules.
|
|
160
|
+
:param verbose: if True, prints the progress of the optimization.
|
|
161
|
+
:param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically.
|
|
162
|
+
:param linguistic_variables: linguistic variables per antecedent.
|
|
163
|
+
'''
|
|
164
|
+
if mnt.save_usage_flag:
|
|
165
|
+
mnt.usage_data[mnt.usage_categories.Classification]['double_go'] += 1
|
|
166
|
+
mnt.usage_data[mnt.usage_categories.Classification]['data_mining'] += 1
|
|
167
|
+
|
|
168
|
+
self.fl_classifier1 = evf.BaseFuzzyRulesClassifier(nRules=nRules* expansion_factor, linguistic_variables=linguistic_variables, nAnts=nAnts, # We give this one more number rules so that then the second optimization has a bigger search space
|
|
169
|
+
fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class)
|
|
170
|
+
self.fl_classifier2 = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables, nAnts=nAnts,
|
|
171
|
+
fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class)
|
|
172
|
+
self.fuzzy_type = fuzzy_type
|
|
173
|
+
self.tolerance = tolerance
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50, checkpoints:int=0, n_runner:int=1):
|
|
177
|
+
'''
|
|
178
|
+
Trains the model with the given data.
|
|
179
|
+
|
|
180
|
+
:param X: samples to train.
|
|
181
|
+
:param y: labels for each sample.
|
|
182
|
+
:param n_gen: number of generations to compute in the genetic optimization.
|
|
183
|
+
:param pop_size: number of subjects per generation.
|
|
184
|
+
:param checkpoints: if bigger than 0, will save the best subject per x generations in a text file.
|
|
185
|
+
:param n_runner: number of threds to use.
|
|
186
|
+
'''
|
|
187
|
+
candidate_rules = rm.multiclass_mine_rulebase(X, y, self.fl_classifier1.lvs, self.tolerance)
|
|
188
|
+
|
|
189
|
+
self.fl_classifier1.fit(X, y, n_gen, pop_size, checkpoints, candidate_rules=candidate_rules)
|
|
190
|
+
self.phase1_rules = self.fl_classifier1.rule_base
|
|
191
|
+
self.fl_classifier2.fit(X, y, n_gen, pop_size, checkpoints, initial_rules=self.phase1_rules, n_runner=n_runner)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def predict(self, X: np.array) -> np.array:
|
|
195
|
+
'''
|
|
196
|
+
Predcit for each sample the correspondent class.
|
|
197
|
+
|
|
198
|
+
:param X: samples to predict.
|
|
199
|
+
:return: a class for each sample.
|
|
200
|
+
'''
|
|
201
|
+
# Make predictions using the fitted model
|
|
202
|
+
y_pred = self.fl_classifier.predict(X)
|
|
203
|
+
|
|
204
|
+
return y_pred
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier:
|
|
208
|
+
# Returns the classifier that performs the final predictions
|
|
209
|
+
return self.fl_classifier2
|