fuzzytool 0.1.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.
- fuzzytool-0.1.0/.github/workflows/ci.yml +24 -0
- fuzzytool-0.1.0/.github/workflows/docs.yml +40 -0
- fuzzytool-0.1.0/.github/workflows/release-pypi.yml +23 -0
- fuzzytool-0.1.0/.gitignore +27 -0
- fuzzytool-0.1.0/.zenodo.json +24 -0
- fuzzytool-0.1.0/CHANGELOG.md +52 -0
- fuzzytool-0.1.0/CITATION.cff +18 -0
- fuzzytool-0.1.0/CLAUDE.md +82 -0
- fuzzytool-0.1.0/CONTRIBUTING.md +36 -0
- fuzzytool-0.1.0/LICENSE +21 -0
- fuzzytool-0.1.0/PKG-INFO +126 -0
- fuzzytool-0.1.0/README.md +89 -0
- fuzzytool-0.1.0/ROADMAP.md +52 -0
- fuzzytool-0.1.0/docs/api/python.md +63 -0
- fuzzytool-0.1.0/docs/citing.md +30 -0
- fuzzytool-0.1.0/docs/comparison.md +72 -0
- fuzzytool-0.1.0/docs/extending.md +54 -0
- fuzzytool-0.1.0/docs/getting-started.md +57 -0
- fuzzytool-0.1.0/docs/guide/anfis.md +29 -0
- fuzzytool-0.1.0/docs/guide/clustering.md +50 -0
- fuzzytool-0.1.0/docs/guide/defuzzification.md +28 -0
- fuzzytool-0.1.0/docs/guide/ftransform.md +29 -0
- fuzzytool-0.1.0/docs/guide/mamdani.md +32 -0
- fuzzytool-0.1.0/docs/guide/membership.md +36 -0
- fuzzytool-0.1.0/docs/guide/rules.md +47 -0
- fuzzytool-0.1.0/docs/guide/tsk.md +27 -0
- fuzzytool-0.1.0/docs/guide/type2.md +73 -0
- fuzzytool-0.1.0/docs/guide/visualization.md +27 -0
- fuzzytool-0.1.0/docs/index.md +36 -0
- fuzzytool-0.1.0/docs/installation.md +18 -0
- fuzzytool-0.1.0/examples/anfis.py +24 -0
- fuzzytool-0.1.0/examples/clustering.py +28 -0
- fuzzytool-0.1.0/examples/credit_risk.py +39 -0
- fuzzytool-0.1.0/examples/credit_risk_it2.py +40 -0
- fuzzytool-0.1.0/examples/ftransform.py +30 -0
- fuzzytool-0.1.0/fuzzytool/__init__.py +55 -0
- fuzzytool-0.1.0/fuzzytool/anfis.py +141 -0
- fuzzytool-0.1.0/fuzzytool/cluster.py +231 -0
- fuzzytool-0.1.0/fuzzytool/datasets.py +104 -0
- fuzzytool-0.1.0/fuzzytool/defuzz.py +84 -0
- fuzzytool-0.1.0/fuzzytool/ftransform.py +79 -0
- fuzzytool-0.1.0/fuzzytool/inference/__init__.py +6 -0
- fuzzytool-0.1.0/fuzzytool/inference/mamdani.py +93 -0
- fuzzytool-0.1.0/fuzzytool/inference/tsk.py +77 -0
- fuzzytool-0.1.0/fuzzytool/membership.py +149 -0
- fuzzytool-0.1.0/fuzzytool/norms.py +105 -0
- fuzzytool-0.1.0/fuzzytool/rules.py +34 -0
- fuzzytool-0.1.0/fuzzytool/sets.py +210 -0
- fuzzytool-0.1.0/fuzzytool/type2/__init__.py +27 -0
- fuzzytool-0.1.0/fuzzytool/type2/inference.py +122 -0
- fuzzytool-0.1.0/fuzzytool/type2/reduction.py +83 -0
- fuzzytool-0.1.0/fuzzytool/type2/sets.py +96 -0
- fuzzytool-0.1.0/fuzzytool/viz.py +118 -0
- fuzzytool-0.1.0/mkdocs.yml +79 -0
- fuzzytool-0.1.0/notebooks/01_quickstart.ipynb +210 -0
- fuzzytool-0.1.0/notebooks/02_type2.ipynb +141 -0
- fuzzytool-0.1.0/notebooks/03_clustering.ipynb +130 -0
- fuzzytool-0.1.0/notebooks/04_learning.ipynb +147 -0
- fuzzytool-0.1.0/notebooks/README.md +18 -0
- fuzzytool-0.1.0/paper.bib +32 -0
- fuzzytool-0.1.0/paper.md +66 -0
- fuzzytool-0.1.0/pyproject.toml +52 -0
- fuzzytool-0.1.0/tests/test_cluster.py +73 -0
- fuzzytool-0.1.0/tests/test_inference.py +49 -0
- fuzzytool-0.1.0/tests/test_learning.py +84 -0
- fuzzytool-0.1.0/tests/test_membership.py +40 -0
- fuzzytool-0.1.0/tests/test_type2.py +77 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.9", "3.11", "3.13"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
- name: Install
|
|
20
|
+
run: pip install -e ".[dev,viz]"
|
|
21
|
+
- name: Lint
|
|
22
|
+
run: ruff check fuzzytool tests
|
|
23
|
+
- name: Test
|
|
24
|
+
run: pytest -q
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
pages: write
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: pages
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
- name: Install (package + docs deps so mkdocstrings can import it)
|
|
25
|
+
run: pip install -e ".[docs]"
|
|
26
|
+
- name: Build
|
|
27
|
+
run: mkdocs build --strict
|
|
28
|
+
- uses: actions/upload-pages-artifact@v3
|
|
29
|
+
with:
|
|
30
|
+
path: site
|
|
31
|
+
|
|
32
|
+
deploy:
|
|
33
|
+
needs: build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
environment:
|
|
36
|
+
name: github-pages
|
|
37
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
38
|
+
steps:
|
|
39
|
+
- id: deployment
|
|
40
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Release (PyPI)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment: pypi
|
|
11
|
+
permissions:
|
|
12
|
+
id-token: write # PyPI Trusted Publishing (OIDC) — no API token needed
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- name: Build sdist + wheel
|
|
19
|
+
run: |
|
|
20
|
+
pip install build
|
|
21
|
+
python -m build
|
|
22
|
+
- name: Publish to PyPI
|
|
23
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
|
|
11
|
+
# Tooling
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.coverage
|
|
15
|
+
htmlcov/
|
|
16
|
+
.mypy_cache/
|
|
17
|
+
|
|
18
|
+
# MkDocs build output
|
|
19
|
+
site/
|
|
20
|
+
|
|
21
|
+
# Jupyter
|
|
22
|
+
.ipynb_checkpoints/
|
|
23
|
+
|
|
24
|
+
# OS / editor
|
|
25
|
+
.DS_Store
|
|
26
|
+
.vscode/
|
|
27
|
+
.idea/
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "fuzzytool: a clean, extensible fuzzy-logic toolkit in pure Python",
|
|
3
|
+
"description": "A composable, extensible fuzzy-logic toolkit in pure Python + NumPy: membership functions, t-/s-norms, Mamdani and Takagi-Sugeno inference, interval type-2 sets with Karnik-Mendel type reduction, fuzzy clustering (FCM, Gustafson-Kessel, possibilistic), ANFIS, and the F-transform.",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"upload_type": "software",
|
|
6
|
+
"access_right": "open",
|
|
7
|
+
"creators": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Salmeron, Jose L.",
|
|
10
|
+
"affiliation": "CUNEF Universidad"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"fuzzy logic",
|
|
15
|
+
"fuzzy inference",
|
|
16
|
+
"Mamdani",
|
|
17
|
+
"Takagi-Sugeno",
|
|
18
|
+
"interval type-2",
|
|
19
|
+
"fuzzy clustering",
|
|
20
|
+
"ANFIS",
|
|
21
|
+
"F-transform",
|
|
22
|
+
"Python"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/) and the project adheres to
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Example notebooks (`notebooks/`): quickstart, interval type-2, clustering, and
|
|
12
|
+
ANFIS/F-transform — committed executed.
|
|
13
|
+
- Documentation: a comparison page vs scikit-fuzzy and a citing/releasing page;
|
|
14
|
+
`.zenodo.json` for DOI archival; `notebooks` optional dependency group.
|
|
15
|
+
- **ANFIS** (`fuzzytool.anfis.ANFIS`): a trainable first-order Sugeno system over
|
|
16
|
+
a grid partition, fit with Jang's hybrid scheme (least-squares consequents +
|
|
17
|
+
gradient-descent premises). `fit` / `predict` / `history_`.
|
|
18
|
+
- **F-transform** (`fuzzytool.ftransform.FTransform`): direct and inverse fuzzy
|
|
19
|
+
transform over a triangular partition of unity, with `fit` / `smooth` for
|
|
20
|
+
denoising and compression.
|
|
21
|
+
- **Fuzzy clustering** (`fuzzytool.cluster`):
|
|
22
|
+
- `fuzzy_cmeans` (Bezdek FCM), `gustafson_kessel` (adaptive Mahalanobis norm),
|
|
23
|
+
`possibilistic_cmeans` (typicalities); all seeded for reproducibility.
|
|
24
|
+
- Validity metrics: `partition_coefficient`, `partition_entropy`, `xie_beni`.
|
|
25
|
+
- `viz.plot_clusters` and `datasets.make_blobs`.
|
|
26
|
+
- **Interval type-2 (IT2)** support (`fuzzytool.type2`):
|
|
27
|
+
- IT2 membership functions with a footprint of uncertainty: `it2` (explicit
|
|
28
|
+
LMF/UMF), `it2_scale` (height), `it2_gauss_uncertain_mean`,
|
|
29
|
+
`it2_gauss_uncertain_std`.
|
|
30
|
+
- Interval-valued antecedent evaluation (`Antecedent.eval_interval`); type-1
|
|
31
|
+
and IT2 terms can be mixed in one rule.
|
|
32
|
+
- `IT2Mamdani` (center-of-sets type reduction) and `IT2TSK` engines.
|
|
33
|
+
- Karnik-Mendel type reduction: `km_endpoint`, `karnik_mendel`, `centroid_it2`.
|
|
34
|
+
- `viz.plot_it2_variable` (shaded FOU); `datasets.credit_risk_it2`.
|
|
35
|
+
|
|
36
|
+
## [0.1.0] - 2026-06-24
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- Core membership functions: triangular, trapezoidal, gaussian, generalized
|
|
41
|
+
bell, sigmoid (`fuzzytool.membership`).
|
|
42
|
+
- T-norms and s-norms (min/prod/Łukasiewicz, max/probor/Łukasiewicz), resolved
|
|
43
|
+
by name (`fuzzytool.norms`).
|
|
44
|
+
- `Variable` (linguistic variable) with auto-generated or explicit terms, and an
|
|
45
|
+
operator-based rule-antecedent expression tree (`&`, `|`, `~`).
|
|
46
|
+
- **Mamdani** inference with configurable implication/aggregation and
|
|
47
|
+
defuzzification (centroid, bisector, MOM/SOM/LOM).
|
|
48
|
+
- **Takagi-Sugeno (TSK)** inference (zero- and first-order, plus callable
|
|
49
|
+
consequents).
|
|
50
|
+
- `fuzzytool.viz`: membership-function plots and 2-input control surfaces.
|
|
51
|
+
- `fuzzytool.datasets.tipper`: the classic example system.
|
|
52
|
+
- Test suite, MkDocs Material documentation, and CI.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use fuzzytool, please cite it as below."
|
|
3
|
+
title: "fuzzytool: a clean, extensible fuzzy-logic toolkit in pure Python"
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: Salmeron
|
|
7
|
+
given-names: Jose L.
|
|
8
|
+
version: 0.1.0
|
|
9
|
+
date-released: 2026-06-24
|
|
10
|
+
license: MIT
|
|
11
|
+
repository-code: "https://github.com/fuzzytool/fuzzytool.github.io"
|
|
12
|
+
url: "https://fuzzytool.github.io"
|
|
13
|
+
keywords:
|
|
14
|
+
- fuzzy logic
|
|
15
|
+
- fuzzy inference
|
|
16
|
+
- Mamdani
|
|
17
|
+
- Takagi-Sugeno
|
|
18
|
+
- Python
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
Guide for working in this repository with Claude Code.
|
|
4
|
+
|
|
5
|
+
## What this project is
|
|
6
|
+
|
|
7
|
+
**fuzzytool** — a clean, extensible **fuzzy-logic toolkit** in **pure Python +
|
|
8
|
+
NumPy**, published on PyPI with docs on GitHub Pages. Priorities, in order:
|
|
9
|
+
1) a composable API, 2) algorithm comparison, 3) visualization, 4) code clarity.
|
|
10
|
+
It is the fuzzy-logic sibling of the *turboswarm* PSO library and follows the
|
|
11
|
+
same packaging and extensibility philosophy.
|
|
12
|
+
|
|
13
|
+
## Architecture
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
fuzzytool/
|
|
17
|
+
membership.py MF Protocol + tri/trap/gauss/gbell/sigmoid
|
|
18
|
+
norms.py t-norms (AND) / s-norms (OR), resolved by name
|
|
19
|
+
sets.py FuzzySet, Variable, antecedent tree (& | ~)
|
|
20
|
+
rules.py Rule dataclass (shared by the engines)
|
|
21
|
+
defuzz.py centroid / bisector / mom / som / lom
|
|
22
|
+
inference/ mamdani.py, tsk.py
|
|
23
|
+
viz.py matplotlib: membership plots, control surface
|
|
24
|
+
datasets.py example systems (credit_risk)
|
|
25
|
+
tests/ examples/ docs/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### The central design (read before touching the engines)
|
|
29
|
+
|
|
30
|
+
The inference loop knows **nothing** about concrete variants. Everything that
|
|
31
|
+
changes lives behind small Protocols:
|
|
32
|
+
|
|
33
|
+
- **`MembershipFunction`** (`membership.py`) — a callable `x -> degree`. A new
|
|
34
|
+
shape is a new callable; nothing else changes.
|
|
35
|
+
- **`Norm`** (`norms.py`) — t-/s-norms, resolved by name via `get_tnorm` /
|
|
36
|
+
`get_snorm`. You may also pass a callable directly to an engine.
|
|
37
|
+
- **defuzzifiers** (`defuzz.py`) — resolved by name via `get_defuzzifier`.
|
|
38
|
+
|
|
39
|
+
Rules compose with operators on `Proposition` objects: `&` → t-norm (AND),
|
|
40
|
+
`|` → s-norm (OR), `~` → complement (NOT). The antecedent tree is evaluated by
|
|
41
|
+
`Antecedent.eval(inputs, tnorm, snorm)`; both engines reuse it.
|
|
42
|
+
|
|
43
|
+
`Mamdani` consequents are propositions (`output[term]`); `TSK` consequents are
|
|
44
|
+
numbers, coefficient mappings, or callables.
|
|
45
|
+
|
|
46
|
+
## Commands (verified)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python -m venv .venv && source .venv/bin/activate
|
|
50
|
+
pip install -e ".[dev,viz,docs]"
|
|
51
|
+
pytest -q # tests + doctests (--doctest-modules)
|
|
52
|
+
ruff check fuzzytool tests
|
|
53
|
+
python examples/credit_risk.py
|
|
54
|
+
mkdocs serve # docs at http://127.0.0.1:8000
|
|
55
|
+
mkdocs build --strict
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Conventions
|
|
59
|
+
|
|
60
|
+
- **Language:** all code, comments, identifiers and prose in **English**
|
|
61
|
+
(published internationally on GitHub and PyPI).
|
|
62
|
+
- **Vectorize:** membership functions accept scalars *and* NumPy arrays.
|
|
63
|
+
- **NumPy 2 compat:** `np.trapz` was renamed `np.trapezoid`; `defuzz.py` shims
|
|
64
|
+
both — do not call `np.trapz` directly elsewhere.
|
|
65
|
+
- **Tests:** every new MF / connective / defuzzifier / engine needs a test;
|
|
66
|
+
engines need a behavioral check (monotonicity or known output).
|
|
67
|
+
- **Docstrings:** Google style (rendered by `mkdocstrings`).
|
|
68
|
+
|
|
69
|
+
## How to extend (typical tasks)
|
|
70
|
+
|
|
71
|
+
- **New membership function:** any callable `x -> degree`; add a factory in
|
|
72
|
+
`membership.py` if it is a standard shape, plus a test.
|
|
73
|
+
- **New connective:** register a `(a, b) -> result` in `norms._TNORMS` /
|
|
74
|
+
`_SNORMS`, or pass it directly to the engine.
|
|
75
|
+
- **New defuzzifier:** add a `(x, y) -> float` to `defuzz._METHODS`.
|
|
76
|
+
- **New engine:** implement `__call__(**inputs)`, reuse `Antecedent.eval` and the
|
|
77
|
+
shared `Rule`. Templates: `inference/mamdani.py`, `inference/tsk.py`.
|
|
78
|
+
|
|
79
|
+
## Status
|
|
80
|
+
|
|
81
|
+
See `ROADMAP.md`. Phase 1 (core + Mamdani) and Phase 2 (TSK + viz) are done;
|
|
82
|
+
type-2, clustering, ANFIS and F-transform are planned.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in fuzzytool!
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
python -m venv .venv && source .venv/bin/activate
|
|
9
|
+
pip install -e ".[dev,viz,docs]"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Checks (run before opening a PR)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
ruff check fuzzytool tests # lint
|
|
16
|
+
pytest -q # tests + doctests
|
|
17
|
+
mkdocs build --strict # docs build cleanly
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Conventions
|
|
21
|
+
|
|
22
|
+
- **Language:** all code, comments, identifiers, and prose are in **English**
|
|
23
|
+
(the project is published internationally on GitHub and PyPI).
|
|
24
|
+
- **Tests:** every new membership function, connective, defuzzifier, or engine
|
|
25
|
+
needs a test. Inference engines need at least one behavioral test (e.g. a
|
|
26
|
+
monotonicity or known-output check).
|
|
27
|
+
- **Docstrings:** Google style (rendered by `mkdocstrings`).
|
|
28
|
+
- **Extensibility first:** prefer adding a callable behind an existing Protocol
|
|
29
|
+
over special-casing the inference loop. See [`docs/extending.md`](docs/extending.md).
|
|
30
|
+
|
|
31
|
+
## Adding a feature
|
|
32
|
+
|
|
33
|
+
1. Implement it in the relevant module.
|
|
34
|
+
2. Export it where appropriate (`__init__.py` for public API).
|
|
35
|
+
3. Add tests and a docs entry.
|
|
36
|
+
4. Update `CHANGELOG.md` and, if it completes a milestone, `ROADMAP.md`.
|
fuzzytool-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jose L. Salmeron
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
fuzzytool-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fuzzytool
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A clean, extensible fuzzy-logic toolkit in pure Python + NumPy
|
|
5
|
+
Project-URL: Homepage, https://fuzzytool.github.io
|
|
6
|
+
Project-URL: Documentation, https://fuzzytool.github.io
|
|
7
|
+
Project-URL: Repository, https://github.com/fuzzytool/fuzzytool.github.io
|
|
8
|
+
Project-URL: Issues, https://github.com/fuzzytool/fuzzytool.github.io/issues
|
|
9
|
+
Author: Jose L. Salmeron
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: anfis,fuzzy inference,fuzzy logic,mamdani,takagi-sugeno,type-2
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Requires-Dist: numpy>=1.21
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
24
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
25
|
+
Provides-Extra: docs
|
|
26
|
+
Requires-Dist: mkdocs-material; extra == 'docs'
|
|
27
|
+
Requires-Dist: mkdocstrings[python]; extra == 'docs'
|
|
28
|
+
Provides-Extra: notebooks
|
|
29
|
+
Requires-Dist: ipykernel; extra == 'notebooks'
|
|
30
|
+
Requires-Dist: jupyter; extra == 'notebooks'
|
|
31
|
+
Requires-Dist: matplotlib>=3.4; extra == 'notebooks'
|
|
32
|
+
Requires-Dist: nbconvert; extra == 'notebooks'
|
|
33
|
+
Requires-Dist: nbformat; extra == 'notebooks'
|
|
34
|
+
Provides-Extra: viz
|
|
35
|
+
Requires-Dist: matplotlib>=3.4; extra == 'viz'
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<a href="https://pypi.org/project/fuzzytool/"><img src="https://img.shields.io/pypi/v/fuzzytool?logo=pypi&logoColor=white" alt="PyPI"></a>
|
|
40
|
+
<a href="https://github.com/fuzzytool/fuzzytool.github.io/actions/workflows/ci.yml"><img src="https://github.com/fuzzytool/fuzzytool.github.io/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
41
|
+
<a href="https://fuzzytool.github.io/"><img src="https://img.shields.io/badge/docs-fuzzytool.github.io-3f51b5" alt="Docs"></a>
|
|
42
|
+
<img src="https://img.shields.io/pypi/pyversions/fuzzytool?logo=python&logoColor=white" alt="Python versions">
|
|
43
|
+
<img src="https://img.shields.io/badge/license-MIT-blue" alt="License: MIT">
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
# fuzzytool
|
|
47
|
+
|
|
48
|
+
A clean, **extensible fuzzy-logic toolkit** in **pure Python + NumPy**. Its
|
|
49
|
+
design priorities are a composable API, algorithm comparison, visualization and
|
|
50
|
+
code clarity — a modern alternative to the verbose control API of scikit-fuzzy.
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import fuzzytool as fz
|
|
54
|
+
|
|
55
|
+
# Credit-risk premium: a lender turns a credit score + debt-to-income ratio
|
|
56
|
+
# into the risk points it adds on top of its base interest rate.
|
|
57
|
+
score = fz.Variable("score", (300, 850), terms=["poor", "fair", "good", "excellent"])
|
|
58
|
+
dti = fz.Variable("dti", (0, 50), terms=["low", "moderate", "high"])
|
|
59
|
+
premium = fz.Variable("premium", (0, 12), terms=["low", "medium", "high"])
|
|
60
|
+
|
|
61
|
+
sys = fz.Mamdani(defuzz="centroid")
|
|
62
|
+
sys.rule(score["poor"] | dti["high"], premium["high"]) # |=OR &=AND ~=NOT
|
|
63
|
+
sys.rule(score["fair"] & dti["moderate"], premium["medium"])
|
|
64
|
+
sys.rule(score["good"] | score["excellent"], premium["low"])
|
|
65
|
+
|
|
66
|
+
print(sys(score=800, dti=10)) # the system is just callable -> a low premium
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## The design idea (extensibility)
|
|
70
|
+
|
|
71
|
+
The inference loop knows **nothing** about any concrete variant. Everything that
|
|
72
|
+
changes lives behind small Python **Protocols**:
|
|
73
|
+
|
|
74
|
+
- **`MembershipFunction`** (`fuzzytool/membership.py`) — a callable `x -> degree`.
|
|
75
|
+
A new shape = a new callable.
|
|
76
|
+
- **`Norm`** (`fuzzytool/norms.py`) — t-norms (AND) and s-norms (OR), resolved by
|
|
77
|
+
name. A new connective = one registered function.
|
|
78
|
+
- **defuzzifiers** (`fuzzytool/defuzz.py`) — centroid, bisector, MOM/SOM/LOM,
|
|
79
|
+
resolved by name.
|
|
80
|
+
|
|
81
|
+
Rules read like logic thanks to operator overloading: `&` is the t-norm, `|` the
|
|
82
|
+
s-norm, `~` the complement.
|
|
83
|
+
|
|
84
|
+
## What it includes / roadmap
|
|
85
|
+
|
|
86
|
+
| Phase | Content | Status |
|
|
87
|
+
|------|-----------|--------|
|
|
88
|
+
| 1 | Core: membership functions, t-/s-norms, `Variable`, operator rules, **Mamdani** + defuzzification, tipper example, tests | ✅ |
|
|
89
|
+
| 2 | **Takagi-Sugeno (TSK)** inference + `viz` (membership plots, control surface) | ✅ (TSK + viz) |
|
|
90
|
+
| 3 | **Type-2 / interval type-2** sets (footprint of uncertainty) + Karnik-Mendel type reduction | ✅ |
|
|
91
|
+
| 4 | **Fuzzy clustering**: fuzzy c-means, Gustafson-Kessel, possibilistic | ✅ |
|
|
92
|
+
| 5 | **ANFIS** (trainable TSK) + **F-transform** (direct/inverse) | ✅ |
|
|
93
|
+
| 6 | Notebooks, JOSS `paper.md`, Zenodo DOI, PyPI release | ⏳ |
|
|
94
|
+
|
|
95
|
+
See [`ROADMAP.md`](ROADMAP.md).
|
|
96
|
+
|
|
97
|
+
## Install
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pip install fuzzytool # core (NumPy only)
|
|
101
|
+
pip install fuzzytool[viz] # + matplotlib visualization
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
From source, for development:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
python -m venv .venv && source .venv/bin/activate
|
|
108
|
+
pip install -e ".[dev,viz,docs]"
|
|
109
|
+
pytest -q
|
|
110
|
+
python examples/tipper.py
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Documentation
|
|
114
|
+
|
|
115
|
+
A documentation portal (narrative guide + API reference from docstrings) is built
|
|
116
|
+
with **MkDocs Material** and published to **GitHub Pages**:
|
|
117
|
+
<https://fuzzytool.github.io/>.
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
pip install -e ".[docs]"
|
|
121
|
+
mkdocs serve # live portal at http://127.0.0.1:8000
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
MIT. See [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://pypi.org/project/fuzzytool/"><img src="https://img.shields.io/pypi/v/fuzzytool?logo=pypi&logoColor=white" alt="PyPI"></a>
|
|
3
|
+
<a href="https://github.com/fuzzytool/fuzzytool.github.io/actions/workflows/ci.yml"><img src="https://github.com/fuzzytool/fuzzytool.github.io/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
4
|
+
<a href="https://fuzzytool.github.io/"><img src="https://img.shields.io/badge/docs-fuzzytool.github.io-3f51b5" alt="Docs"></a>
|
|
5
|
+
<img src="https://img.shields.io/pypi/pyversions/fuzzytool?logo=python&logoColor=white" alt="Python versions">
|
|
6
|
+
<img src="https://img.shields.io/badge/license-MIT-blue" alt="License: MIT">
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
# fuzzytool
|
|
10
|
+
|
|
11
|
+
A clean, **extensible fuzzy-logic toolkit** in **pure Python + NumPy**. Its
|
|
12
|
+
design priorities are a composable API, algorithm comparison, visualization and
|
|
13
|
+
code clarity — a modern alternative to the verbose control API of scikit-fuzzy.
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import fuzzytool as fz
|
|
17
|
+
|
|
18
|
+
# Credit-risk premium: a lender turns a credit score + debt-to-income ratio
|
|
19
|
+
# into the risk points it adds on top of its base interest rate.
|
|
20
|
+
score = fz.Variable("score", (300, 850), terms=["poor", "fair", "good", "excellent"])
|
|
21
|
+
dti = fz.Variable("dti", (0, 50), terms=["low", "moderate", "high"])
|
|
22
|
+
premium = fz.Variable("premium", (0, 12), terms=["low", "medium", "high"])
|
|
23
|
+
|
|
24
|
+
sys = fz.Mamdani(defuzz="centroid")
|
|
25
|
+
sys.rule(score["poor"] | dti["high"], premium["high"]) # |=OR &=AND ~=NOT
|
|
26
|
+
sys.rule(score["fair"] & dti["moderate"], premium["medium"])
|
|
27
|
+
sys.rule(score["good"] | score["excellent"], premium["low"])
|
|
28
|
+
|
|
29
|
+
print(sys(score=800, dti=10)) # the system is just callable -> a low premium
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## The design idea (extensibility)
|
|
33
|
+
|
|
34
|
+
The inference loop knows **nothing** about any concrete variant. Everything that
|
|
35
|
+
changes lives behind small Python **Protocols**:
|
|
36
|
+
|
|
37
|
+
- **`MembershipFunction`** (`fuzzytool/membership.py`) — a callable `x -> degree`.
|
|
38
|
+
A new shape = a new callable.
|
|
39
|
+
- **`Norm`** (`fuzzytool/norms.py`) — t-norms (AND) and s-norms (OR), resolved by
|
|
40
|
+
name. A new connective = one registered function.
|
|
41
|
+
- **defuzzifiers** (`fuzzytool/defuzz.py`) — centroid, bisector, MOM/SOM/LOM,
|
|
42
|
+
resolved by name.
|
|
43
|
+
|
|
44
|
+
Rules read like logic thanks to operator overloading: `&` is the t-norm, `|` the
|
|
45
|
+
s-norm, `~` the complement.
|
|
46
|
+
|
|
47
|
+
## What it includes / roadmap
|
|
48
|
+
|
|
49
|
+
| Phase | Content | Status |
|
|
50
|
+
|------|-----------|--------|
|
|
51
|
+
| 1 | Core: membership functions, t-/s-norms, `Variable`, operator rules, **Mamdani** + defuzzification, tipper example, tests | ✅ |
|
|
52
|
+
| 2 | **Takagi-Sugeno (TSK)** inference + `viz` (membership plots, control surface) | ✅ (TSK + viz) |
|
|
53
|
+
| 3 | **Type-2 / interval type-2** sets (footprint of uncertainty) + Karnik-Mendel type reduction | ✅ |
|
|
54
|
+
| 4 | **Fuzzy clustering**: fuzzy c-means, Gustafson-Kessel, possibilistic | ✅ |
|
|
55
|
+
| 5 | **ANFIS** (trainable TSK) + **F-transform** (direct/inverse) | ✅ |
|
|
56
|
+
| 6 | Notebooks, JOSS `paper.md`, Zenodo DOI, PyPI release | ⏳ |
|
|
57
|
+
|
|
58
|
+
See [`ROADMAP.md`](ROADMAP.md).
|
|
59
|
+
|
|
60
|
+
## Install
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install fuzzytool # core (NumPy only)
|
|
64
|
+
pip install fuzzytool[viz] # + matplotlib visualization
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
From source, for development:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
python -m venv .venv && source .venv/bin/activate
|
|
71
|
+
pip install -e ".[dev,viz,docs]"
|
|
72
|
+
pytest -q
|
|
73
|
+
python examples/tipper.py
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Documentation
|
|
77
|
+
|
|
78
|
+
A documentation portal (narrative guide + API reference from docstrings) is built
|
|
79
|
+
with **MkDocs Material** and published to **GitHub Pages**:
|
|
80
|
+
<https://fuzzytool.github.io/>.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install -e ".[docs]"
|
|
84
|
+
mkdocs serve # live portal at http://127.0.0.1:8000
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
MIT. See [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
Phases mirror the structure of the sibling project *turboswarm*: each phase is a
|
|
4
|
+
self-contained, testable increment.
|
|
5
|
+
|
|
6
|
+
## ✅ Phase 1 — Core + Mamdani
|
|
7
|
+
|
|
8
|
+
- [x] Membership functions (tri, trap, gauss, gbell, sigmoid) behind the
|
|
9
|
+
`MembershipFunction` Protocol.
|
|
10
|
+
- [x] T-norms / s-norms resolved by name; standard complement.
|
|
11
|
+
- [x] `Variable` + operator-based antecedent tree (`&`, `|`, `~`).
|
|
12
|
+
- [x] Mamdani inference + defuzzification (centroid, bisector, MOM/SOM/LOM).
|
|
13
|
+
- [x] Tipper example, test suite, packaging, docs, CI.
|
|
14
|
+
|
|
15
|
+
## ✅ Phase 2 — TSK + visualization
|
|
16
|
+
|
|
17
|
+
- [x] Takagi-Sugeno inference (zero/first-order + callable consequents).
|
|
18
|
+
- [x] `viz`: membership plots, 2-input control surface.
|
|
19
|
+
- [ ] Example notebooks (tipper, TSK, comparison).
|
|
20
|
+
|
|
21
|
+
## ✅ Phase 3 — Type-2 / interval type-2
|
|
22
|
+
|
|
23
|
+
- [x] IT2 membership functions (footprint of uncertainty): explicit LMF/UMF,
|
|
24
|
+
height scaling, uncertain Gaussian mean, uncertain Gaussian spread.
|
|
25
|
+
- [x] Interval antecedent evaluation (type-1 and IT2 terms mix freely).
|
|
26
|
+
- [x] IT2 inference: `IT2Mamdani` (center-of-sets) and `IT2TSK`.
|
|
27
|
+
- [x] Karnik-Mendel type reduction (`km_endpoint`, `karnik_mendel`,
|
|
28
|
+
`centroid_it2`) + FOU visualization.
|
|
29
|
+
|
|
30
|
+
## ✅ Phase 4 — Fuzzy clustering
|
|
31
|
+
|
|
32
|
+
- [x] Fuzzy c-means (FCM).
|
|
33
|
+
- [x] Gustafson-Kessel.
|
|
34
|
+
- [x] Possibilistic c-means.
|
|
35
|
+
- [x] Cluster-quality metrics (partition coefficient, partition entropy,
|
|
36
|
+
Xie-Beni) + 2-D cluster visualization and a synthetic-blob generator.
|
|
37
|
+
|
|
38
|
+
## ✅ Phase 5 — ANFIS + F-transform
|
|
39
|
+
|
|
40
|
+
- [x] ANFIS: trainable first-order TSK with Jang's hybrid learning (least
|
|
41
|
+
squares for consequents + gradient descent for premises).
|
|
42
|
+
- [x] F-transform: direct and inverse over a triangular fuzzy partition
|
|
43
|
+
(partition of unity), with smoothing/denoising.
|
|
44
|
+
|
|
45
|
+
## ⏳ Phase 6 — Release
|
|
46
|
+
|
|
47
|
+
- [x] Example notebooks (`notebooks/`) and a comparison page vs scikit-fuzzy.
|
|
48
|
+
- [x] JOSS `paper.md`; Zenodo metadata (`.zenodo.json`) and a citing/releasing page.
|
|
49
|
+
- [x] GitHub Pages live (`https://fuzzytool.github.io`).
|
|
50
|
+
- [ ] Register the PyPI trusted publisher, then tag `v0.1.0` to publish (the
|
|
51
|
+
`release-pypi.yml` workflow is ready).
|
|
52
|
+
- [ ] Enable the Zenodo GitHub integration and cut a release to mint a DOI.
|