This project is part of the @thi.ng/umbrella monorepo.
Fuzzy logic operators & configurable rule inferencing engine.
- Entirely declarative & functional approach
- Fuzzy set domain shaping & composition functions (incl. negated / inverse)
- Various T-norms & S-norms, incl. parametric versions
- Rules with multiple inputs/outputs and arbitrary term combinators (i.e.
T-norms). Syntax sugar for common
and
/or
rules. - Defuzzification via customizable strategies and options to balance precision
vs. performance
- Maxima: First, Last, Mean
- Center-of-Gravity (COG)
- Linguistic variable creation and term/set classification for given domain values
- Fuzzy Logic (Wikipedia)
- T-norm (Wikipedia)
- Fuzzy Logic - University of Western Australia
- Introduction to Fuzzy Logic
- Defuzzification (Wikipedia)
- Defuzzification methods
- Comparison of the COG Defuzzification Technique
ALPHA - bleeding edge / work-in-progress
Search or submit any issues for this package
yarn add @thi.ng/fuzzy
// ES module
<script type="module" src="https://unpkg.com/@thi.ng/fuzzy?module" crossorigin></script>
// UMD
<script src="https://unpkg.com/@thi.ng/fuzzy/lib/index.umd.js" crossorigin></script>
Package sizes (gzipped, pre-treeshake): ESM: 1.55 KB / CJS: 1.72 KB / UMD: 1.64 KB
Generators:
constant()
point()
ramp()
/invRamp()
triangle()
trapezoid()
sigmoid()
/invSigmoid()
gaussian()
Combinators:
negate()
weighted()
alphaCut()
/invAlphaCut()
implication()
compose()
// temperature sets (in celsius)
const temp = variable([-20, 40], {
freezing: invSigmoid(0, 2),
cold: trapezoid(0, 4, 16, 20),
warm: trapezoid(15, 20, 25, 30),
hot: sigmoid(30, 2)
});
evaluate(temp, 18)
// {
// freezing: 2.220446049250313e-16,
// cold: 0.5,
// warm: 0.6,
// hot: 3.7751345441365816e-11
// }
evaluate(temp, 28)
// {
// freezing: 0,
// cold: 0,
// warm: 0.4,
// hot: 0.01798620996209156
// }
// classify temperature (min confidence 33%, default: 50%)
classify(temp, 28, 0.33)
// "warm"
Example taken from Franck Dernoncourt's Introduction to Fuzzy Logic:
const food = variable([0, 10], {
awful: invRamp(1, 3),
delicious: ramp(7, 9),
});
const service = variable([0, 10], {
poor: gaussian(0, 1.5),
good: gaussian(5, 1.5),
excellent: gaussian(10, 1.5),
});
const tip = variable([0, 30], {
low: triangle(0, 5, 10),
medium: triangle(10, 15, 20),
high: triangle(20, 25, 30),
});
// if service is poor OR food is awful -> tip is low
// if service is normal -> tip is medium
// if service is excellent OR food is delicious -> tip is high
const rules = [
or({ food: "awful", service: "poor" }, { tip: "low" }),
or({ service: "good" }, { tip: "medium" }),
or({ food: "delicious", service: "excellent" }, { tip: "high" }),
];
// defuzzification using default center-of-gravity strategy
defuzz(
// input variables
{ food, service },
// output variables
{ tip },
// rules (see above)
rules,
// input values
{ food: 7.32, service: 7.83 },
);
// { tip: 22.650000000000034 }
// defuzz with custom strategy (note: each has further config options)
defuzz(
// input variables
{ food, service },
// output variables
{ tip },
// rules (see above)
rules,
// input values
{ food: 7.32, service: 7.83 },
// mean-on-maxima strategy
maximaStrategy({ mode: "mean" })
);
// { tip: 25.050000000000043 }
Note: The results are slightly different than those in the textbook example, due
to different gaussian
fuzzy sets used for the service
lvar.
Using the traceStrategy
from the upcoming
@thi.ng/fuzzy-utils
package, we can also visualize the fuzzy sets and highlight the position of the
crisp result value.
Here is the result for COG strategy and using tnormMin
(the default) to
transform each rule's output set(s):
...........................................................................|........................
...........................................................................|........................
...........................................................................|........................
...........................................................................|........................
...........................................................................|........................
...........................................................................|........................
...........................................................................|........................
...........................................................................|........................
...........................................................................|........................
...........................................................................|........................
........................................................................▁▅▅|▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅.....
.......................................................................▁███|███████████████████▇....
......................................................................▁████|████████████████████▇...
....................................▅▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▅....▂█████|█████████████████████▇..
...................................▅█████████████████████████████▅..▂██████|███████████████████████.
..................................▅███████████████████████████████▅▂███████|████████████████████████
^ 22.65
Different results can be obtained by adjusting the
T-norm used to transform each rule's
output sets, here using tnormHamacher(2)
.
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|.....................
..............................................................................|....▃▂...............
..............................................................................|..▃███▆▂.............
..............................................................................|▅███████▇▃...........
................................................▁▃▆▃▁......................▁▄▇|███████████▆▃........
...........................................▁▂▄▆███████▆▄▂▁..............▂▄▇███|██████████████▆▃▁....
...................................▁▂▃▄▅▆▇█████████████████▇▆▅▄▃▂▁..▂▄▆███████|██████████████████▅▃▁
^ 23.55
Karsten Schmidt
If this project contributes to an academic publication, please cite it as:
@misc{thing-fuzzy,
title = "@thi.ng/fuzzy",
author = "Karsten Schmidt",
note = "https://thi.ng/fuzzy",
year = 2020
}
© 2020 Karsten Schmidt // Apache Software License 2.0