aresio / simpful Goto Github PK
View Code? Open in Web Editor NEWA friendly python library for fuzzy logic reasoning
License: Academic Free License v3.0
A friendly python library for fuzzy logic reasoning
License: Academic Free License v3.0
Hi
Could you please tell me where I can get fuzzy inputs membership values assigned at every run of Fuzzy inference to calculate Fuzzy score.
Thank you.
This package claims compatibility with Python 3.7. However, in simpful.py (since version 2.9.0), it imports prod from math, which was only introduced in Python 3.8.
Atm, if the sum of rules firing is 0, division by 0 is captured and just 0 is returned. This behaviour is expected and doesn't lead to any error. However, everytime this event occurs, a warning is printed see here.
Especially for systems designed to lead to 0 values in specific cases, this can produce a large output. It is desired that this warning could be surpressed by a specific setting or maybe even with the "verbose" parameter.
error:
============================= test session starts ==============================
platform linux -- Python 3.11.5, pytest-7.4.2, pluggy-1.2.0
rootdir: /build/source
collected 7 items
tests/test_examples.py .....F [ 85%]
tests/test_rule_parsing.py . [100%]
=================================== FAILURES ===================================
_________________________________ test_sepsis __________________________________
def test_sepsis():
FS = sf.FuzzySystem(show_banner=False)
# Define fuzzy sets for the variable PaO2
P1 = sf.FuzzySet(function=sf.Sigmoid_MF(c=40, a=0.1), term="low")
P2 = sf.FuzzySet(function=sf.InvSigmoid_MF(c=40, a=0.1), term="high")
LV1 = sf.LinguisticVariable([P1,P2], concept="PaO2 level in blood", universe_of_discourse=[0,80])
FS.add_linguistic_variable("PaO2", LV1)
# Define fuzzy sets for the variable base excess
B1 = sf.FuzzySet(function=sf.Gaussian_MF(mu=0,sigma=1.25), term="normal")
LV2 = sf.LinguisticVariable([B1], concept="Base excess of the blood", universe_of_discourse=[-10,10])
FS.add_linguistic_variable("BaseExcess", LV2)
# Define fuzzy sets for the variable trombocytes
T1 = sf.FuzzySet(function=sf.Sigmoid_MF(c=50, a=0.75), term="low")
T2 = sf.FuzzySet(function=sf.InvSigmoid_MF(c=50, a=0.75), term="high")
LV3 = sf.LinguisticVariable([T1,T2], concept="Trombocytes in blood", universe_of_discourse=[0,100])
FS.add_linguistic_variable("Trombocytes", LV3)
# Define fuzzy sets for the variable creatinine
C1 = sf.FuzzySet(function=sf.Sigmoid_MF(c=300, a=0.2), term="low")
C2 = sf.FuzzySet(function=sf.InvSigmoid_MF(c=300, a=0.1), term="high")
LV4 = sf.LinguisticVariable([C1,C2], concept="Creatinine in blood", universe_of_discourse=[0,600])
FS.add_linguistic_variable("Creatinine", LV4)
# Plot all linguistic variables and save them in a output file
> FS.produce_figure(outputfile='lvs.pdf')
tests/test_examples.py:160:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
simpful/simpful.py:890: in produce_figure
v.draw(ax[c][r], element=element_dict[k])
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Linguistic variable 'PaO2 level in blood', contains fuzzy sets [<Fuzzy set (function), term='low'>, <Fuzzy set (function), term='high'>], universe of discourse: [0, 80]>
ax = <Axes: >, TGT = None, element = None, highlight = None, xscale = 'linear'
def draw(self, ax, TGT=None, element=None, highlight=None, xscale="linear"):
"""
This method returns a matplotlib ax, representing all fuzzy sets contained in the liguistic variable.
Args:
ax: the matplotlib axis to plot to.
TGT: (deprecated) show the memberships of a specific element of discourse TGT in the figure.
element: show the memberships of a specific element of discourse in the figure.
highlight: string, indicating the linguistic term/fuzzy set to highlight in the plot.
xscale: default "linear", supported scales "log". Changes the scale of the xaxis.
Returns:
A matplotlib axis, representing all fuzzy sets contained in the liguistic variable.
"""
if matplotlib == False:
raise Exception("ERROR: please, install matplotlib for plotting facilities")
if TGT is not None:
print("Warning: argument 'TGT' is deprecated and will be discontinued in future relseases. Please use 'element'")
element = TGT
mi, ma = self.get_universe_of_discourse()
if xscale == "linear":
x = linspace(mi, ma, 10000)
elif xscale == "log":
if mi < 0 and ma > 0:
x = geomspace(mi, -finfo(float64).eps, 5000) + geomspace(finfo(float64).eps, ma, 5000)
# raise Exception("ERROR: cannot plot in log scale with negative universe of discourse")
elif mi == 0:
x = geomspace(finfo(float64).eps, ma, 10000)
else:
x = geomspace(mi, ma, 10000)
else:
raise Exception("ERROR: scale "+xscale+" not supported.")
if highlight is None:
linestyles= ["-", "--", ":", "-."]
else:
linestyles= ["-"]*4
if element is not None:
ax.plot([element, element], [0.0, 1], color="red", linestyle="--", linewidth=2.0, label="Value")
for nn, fs in enumerate(self._FSlist):
# singleton
if isinstance(fs, SingletonsSet):
xs = [pair[0] for pair in fs._funpointer._pairs]
ys = [pair[1] for pair in fs._funpointer._pairs]
ax.vlines(x=xs, ymin=0.0, ymax=ys, linestyles=linestyles[nn%4], color=next(ax._get_lines.prop_cycler)['color'], label=fs._term)
elif fs._type == "function":
y = [fs.get_value(xx) for xx in x]
> color = next(ax._get_lines.prop_cycler)['color']
E AttributeError: '_process_plot_var_args' object has no attribute 'prop_cycler'
simpful/simpful.py:139: AttributeError
proposed patch:
diff --git a/simpful/simpful.py b/simpful/simpful.py
index 9fb653b..5a2f046 100644
--- a/simpful/simpful.py
+++ b/simpful/simpful.py
@@ -131,12 +131,12 @@ class LinguisticVariable(object):
if isinstance(fs, SingletonsSet):
xs = [pair[0] for pair in fs._funpointer._pairs]
ys = [pair[1] for pair in fs._funpointer._pairs]
- ax.vlines(x=xs, ymin=0.0, ymax=ys, linestyles=linestyles[nn%4], color=next(ax._get_lines.prop_cycler)['color'], label=fs._term)
-
+ ax.vlines(x=xs, ymin=0.0, ymax=ys, linestyles=linestyles[nn%4], color=ax._get_lines.get_next_color(), label=fs._term)
+
elif fs._type == "function":
y = [fs.get_value(xx) for xx in x]
- color = next(ax._get_lines.prop_cycler)['color']
+ color = ax._get_lines.get_next_color()
lw = 1
if highlight==fs._term:
I think it would be more appropriate to use LGPL license, or a more permissive one, since GPL prohibits any linking of non-GPL software to GPL software, thus forcing anyone that uses simpful to use a GPL license for their package (if they redistribute it). That's because importing a python packages seems to be considered "dynamic linking". As a result, adoption of simpful will be less likely.
"The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License." tl;drlegal (Full Text)
I am looking for guidance to apply simpful as intended. I prepared a minimalistic experiment (screenshot) and respective code (below). I used python 3.10.12 with simpful 2.11.0
I tried various things to tweak my example for the desired outcome, but so far failed. I assume it is working as expected, but I don't find the result intuitive or explainable. Any discussion/clarification is greatly appreciated.
Be Good
from simpful import * # version 2.11.0
FS = FuzzySystem(show_banner=False)
# Create First Input "Rating"
S_1 = TriangleFuzzySet(a=0, b=0, c=5, term="laggard")
S_2 = TriangleFuzzySet(a=0, b=5, c=10, term="average")
S_3 = TriangleFuzzySet(a=5, b=10, c=10, term="leader")
FS.add_linguistic_variable(
"Rating",
LinguisticVariable(
[
S_1,
S_2,
S_3,
],
concept="Rating",
universe_of_discourse=[0, 10],
),
)
# Create Second Input "Revenues"
R_1 = TrapezoidFuzzySet(a=0, b=0, c=1, d=5, term="miss")
R_2 = TrapezoidFuzzySet(a=1, b=5, c=15, d=30, term="minor")
R_3 = TrapezoidFuzzySet(a=15, b=30, c=50, d=80, term="major")
R_4 = TrapezoidFuzzySet(a=50, b=80, c=100, d=100, term="pure")
FS.add_linguistic_variable(
"Revenue",
LinguisticVariable(
[
R_1,
R_2,
R_3,
R_4,
],
concept="Revenue",
universe_of_discourse=[0, 100],
),
)
# Create Output
T_1 = TrapezoidFuzzySet(a=0, b=0, c=0, d=2.5, term="veryslim")
T_2 = TrapezoidFuzzySet(a=0, b=2.5, c=2.5, d=5, term="slim")
T_3 = TrapezoidFuzzySet(a=2.5, b=5, c=5, d=7.5, term="moderate")
T_4 = TrapezoidFuzzySet(a=5, b=7.5, c=7.5, d=10, term="strong")
T_5 = TrapezoidFuzzySet(a=7.5, b=10, c=10, d=10, term="verystrong")
FS.add_linguistic_variable(
"Result",
LinguisticVariable([T_1, T_2, T_3, T_4, T_5], universe_of_discourse=[0, 10]),
)
# Create Rules
FS.add_rules(
[
"IF (Rating IS leader) THEN (Result IS verystrong)",
#
"IF (Rating IS average) AND (Revenue IS pure) THEN (Result IS strong)",
"IF (Rating IS average) AND (Revenue IS major) THEN (Result IS moderate)",
"IF (Rating IS average) AND (Revenue IS minor) THEN (Result IS slim)",
"IF (Rating IS average) AND (Revenue IS miss) THEN (Result IS veryslim)",
#
"IF (Rating IS laggard) THEN (Result IS veryslim)",
]
)
for i in range(0,40,1):
FS.set_variable("Rating", 8)
FS.set_variable("Revenue", i)
print(f"For Rating frozen at 8. Revenue {i}: Result is: {FS.Mamdani_inference(['Result']).get('Result')}")
Please add a script to ./examples, which illustrates how to construct the rule strings properly when combining operators. Some examples, I would find helpful
For example, I noticed that this does not work:
"IF (NOT (service IS low)) AND (food IS high) THEN (tip IS high)"
while this does
"IF (food IS high) AND (NOT (service IS low)) THEN (tip IS high)"
Documentation would have helped. Thank you!
I saw some of your code snippets, a good rule of thumb is to refactor the code and eliminate the comments.
This way people do not need to read the comment when they are reading and optimizing your code.
I tried to plot your built in plotting tools but it does not work because it says matplotlib does not exist.
Here is my error code:
Traceback (most recent call last):
File "c:\Users\zaina\OneDrive\Skoleopgaver\Robotteknologi\Bachelorprojekt\Source code\pytello\test_Arucodetector.py", line 68, in setUp
self.drone_controller.SetFuzzySystem()
File "c:\Users\zaina\OneDrive\Skoleopgaver\Robotteknologi\Bachelorprojekt\Source code\pytello\Arucodetector.py", line 78, in SetFuzzySystem
self.SetInputs()
File "c:\Users\zaina\OneDrive\Skoleopgaver\Robotteknologi\Bachelorprojekt\Source code\pytello\Arucodetector.py", line 84, in SetInputs
self.controller.produce_figure(outputfile = "x.png")
File "C:\Users\zaina\anaconda3\lib\site-packages\simpful\simpful.py", line 722, in produce_figure
raise Exception("ERROR: please, install matplotlib for plotting facilities")
Exception: ERROR: please, install matplotlib for plotting facilities
I'm doing a digital twin with fuzzy logic. Anyways, sometimes I need to replace a rule for another that represents better the dynamic of the system. Is it possible to do this replacement without load all the rules every time I need to update the rules? It's different of just "append" the rules, I would need a way to replace a specific rule for another.
I thank you for the package, it's very simple to use and I already thank you for the attention!
Hi, is there a way to parse an utf-8, -16 and even -32 characters to the rule base?
such as greek letter θ, is it possible?
if not, when will it be implimented?
is there any way to Save The Fuzzy Rules in FCL format in a file ?
Would there be a way to define my custom fuzzy logic rules which use different format than “IS”. From what I was looking at the simpful code it only supports conditions as follow:
a “IS" b AND b "IS" c THEN a "IS” c
I need to define format as
a “SUBCLASS" b AND b “SUBCLASS" c THEN a “SUBCLASS" c.
Or
a “SUBCLASS" b AND x “TYPE" a THEN x “TYPE” b.
And more custom rules as in the attached picture.
But looking at the https://github.com/aresio/simpful/blob/master/simpful/rule_parsing.py (line 4,5) the only rule which can be parsed is only the “IS” condition.
The question is if there is a way to define these rules without significantly modifying the source code which I might be missing?
I recently read your paper.
It clearly explained the general idea of your Simpful library and how many features It easily provides.
But you did not compare the performance of your Simpful Fuzzy with other fuzzy control libraries.
Why?
Dear all,
I've declined an invitation to review your paper given my lack of knowledge in fuzzy logic. However, having looked at your repository, I may leave some comments here from a Python perspective that you may consider improving on. Given that the main advantage of your package comes from having a package, not just implementing a new algorithm, this aspects seem crucial. I'll noted below the aspects that I would improve on and they are of course subject to my personal and professional experience, which is limited and surely biased. I hope however, that this will help you and I do not want to discourage you from developing a package, but rather help you by providing a realistic and honest feedback. Depending on your scope, they may also aim too high.
from ... import *
imports! e.g. from math import *
. It is highly discouraged to use it.1.9) consider sticking to PEP-8 and general not to "bend" the python syntax. There are autoformatters for the code. For example, a print
is a function and does not have space before the (
. So it's print(...)
, and not print (...)
.
1.10) there are a few things that miss the proper implementation and that Python offers improved ways. Python code that should be changed:
Line 554 in 4515877
Line 103 in 4515877
exit
is almost never (and surely not here) the way to go.from the user perspective, there are a few things missing
2.1) the example has a from package import *
at the beginning. This is discouraged and should absolutely not be used (the *
) if not for special cases (e.g. config files). It can cause many bad issues. Also consider removing this from the __init__.py
2.2) there is no API documentation. How is a user supposed to know, which methods can be called, which arguments can be used? Consider setting up an auto api docs with sphinx and readthedocs
2.3) Is there something more about the project? e.g. people involved, long-term goals etc, the reason why this was built?
just an overall comment, maybe I miss out: why does it has to be capitalized strings that are added? It always seems a little antique to me. why not lowercase for example?
My overall impression of the package is that it looks more like a useful, private script that has been uploaded and slightly cleaned up. However, to provide a useful package (and "guarantee" support for the next few years -- be aware that as a user I don't want the package to work "just now" -- with the tools and work invested), there needs to be a whole lot more of things there, many which are lacking currently and can surely be improved on. This surely takes quite some works to accomplish but will reduce the workload in the future for maintenance. If this work is not provided, as a user, it will be highly assumed that the author will also not invest further work in case of possible bugs. Given that this package claims to be primarily a package to be used by people, not a novel algorithm, this points seem crucial to me.
My (personal) advice: writing a package is not sharing a private script. Be aware of the extra work required, that there is a whole science behind this (software engineering) and that it bears some 'responsibility', as people will rely on your work. Make sure you want to take this work! It's not always peaches and cream but roses and thorns.
I hope this comments can help you better orient and develop the package, they are written with the best intend.
I am getting the following error possibly due to use of AND in the rules.
Kindly help
Hi.
Thanks for the excellent repo and paper.
I want to plot the output surface like Fig.4 in the paper.
What kind of code should I add in the mamdani tip problem example to get the figure like Fig. 4. in the paper?
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.