Skip to content

API reference

Generated from docstrings with mkdocstrings.

Membership functions

fuzzytool.membership

Membership functions.

Every membership function (MF) is a callable mapping a crisp value (scalar or NumPy array) to a membership degree in [0, 1]. The :class:MembershipFunction Protocol is the only contract the rest of the library relies on: the inference engine never inspects a concrete MF type, so a new shape = a new callable, with no changes to the core (mirroring the "one variant = one impl" design of the sibling project turboswarm).

The lowercase factory functions (:func:tri, :func:trap, :func:gauss, :func:gbell, :func:sigmoid) are the public API; they return small classes so the parameters stay introspectable for visualization and serialization.

MembershipFunction

Bases: Protocol

A callable x -> degree with membership degrees in [0, 1].

Triangular

Triangular MF with feet at a/c and peak at b.

Trapezoidal

Trapezoidal MF; flat top between b and c.

Gaussian

Gaussian MF centered at c with spread sigma.

GeneralizedBell

Generalized bell MF: 1 / (1 + |(x - c) / a|^(2b)).

Sigmoid

Sigmoidal MF: 1 / (1 + exp(-a (x - c))). Monotonic (invertible).

inverse

inverse(y: float) -> float

The x at which membership equals y (for Tsukamoto inference).

RampUp

Monotonically increasing ramp: 0 below a, 1 above b.

RampDown

Monotonically decreasing ramp: 1 below a, 0 above b.

tri

tri(a: float, b: float, c: float) -> Triangular

Triangular MF: feet at a/c, peak at b.

trap

trap(a: float, b: float, c: float, d: float) -> Trapezoidal

Trapezoidal MF: shoulders a/d, flat top b..c.

gauss

gauss(c: float, sigma: float) -> Gaussian

Gaussian MF: center c, spread sigma.

gbell

gbell(a: float, b: float, c: float) -> GeneralizedBell

Generalized bell MF: width a, slope b, center c.

sigmoid

sigmoid(a: float, c: float) -> Sigmoid

Sigmoidal MF: slope a, inflection c.

ramp_up

ramp_up(a: float, b: float) -> RampUp

Increasing ramp MF from 0 at a to 1 at b (monotonic).

ramp_down

ramp_down(a: float, b: float) -> RampDown

Decreasing ramp MF from 1 at a to 0 at b (monotonic).

to_dict

to_dict(mf) -> dict

Serialize a built-in membership function to a JSON-ready dict.

from_dict

from_dict(d: dict)

Rebuild a membership function from :func:to_dict output.

Connectives (t-norms / s-norms)

fuzzytool.norms

Fuzzy connectives: t-norms (AND) and s-norms / t-conorms (OR).

Connectives are plain vectorized callables (a, b) -> result operating elementwise on membership degrees. They are pluggable: the inference engines look them up by name through :func:get_tnorm / :func:get_snorm, so adding a connective means registering one function — the engine never changes.

Norm

Bases: Protocol

A binary connective on membership degrees.

t_min

t_min(a, b)

Minimum (Gödel) t-norm.

t_prod

t_prod(a, b)

Product (algebraic) t-norm.

t_lukasiewicz

t_lukasiewicz(a, b)

Łukasiewicz t-norm: max(0, a + b - 1).

s_max

s_max(a, b)

Maximum (Gödel) s-norm.

s_probor

s_probor(a, b)

Probabilistic OR (algebraic sum): a + b - a*b.

s_lukasiewicz

s_lukasiewicz(a, b)

Łukasiewicz s-norm: min(1, a + b).

get_tnorm

get_tnorm(name: str | Callable) -> Callable

Resolve a t-norm by name (or pass a callable through unchanged).

get_snorm

get_snorm(name: str | Callable) -> Callable

Resolve an s-norm by name (or pass a callable through unchanged).

complement

complement(a)

Standard fuzzy complement (NOT): 1 - a.

Sets, variables, and rule antecedents

fuzzytool.sets

Fuzzy sets, linguistic variables, and the rule-antecedent expression tree.

A :class:Variable is a linguistic variable: a named universe of discourse plus a dictionary of terms (named membership functions). Indexing a variable with a term name (score["good"]) returns a :class:Proposition, the atom of a rule antecedent. Propositions compose with Python operators:

score["poor"] | dti["high"]         # OR  (s-norm)
score["good"] & dti["low"]          # AND (t-norm)
~dti["high"]                        # NOT (complement)

The result is a small expression tree that the inference engine evaluates against crisp inputs to get a firing strength. The same atom doubles as a rule consequent (premium["high"]), so there is a single concept to learn.

Antecedent

Base node of a rule-antecedent expression tree.

eval

eval(inputs: Mapping[str, float], tnorm, snorm) -> np.ndarray

Return the (type-1) firing strength given crisp inputs.

eval_interval

eval_interval(inputs: Mapping[str, float], tnorm, snorm)

Return the firing interval (lower, upper) for IT2 inference.

Type-1 terms collapse to a degenerate interval (d, d), so type-1 and IT2 terms may be mixed freely in the same antecedent.

to_dict

to_dict() -> dict

Serialize this antecedent subtree to a JSON-ready dict.

Proposition

Bases: Antecedent

An atomic variable is term clause; also used as a consequent.

Variable

A linguistic variable: a named universe with named fuzzy-set terms.

Parameters:

Name Type Description Default
name str

identifier; rule inputs are matched to variables by this name.

required
universe tuple[float, float]

(low, high) range of the universe of discourse.

required
terms Iterable[str] | Mapping[str, MembershipFunction] | None

optional list of term names to auto-generate evenly across the universe, or a mapping {name: MembershipFunction}.

None
kind str

shape used by auto-generation ("triangular" or "gauss").

'triangular'
resolution int

number of samples used to discretize the universe for Mamdani defuzzification.

501

auto_terms

auto_terms(names: list[str], kind: str = 'triangular') -> Variable

Generate evenly-spaced terms named names across the universe.

to_dict

to_dict() -> dict

Serialize this variable (universe + terms) to a JSON-ready dict.

Only built-in membership functions can be serialized (see :func:fuzzytool.membership.to_dict).

from_dict classmethod

from_dict(d: dict) -> Variable

Rebuild a variable from :meth:to_dict output.

antecedent_from_dict

antecedent_from_dict(d: dict, variables: Mapping[str, Variable]) -> Antecedent

Rebuild an antecedent tree from :meth:Antecedent.to_dict output.

variables maps variable names to the :class:Variable instances the propositions should reference.

Rules

fuzzytool.rules

Fuzzy rules shared by the inference engines.

A :class:Rule pairs an antecedent expression with a consequent and an optional weight. The consequent is interpreted by the engine: Mamdani expects a :class:~fuzzytool.sets.Proposition (output is term); TSK expects a constant or a linear coefficient vector.

Rule dataclass

IF antecedent THEN consequent with an optional firing weight.

Defuzzification

fuzzytool.defuzz

Defuzzification: collapse an aggregated output set into a crisp value.

Each defuzzifier takes the discretized universe x and the aggregated membership y (same shape) and returns a scalar. They are looked up by name through :func:get_defuzzifier, so adding a method = registering a function.

centroid

centroid(x: ndarray, y: ndarray) -> float

Center of gravity of the area under y (the most common choice).

bisector

bisector(x: ndarray, y: ndarray) -> float

Abscissa that splits the area under y into two equal halves.

mom

mom(x: ndarray, y: ndarray) -> float

Mean of maxima.

som

som(x: ndarray, y: ndarray) -> float

Smallest of maxima.

lom

lom(x: ndarray, y: ndarray) -> float

Largest of maxima.

centroid_batch

centroid_batch(x: ndarray, Y: ndarray) -> np.ndarray

Vectorized :func:centroid over the rows of Y.

bisector_batch

bisector_batch(x: ndarray, Y: ndarray) -> np.ndarray

Vectorized :func:bisector over the rows of Y.

get_batch_defuzzifier

get_batch_defuzzifier(fn: Callable) -> Callable | None

Return the vectorized form of a defuzzifier, or None if it has none.

get_defuzzifier

get_defuzzifier(name: str | Callable) -> Callable

Resolve a defuzzifier by name (or pass a callable through unchanged).

Inference — Mamdani

fuzzytool.inference.mamdani

Mamdani fuzzy inference.

The engine knows nothing about specific membership functions, connectives, or defuzzifiers: t-norm, s-norm, implication, aggregation and defuzzification are all resolved by name (or supplied as callables) and applied uniformly. Adding a behavior means registering a function in :mod:fuzzytool.norms or :mod:fuzzytool.defuzz, never editing this loop.

Pipeline per call: evaluate each rule's antecedent to a firing strength → shape its consequent term over the output universe via the implication operator → aggregate the shaped sets per output variable → defuzzify.

Mamdani

A Mamdani inference system.

Parameters:

Name Type Description Default
tnorm str | Callable

t-norm for AND in antecedents (default "min").

'min'
snorm str | Callable

s-norm for OR in antecedents (default "max").

'max'
implication str

how a firing strength shapes its consequent set — "min" (clip) or "prod" (scale).

'min'
aggregation str | Callable

s-norm combining shaped sets per output (default "max").

'max'
defuzz str | Callable

defuzzification method (default "centroid").

'centroid'
on_no_rule str

crisp value for an output when no rule fires — "mid" (midpoint of the output universe, the default), "nan", or "raise". Applied identically by __call__ and predict.

'mid'

rule

rule(antecedent: Antecedent, consequent: Proposition, weight: float = 1.0) -> Mamdani

Add IF antecedent THEN output is term and return self.

__call__

__call__(**inputs: float)

Run inference. Returns a float for one output, else a dict by name.

predict

predict(**inputs)

Vectorized inference over array-valued inputs.

Each keyword is an array of n samples. Returns an array of length n for a single output, else a dict of arrays. Equivalent to calling the system once per sample, but evaluated in batch.

Inference — Takagi-Sugeno (TSK)

fuzzytool.inference.tsk

Takagi-Sugeno-Kang (TSK) fuzzy inference.

Consequents are crisp functions of the inputs rather than fuzzy sets, so there is no defuzzification: the output is the firing-weighted average of the rule consequents. A consequent may be

  • a number — zero-order (Sugeno constant), e.g. 5.0;
  • a mapping {"const": b0, "x": b1, ...} — first-order linear in the inputs;
  • any callable f(**inputs) -> float — arbitrary.

TSK

A (zero- or first-order) Takagi-Sugeno inference system.

Parameters:

Name Type Description Default
tnorm str | Callable

t-norm for AND in antecedents (default "min").

'min'
snorm str | Callable

s-norm for OR in antecedents (default "max").

'max'
on_no_rule str

what to return when no rule fires — "nan" (default) or "raise". Applied identically by __call__ and predict.

'nan'

rule

rule(antecedent: Antecedent, consequent, weight: float = 1.0) -> TSK

Add IF antecedent THEN output = consequent and return self.

__call__

__call__(**inputs: float) -> float

Run inference, returning the firing-weighted average output.

predict

predict(**inputs) -> np.ndarray

Vectorized inference over array-valued inputs (n per keyword).

Returns an array of length n. Samples where no rule fires follow on_no_rule: nan (default) or a raised ValueError.

Inference — Tsukamoto

fuzzytool.inference.tsukamoto

Tsukamoto fuzzy inference.

In a Tsukamoto system every rule's consequent is a monotonic membership function. A rule firing with strength w produces the crisp value at which its consequent reaches w (the inverse of the monotonic MF). The system output is the firing-weighted average of those crisp values — so, like TSK, there is no defuzzification step.

Consequents must expose inverse(degree) -> value; the built-in :func:~fuzzytool.membership.ramp_up, :func:~fuzzytool.membership.ramp_down and :func:~fuzzytool.membership.sigmoid do.

Tsukamoto

A Tsukamoto inference system (monotonic consequents).

Parameters:

Name Type Description Default
tnorm str | Callable

t-norm for AND in antecedents (default "min").

'min'
snorm str | Callable

s-norm for OR in antecedents (default "max").

'max'
on_no_rule str

what to return when no rule fires — "nan" (default) or "raise".

'nan'

rule

rule(antecedent: Antecedent, consequent, weight: float = 1.0) -> Tsukamoto

Add a rule; consequent is a monotonic MF with an inverse.

__call__

__call__(**inputs: float) -> float

Run inference, returning the firing-weighted average crisp output.

Rule learning (Wang-Mendel)

fuzzytool.learn

Learning fuzzy rule bases from data.

:func:wang_mendel implements the classic Wang-Mendel (1992) method: it turns each training sample into one fuzzy rule (picking, per variable, the term with the highest membership), assigns the rule a degree equal to the product of those memberships, and resolves antecedent conflicts by keeping the highest-degree consequent. The result is a ready-to-use :class:~fuzzytool.inference.Mamdani.

wang_mendel

wang_mendel(X: ndarray, y: ndarray, inputs: list[Variable], output: Variable) -> Mamdani

Generate a Mamdani rule base from data with the Wang-Mendel method.

Parameters:

Name Type Description Default
X ndarray

inputs, shape (n_samples, len(inputs)).

required
y ndarray

targets, shape (n_samples,).

required
inputs list[Variable]

the input linguistic variables (each pre-populated with terms); column j of X maps to inputs[j].

required
output Variable

the output linguistic variable (pre-populated with terms).

required

Returns:

Name Type Description
A Mamdani

class:~fuzzytool.inference.Mamdani with one rule per distinct

Mamdani

antecedent (conflicts resolved by rule degree).

Fuzzy numbers

fuzzytool.fuzzynum

Fuzzy numbers and their arithmetic.

A fuzzy number is a convex, normal fuzzy set on the reals. This module provides the two most used shapes — triangular (TFN) and trapezoidal (TrFN) — with standard fuzzy arithmetic (+ - * / and scalar scaling), alpha-cuts, a crisp (centroid) value, and a vertex distance used by fuzzy MCDM (see :mod:fuzzytool.mcdm).

Multiplication and division use the common positive-support approximation (operate on the ordered defining points), which is exact for +/- and a good approximation for *// when supports are positive.

FuzzyNumber

Base class for fuzzy numbers defined by ordered points p.

distance

distance(other: FuzzyNumber) -> float

Vertex distance to another fuzzy number of the same shape.

TriangularFuzzyNumber

Bases: FuzzyNumber

Triangular fuzzy number (a, b, c) with peak at b.

TrapezoidalFuzzyNumber

Bases: FuzzyNumber

Trapezoidal fuzzy number (a, b, c, d) with flat top [b, c].

tfn

tfn(a: float, b: float, c: float) -> TriangularFuzzyNumber

Shortcut for :class:TriangularFuzzyNumber.

trfn

trfn(a: float, b: float, c: float, d: float) -> TrapezoidalFuzzyNumber

Shortcut for :class:TrapezoidalFuzzyNumber.

rank

rank(numbers: list[FuzzyNumber]) -> list[int]

Indices that sort numbers from largest to smallest by centroid.

Fuzzy MCDM

fuzzytool.mcdm

Fuzzy multi-criteria decision making (MCDM).

  • :func:fuzzy_topsis — Chen's (2000) fuzzy TOPSIS: rank alternatives by their closeness to the fuzzy positive-ideal solution.
  • :func:fuzzy_ahp — Chang's (1996) extent-analysis AHP: derive crisp criterion weights from a triangular-fuzzy pairwise-comparison matrix.

Inputs are triangular fuzzy numbers (:class:~fuzzytool.fuzzynum.TriangularFuzzyNumber).

TopsisResult dataclass

Result of :func:fuzzy_topsis.

Attributes:

Name Type Description
closeness ndarray

closeness coefficient CC per alternative (higher = better).

ranking list[int]

alternative indices ordered best-to-worst.

d_plus ndarray

distance to the fuzzy positive-ideal solution per alternative.

d_minus ndarray

distance to the fuzzy negative-ideal solution per alternative.

fuzzy_topsis

fuzzy_topsis(matrix: list, weights: list, benefit: list) -> TopsisResult

Rank alternatives with Chen's fuzzy TOPSIS.

Parameters:

Name Type Description Default
matrix list

m x n ratings as TriangularFuzzyNumber (m alternatives, n criteria).

required
weights list

n criterion weights as TriangularFuzzyNumber.

required
benefit list

length-n booleans — True if a criterion is to be maximized (benefit), False if minimized (cost).

required

Returns:

Name Type Description
A TopsisResult

class:TopsisResult.

fuzzy_ahp

fuzzy_ahp(matrix: list) -> np.ndarray

Crisp criterion weights from a fuzzy pairwise matrix (Chang's method).

Parameters:

Name Type Description Default
matrix list

n x n pairwise comparisons as TriangularFuzzyNumber; the diagonal is (1, 1, 1) and matrix[j][i] is the reciprocal of matrix[i][j].

required

Returns:

Type Description
ndarray

A length-n array of normalized, non-negative weights summing to 1.

Serialization

fuzzytool.serialize

Save and load fuzzy inference systems as JSON.

Supports :class:~fuzzytool.inference.Mamdani and :class:~fuzzytool.inference.TSK systems whose connectives/defuzzifier were given by name and whose variables use built-in membership functions. TSK consequents must be numbers or coefficient mappings (callable consequents cannot be serialized).

fz.save(system, "system.json")
system = fz.load("system.json")

to_dict

to_dict(system) -> dict

Serialize a Mamdani or TSK system to a JSON-ready dict.

from_dict

from_dict(d: dict)

Rebuild a Mamdani or TSK system from :func:to_dict output.

save

save(system, path: str) -> None

Write system to path as JSON.

load

load(path: str)

Read a system back from a JSON file written by :func:save.

Interval type-2 — sets

fuzzytool.type2.sets

Interval type-2 (IT2) membership functions.

An :class:IntervalType2MF carries a lower (LMF) and an upper (UMF) type-1 membership function. Calling it returns the membership interval (lower, upper); the engines also call .lower(x) / .upper(x) directly.

The constructors cover the standard ways of building an FOU from a type-1 set:

  • :func:it2 — explicit LMF/UMF;
  • :func:it2_scale — height uncertainty (LMF is a scaled-down UMF);
  • :func:it2_gauss_uncertain_mean — a Gaussian with mean in [c1, c2];
  • :func:it2_gauss_uncertain_std — a Gaussian with uncertain spread.

IntervalType2MF

An IT2 set defined by a lower (LMF) and an upper (UMF) type-1 MF.

The UMF must dominate the LMF everywhere (LMF(x) <= UMF(x)); this is not enforced at construction (it would require sampling the universe) but holds for every set built through the constructors below.

it2

it2(lower: MembershipFunction, upper: MembershipFunction) -> IntervalType2MF

An IT2 set from explicit lower and upper type-1 membership functions.

it2_scale

it2_scale(mf: MembershipFunction, scale: float) -> IntervalType2MF

Height-uncertainty FOU: UMF is mf, LMF is scale * mf (0 < scale ≤ 1).

it2_gauss_uncertain_mean

it2_gauss_uncertain_mean(c1: float, c2: float, sigma: float) -> IntervalType2MF

Gaussian with an uncertain mean spanning [c1, c2] (c1 < c2).

The UMF is the upper envelope of all Gaussians with mean in [c1, c2] (flat-topped at 1 between the means); the LMF is their lower envelope.

it2_gauss_uncertain_std

it2_gauss_uncertain_std(c: float, sigma_lo: float, sigma_hi: float) -> IntervalType2MF

Gaussian with an uncertain spread: UMF uses the wider σ, LMF the narrower.

Interval type-2 — inference

fuzzytool.type2.inference

Interval type-2 inference engines.

Both engines evaluate each rule's antecedent to a firing interval [f_low, f_high] (via :meth:Antecedent.eval_interval) and then collapse the rule base with Karnik-Mendel type reduction, returning the midpoint of the type-reduced interval [y_l, y_r].

  • :class:IT2Mamdani uses center-of-sets type reduction: each consequent IT2 set is summarized by its centroid interval (computed once and cached), and KM combines those centroids weighted by the firing intervals.
  • :class:IT2TSK has crisp consequents (numbers, coefficient mappings, or callables) and applies KM directly to them.

IT2Mamdani

Interval type-2 Mamdani inference (center-of-sets type reduction).

Parameters:

Name Type Description Default
tnorm str | Callable

t-norm for AND in antecedents (default "min").

'min'
snorm str | Callable

s-norm for OR in antecedents (default "max").

'max'

rule

rule(antecedent: Antecedent, consequent: Proposition, weight: float = 1.0) -> IT2Mamdani

Add IF antecedent THEN output is term and return self.

__call__

__call__(**inputs: float)

Run inference. Returns a float for one output, else a dict by name.

IT2TSK

Interval type-2 Takagi-Sugeno inference (KM over crisp consequents).

Consequents follow the same convention as the type-1 :class:~fuzzytool.inference.tsk.TSK engine: a number, a coefficient mapping {"const": b0, "x": b1, ...}, or a callable f(**inputs) -> float.

rule

rule(antecedent: Antecedent, consequent, weight: float = 1.0) -> IT2TSK

Add IF antecedent THEN output = consequent and return self.

__call__

__call__(**inputs: float) -> float

Run inference, returning the midpoint of the type-reduced interval.

Interval type-2 — type reduction

fuzzytool.type2.reduction

Karnik-Mendel type reduction.

Type reduction turns the interval-valued output of an IT2 system into a crisp interval [y_l, y_r] (typically defuzzified as its midpoint). The Karnik-Mendel (KM) algorithm finds each endpoint by locating the switch point where the per-point weight flips between its lower and upper bound.

The single primitive :func:km_endpoint is reused everywhere: for an IT2 set's centroid (points = universe samples, weights = the FOU) and for an IT2 rule base (points = consequent centroids, weights = rule firing intervals).

km_endpoint

km_endpoint(points: ndarray, lower: ndarray, upper: ndarray, side: str = 'l', max_iter: int = 100) -> float

One endpoint of the type-reduced interval via Karnik-Mendel.

Parameters:

Name Type Description Default
points ndarray

the y-values (e.g. consequent centroids or universe samples).

required
lower ndarray

per-point weight lower bounds (same shape as points).

required
upper ndarray

per-point weight upper bounds (same shape as points).

required
side str

"l" for the left endpoint y_l, "r" for the right y_r.

'l'
max_iter int

safeguard on the Karnik-Mendel iteration count.

100

Left endpoint uses the upper weights to the left of the switch and the lower weights to its right; the right endpoint mirrors this.

karnik_mendel

karnik_mendel(points, lower, upper) -> tuple[float, float]

Type-reduce to the interval (y_l, y_r) over a shared set of points.

centroid_it2

centroid_it2(it2mf, universe) -> tuple[float, float]

Centroid interval (c_l, c_r) of an IT2 set over universe.

General type-2 (zSlices)

fuzzytool.type2.general

General type-2 (GT2) fuzzy sets via the zSlices / alpha-plane representation.

An interval type-2 set treats every point inside its footprint of uncertainty (FOU) as equally possible. A general type-2 set adds a secondary membership that weights those possibilities — the third dimension IT2 throws away.

A practical, exact way to handle that third dimension is the zSlices (alpha -plane) decomposition (Wagner & Hagras): slice the secondary domain at levels z and, at each level, the GT2 set reduces to an ordinary IT2 set whose FOU is the z-cut. Inference and type reduction then run the existing IT2 machinery on each slice and combine the results, weighted by z.

Here a GT2 set is built from an IT2 footprint plus a triangular secondary peaking at the FOU's principal (mid) MF: at z -> 0 a slice is the full FOU, at z = 1 it collapses to the principal MF.

  • :class:GeneralType2MF — a stack of IT2 z-slices (also exposes the overall FOU via lower/upper, so it degrades gracefully to IT2).
  • :func:gt2_from_it2, :func:gt2_gauss_uncertain_mean, :func:gt2_scale — constructors.
  • :class:GeneralType2Mamdani — z-weighted stack of IT2 Mamdani inferences.
  • :func:centroid_gt2 — zSlices centroid of a single GT2 set.

GeneralType2MF

A general type-2 set represented as a stack of IT2 z-slices.

Parameters:

Name Type Description Default
slices list[IntervalType2MF]

IT2 sets, one per z level, narrowing toward the principal MF as z increases.

required
zlevels ndarray

the secondary levels (in (0, 1]), ascending, aligned with slices.

required
footprint IntervalType2MF

the overall FOU as an IT2 set (used for lower/upper so the GT2 set can stand in for its IT2 footprint).

required

slice

slice(i: int) -> IntervalType2MF

The IT2 set at z-level index i.

GeneralType2Mamdani

General type-2 Mamdani inference via the zSlices decomposition.

At each z level the GT2 terms collapse to their IT2 z-slice and the existing :class:~fuzzytool.type2.inference.IT2Mamdani engine (center-of-sets type reduction) produces a crisp output y(z). The final result is the z-weighted average Σ z·y(z) / Σ z — the centroid of the type-reduced general type-2 output.

Variables may mix GT2 and IT2/type-1 terms; only the GT2 terms are sliced. All GT2 terms must share the same z levels (same n_slices).

rule

rule(antecedent, consequent, weight: float = 1.0) -> GeneralType2Mamdani

Add IF antecedent THEN output is term and return self.

__call__

__call__(**inputs: float)

Run inference. Returns a float for one output, else a dict by name.

gt2_from_it2

gt2_from_it2(footprint: IntervalType2MF, n_slices: int = 5) -> GeneralType2MF

Build a GT2 set from an IT2 FOU with a triangular secondary MF.

The secondary membership peaks at the principal MF (the midline of the FOU) and falls linearly to 0 at the LMF/UMF. The z-slice at level z is the IT2 set whose FOU is narrowed from the full footprint toward that midline by a factor (1 - z).

Parameters:

Name Type Description Default
footprint IntervalType2MF

the IT2 set describing the full footprint of uncertainty.

required
n_slices int

number of z levels (z = 1/n .. 1). More slices = a finer secondary, at proportional cost.

5

gt2_gauss_uncertain_mean

gt2_gauss_uncertain_mean(c1: float, c2: float, sigma: float, n_slices: int = 5) -> GeneralType2MF

GT2 Gaussian with an uncertain mean in [c1, c2] (triangular secondary).

gt2_scale

gt2_scale(mf, scale: float, n_slices: int = 5) -> GeneralType2MF

GT2 set from a height-uncertainty FOU (UMF mf, LMF scale * mf).

centroid_gt2

centroid_gt2(gt2mf: GeneralType2MF, universe) -> float

zSlices centroid of a GT2 set: z-weighted mean of per-slice IT2 centroids.

Fuzzy clustering

fuzzytool.cluster

Fuzzy clustering.

Unlike crisp k-means, fuzzy clustering lets each sample belong to several clusters with graded membership. This module provides three algorithms and a small set of validity metrics, all on plain NumPy arrays of shape (n_samples, n_features):

  • :func:fuzzy_cmeans — Bezdek's FCM (spherical clusters, Euclidean norm).
  • :func:gustafson_kessel — GK, an adaptive norm per cluster that captures ellipsoidal shapes.
  • :func:possibilistic_cmeans — PCM, which drops the "memberships sum to 1" constraint so outliers get low typicality in every cluster.

Each returns a :class:ClusterResult. Every algorithm accepts a seed for reproducibility.

ClusterResult dataclass

Outcome of a fuzzy clustering run.

Attributes:

Name Type Description
centers ndarray

cluster prototypes, shape (c, n_features).

u ndarray

membership/typicality matrix, shape (c, n_samples).

n_iter int

iterations run until convergence.

objective float

final value of the algorithm's objective function.

labels ndarray

hard assignment argmax over u, shape (n_samples,).

fuzzy_cmeans

fuzzy_cmeans(X: ndarray, c: int, m: float = 2.0, max_iter: int = 150, tol: float = 1e-05, seed: int | None = None) -> ClusterResult

Bezdek's fuzzy c-means.

Parameters:

Name Type Description Default
X ndarray

data, shape (n_samples, n_features).

required
c int

number of clusters.

required
m float

fuzziness exponent (> 1; 2.0 is standard).

2.0
max_iter int

maximum iterations.

150
tol float

stop when the membership matrix changes by less than this (max-norm).

1e-05
seed int | None

RNG seed for the membership initialization.

None

gustafson_kessel

gustafson_kessel(X: ndarray, c: int, m: float = 2.0, max_iter: int = 150, tol: float = 1e-05, seed: int | None = None, reg: float = 1e-10) -> ClusterResult

Gustafson-Kessel clustering (adaptive per-cluster Mahalanobis norm).

Each cluster learns a covariance-shaped, unit-determinant norm, so GK fits ellipsoidal clusters that FCM (fixed spherical norm) cannot.

Parameters:

Name Type Description Default
X ndarray

data, shape (n_samples, n_features).

required
c int

number of clusters.

required
m float

fuzziness exponent (> 1).

2.0
max_iter int

maximum iterations.

150
tol float

convergence threshold on the membership matrix (max-norm).

1e-05
seed int | None

RNG seed for initialization.

None
reg float

ridge added to each fuzzy covariance for numerical stability.

1e-10

possibilistic_cmeans

possibilistic_cmeans(X: ndarray, c: int, m: float = 2.0, max_iter: int = 150, tol: float = 1e-05, seed: int | None = None, k: float = 1.0) -> ClusterResult

Possibilistic c-means (Krishnapuram-Keller).

PCM drops the probabilistic constraint that memberships sum to 1: each value is a typicality in [0, 1], so noise points score low everywhere. It is initialized from an FCM run, which also fixes each cluster's scale eta.

Parameters:

Name Type Description Default
X ndarray

data, shape (n_samples, n_features).

required
c int

number of clusters.

required
m float

fuzziness exponent (> 1).

2.0
max_iter int

maximum iterations.

150
tol float

convergence threshold on the typicality matrix (max-norm).

1e-05
seed int | None

RNG seed (passed to the initializing FCM).

None
k float

scale multiplier for the bandwidth eta (1.0 is standard).

1.0

partition_coefficient

partition_coefficient(u: ndarray) -> float

Bezdek's partition coefficient in (1/c, 1]; higher = crisper.

partition_entropy

partition_entropy(u: ndarray) -> float

Partition entropy in [0, log c); lower = crisper.

xie_beni

xie_beni(X, centers: ndarray, u: ndarray, m: float = 2.0) -> float

Xie-Beni index (compactness / separation); lower is better.

ANFIS

fuzzytool.anfis

ANFIS — an adaptive network-based fuzzy inference system (Jang, 1993).

ANFIS is a first-order Takagi-Sugeno system whose parameters are learned from data. With a grid partition, each of the p inputs carries n_mf Gaussian membership functions, giving n_mf ** p rules; rule i fires with the product of its inputs' memberships and emits an affine function of the inputs.

Training uses Jang's hybrid scheme, one pass per epoch:

  1. with the premise (Gaussian) parameters fixed, the consequent (affine) parameters are solved in closed form by least squares — the output is linear in them;
  2. with the consequents fixed, the premise centers and widths take a gradient-descent step on the mean squared error.

Pure NumPy; intended for low-dimensional problems (the rule count grows as n_mf ** p).

ANFIS

A trainable first-order Sugeno system over a grid partition.

Parameters:

Name Type Description Default
n_inputs int

number of input features p.

required
n_mf int

Gaussian membership functions per input (rules = n_mf ** p).

3
learning_rate float

step size for the premise gradient updates.

0.05

fit

fit(X, y, epochs: int = 100) -> ANFIS

Train on X (n, p) and targets y (n,) for epochs epochs.

predict

predict(X) -> np.ndarray

Predict outputs for X (n, p). Requires a prior :meth:fit.

get_params

get_params(deep: bool = True) -> dict

Hyperparameters, for scikit-learn compatibility (Pipeline/GridSearch).

set_params

set_params(**params) -> ANFIS

Set hyperparameters (resets trained state), returning self.

F-transform

fuzzytool.ftransform

F-transform — the fuzzy transform of Perfilieva.

The F-transform projects a function onto a fuzzy partition of its domain. Over a uniform partition by triangular basis functions A_1..A_n that satisfy the Ruspini condition (they sum to 1 everywhere on [a, b]):

  • the direct transform reduces the data to n components, each a membership-weighted average of the samples falling under one basis function;
  • the inverse transform reconstructs an approximation f̂(x) = Σ_k F_k · A_k(x).

With few components the round trip smooths/denoises a signal; with many it approximates it closely. Pure NumPy.

FTransform

A triangular F-transform over a uniform fuzzy partition of [a, b].

Parameters:

Name Type Description Default
a float

left end of the domain.

required
b float

right end of the domain (b > a).

required
n_basis int

number of basis functions / components (>= 2).

required

basis

basis(x) -> np.ndarray

Triangular basis matrix A of shape (len(x), n_basis).

Columns form a partition of unity on [a, b] (each row sums to 1).

direct

direct(x, y) -> np.ndarray

Direct F-transform: the n_basis components from samples (x, y).

inverse

inverse(x, components: ndarray | None = None) -> np.ndarray

Inverse F-transform: reconstruct values at x from components.

fit

fit(x, y) -> FTransform

Compute and store the direct transform of (x, y); returns self.

smooth

smooth(x) -> np.ndarray

Convenience: direct-then-inverse at x (requires a prior fit).

Visualization

fuzzytool.viz

Matplotlib visualization helpers.

Importing this module requires matplotlib (an optional dependency; install with pip install fuzzytool[viz]). Visualization is a first-class priority of the project, mirroring its sibling turboswarm.

plot_variable

plot_variable(variable: Variable, ax=None)

Plot every term's membership function over the variable's universe.

plot_it2_variable

plot_it2_variable(variable: Variable, ax=None)

Plot an IT2 variable: each term's lower/upper MF with a shaded FOU.

Type-1 terms (if any are mixed in) are drawn as a single line.

control_surface

control_surface(system, x_var: Variable, y_var: Variable, n: int = 41, ax=None)

Plot a system's output as a surface over two input variables.

system must be callable as system(**{x_var.name: x, y_var.name: y}) and return a scalar (single-output Mamdani or TSK).

plot_clusters

plot_clusters(X, result, ax=None)

Scatter 2-D data colored by hard label, with cluster centers marked.

result is a :class:~fuzzytool.cluster.ClusterResult. Point opacity encodes the top membership, so fuzzy/boundary points appear fainter.

Integrations — pandas

fuzzytool.integrations.pandas

pandas integration: DataFrame in/out and tabular views of fuzzy objects.

Install with pip install fuzzytool[pandas]. Nothing here imports pandas at module load beyond a guarded check, so the rest of the toolkit stays dependency -free.

  • :func:predict_df — batch inference straight from a DataFrame.
  • :func:rules_dataframe — a readable table of a system's rule base.
  • :func:memberships_dataframe — a clustering result's membership matrix.
  • :func:components_dataframe — an F-transform's components.

predict_df

predict_df(system: Mamdani | TSK, df: DataFrame, columns: list[str] | None = None) -> pd.Series | pd.DataFrame

Run vectorized inference over a DataFrame.

Parameters:

Name Type Description Default
system Mamdani | TSK

a :class:~fuzzytool.inference.Mamdani or :class:~fuzzytool.inference.TSK system.

required
df DataFrame

a DataFrame whose columns include the system's input variables.

required
columns list[str] | None

input column names to use, in order. Defaults to the variables the system's rules reference (see :func:~fuzzytool.integrations._util.input_variable_names).

None

Returns:

Type Description
Series | DataFrame

A Series (single output, named after the output variable) or a

Series | DataFrame

DataFrame (multiple outputs), aligned to df's index.

rules_dataframe

rules_dataframe(system)

Return the system's rule base as a DataFrame (one row per rule).

Columns: antecedent (the IF part as text), consequent (the THEN part) and weight.

memberships_dataframe

memberships_dataframe(result, index=None, prefix: str = 'cluster')

Return a clustering result's membership matrix as a DataFrame.

One row per sample, one column {prefix}_{k} per cluster, plus a label column holding the hard (argmax) assignment.

components_dataframe

components_dataframe(ftransform)

Return an :class:~fuzzytool.ftransform.FTransform's components as a DataFrame.

Columns: node (the basis-function center) and component (its value).

Integrations — scikit-learn

fuzzytool.integrations.sklearn

scikit-learn integration: fuzzy systems as estimators and transformers.

These objects follow the scikit-learn estimator protocol (fit returns self, plus predict/transform, get_params/set_params and a score/fit_transform), so they slot into a Pipeline, GridSearchCV or cross_val_score — yet, like :class:~fuzzytool.anfis.ANFIS, they do not import scikit-learn. The [sklearn] extra simply installs scikit-learn so you have those tools available:

pip install fuzzytool[sklearn]
  • :class:Fuzzifier — a transformer turning crisp features into fuzzy membership-degree features (one column per term).
  • :class:WangMendelRegressor — learns a Mamdani rule base from data (Wang-Mendel) and predicts with it.
  • :class:FuzzySystemRegressor — wraps an already-built Mamdani/TSK system so it can be scored or pipelined.

Fuzzifier

Bases: _Estimator

Expand crisp features into fuzzy membership-degree features.

Column j of X is interpreted through variables[j]: each of that variable's terms becomes one output column holding the membership degree. The result is a soft, interpretable encoding that downstream linear or tree models can consume.

Parameters:

Name Type Description Default
variables list[Variable]

one :class:~fuzzytool.sets.Variable per input column, in column order.

required

WangMendelRegressor

Bases: _Estimator

A regressor that learns a Mamdani rule base from data (Wang-Mendel).

Parameters:

Name Type Description Default
inputs list[Variable]

input linguistic variables (pre-populated with terms), one per column of X.

required
output Variable

the output linguistic variable (pre-populated with terms).

required

FuzzySystemRegressor

Bases: _Estimator

Wrap an already-built single-output fuzzy system as an sklearn regressor.

fit does not change the system (it is already defined); it only records the input column order. Use this to cross-validate, score, or pipeline a hand-written Mamdani/TSK system.

Parameters:

Name Type Description Default
system Mamdani | TSK

a single-output Mamdani or TSK system.

required
columns list[str] | None

input variable names matching X's columns, in order. Defaults to the variables the system's rules reference.

None

Integrations — SciPy

fuzzytool.integrations.scipy

SciPy integration: tune a fuzzy system's membership functions to data.

Install with pip install fuzzytool[scipy]. :func:tune adjusts the parameters of a system's built-in membership functions so its output fits a dataset, using :func:scipy.optimize.least_squares. It mutates the system in place and returns SciPy's OptimizeResult (.x, .cost, .nfev, .success …) — a drop-in way to refine a hand-written Mamdani/TSK system.

Only built-in membership shapes (tri, trap, gauss, gbell, sigmoid, ramp_up, ramp_down) are tunable; custom callables are left untouched. Shape validity is preserved every iteration (breakpoints are kept ordered, widths kept positive), so the optimizer explores freely without producing degenerate sets.

tune

tune(system: Mamdani | TSK, X: ndarray, y: ndarray, columns: list[str] | None = None, tune_outputs: bool = True, **least_squares_kwargs) -> OptimizeResult

Fit a system's membership-function parameters to data.

Any extra keyword arguments are forwarded to :func:scipy.optimize.least_squares (e.g. max_nfev).

Parameters:

Name Type Description Default
system Mamdani | TSK

a Mamdani or TSK system (mutated in place with the best params).

required
X ndarray

inputs, shape (n_samples, n_inputs).

required
y ndarray

targets, shape (n_samples,).

required
columns list[str] | None

input variable names matching X's columns, in order. Defaults to the variables the rules reference.

None
tune_outputs bool

also tune the output variables' MFs (Mamdani only).

True

Returns:

Type Description
OptimizeResult

The SciPy OptimizeResult.

Integrations — turboswarm (PSO)

fuzzytool.integrations.turboswarm

turboswarm integration: tune a fuzzy system with Particle Swarm Optimization.

Install with pip install fuzzytool[turboswarm]. :func:tune fits the parameters of a system's built-in membership functions to data with turboswarm <https://pypi.org/project/turboswarm/>_'s PSO — a gradient-free, global optimizer. It is the metaheuristic sibling of :func:fuzzytool.integrations.scipy.tune (local least-squares): slower, but it escapes poor local optima and needs no derivatives, which suits the rugged, non-smooth error surfaces fuzzy rule bases often produce.

Each parameter is searched within a box of ±margin × universe around its current value; shape validity (ordered breakpoints, positive widths) is enforced every evaluation, so the swarm explores freely. The system is mutated in place with the best parameters found and the turboswarm PsoResult is returned.

tune

tune(system: Mamdani | TSK, X: ndarray, y: ndarray, columns: list[str] | None = None, tune_outputs: bool = True, margin: float = 0.5, n_particles: int = 30, max_iter: int = 100, seed: int | None = None, **minimize_kwargs) -> PsoResult

Fit a system's membership-function parameters to data with PSO.

Extra keyword arguments are forwarded to :func:turboswarm.minimize (e.g. topology, patience, max_time).

Parameters:

Name Type Description Default
system Mamdani | TSK

a Mamdani or TSK system (mutated in place with the best params).

required
X ndarray

inputs, shape (n_samples, n_inputs).

required
y ndarray

targets, shape (n_samples,).

required
columns list[str] | None

input variable names matching X's columns, in order. Defaults to the variables the rules reference.

None
tune_outputs bool

also tune the output variables' MFs (Mamdani only).

True
margin float

search half-width per parameter as a fraction of its variable's universe span (0.5 searches ±50% of the span around each value).

0.5
n_particles int

swarm size.

30
max_iter int

PSO iterations.

100
seed int | None

PSO seed for reproducibility.

None

Returns:

Type Description
PsoResult

The turboswarm PsoResult (.best_position, .best_value, …).

Integrations — Optuna

fuzzytool.integrations.optuna

Optuna integration: search fuzzy-system structure and hyperparameters.

Install with pip install fuzzytool[optuna]. Fuzzy systems have plenty of discrete/continuous knobs — which t-norm, which defuzzifier, how many membership functions, what learning rate — that are awkward to grid-search by hand. These helpers turn an Optuna trial into a configured system, plus a ready-made :func:tune_anfis study.

  • :func:suggest_inference_spec — sample the connectives/implication/defuzz of a Mamdani system from a trial.
  • :func:suggest_anfis — build an :class:~fuzzytool.anfis.ANFIS with a trial-suggested n_mf and learning_rate.
  • :func:tune_anfis — run a full study that minimizes training RMSE and returns the best (refit) model.

suggest_inference_spec

suggest_inference_spec(trial, prefix: str = '') -> dict

Sample a Mamdani spec {tnorm, snorm, implication, defuzz} from a trial.

prefix namespaces the parameter names so several specs can coexist in one study. Pass the result straight to :class:~fuzzytool.inference.Mamdani.

suggest_anfis

suggest_anfis(trial, n_inputs: int, n_mf_range: tuple[int, int] = (2, 5), lr_range: tuple[float, float] = (0.001, 0.2)) -> ANFIS

Build an ANFIS with a trial-suggested n_mf and learning_rate.

tune_anfis

tune_anfis(X: ndarray, y: ndarray, n_trials: int = 20, n_mf_range: tuple[int, int] = (2, 5), lr_range: tuple[float, float] = (0.001, 0.2), epochs: int = 100, seed: int | None = None) -> tuple

Tune an ANFIS's n_mf/learning_rate with an Optuna study.

Parameters:

Name Type Description Default
X ndarray

inputs, shape (n_samples, n_inputs).

required
y ndarray

targets, shape (n_samples,).

required
n_trials int

number of Optuna trials.

20
n_mf_range tuple[int, int]

(min, max) membership functions per input to search.

(2, 5)
lr_range tuple[float, float]

(min, max) learning rate to search (log scale).

(0.001, 0.2)
epochs int

training epochs per trial.

100
seed int | None

seed for Optuna's sampler (reproducible search).

None

Returns:

Type Description
tuple

A (best_model, study) tuple: a fresh ANFIS trained with the best

tuple

hyperparameters, and the Optuna study.

Integrations — Joblib / Dask

fuzzytool.integrations.parallel

Parallel execution helpers (Joblib and Dask).

Install with pip install fuzzytool[parallel] (Joblib) or fuzzytool[dask] (Dask). These spread embarrassingly-parallel fuzzy workloads across cores or a Dask cluster:

  • :func:parallel_predict — chunked batch inference with Joblib.
  • :func:multi_start_cmeans — run fuzzy c-means from many seeds in parallel and keep the best (FCM is sensitive to initialization).
  • :func:dask_predict — the same chunked inference on a Dask scheduler.

.. note:: The process backends pickle the system. A hand-written Mamdani/TSK built from the built-in shapes pickles fine; a TSK with lambda consequents does not — pass backend="threading" for those.

parallel_predict

parallel_predict(system: Mamdani | TSK, X: ndarray, columns: list[str] | None = None, n_jobs: int = -1, n_chunks: int | None = None, backend: str = 'loky') -> np.ndarray | dict

Run batch inference over X in parallel chunks with Joblib.

Parameters:

Name Type Description Default
system Mamdani | TSK

a Mamdani or TSK system.

required
X ndarray

inputs, shape (n_samples, n_inputs).

required
columns list[str] | None

input variable names matching X's columns, in order. Defaults to the variables the rules reference.

None
n_jobs int

Joblib worker count (-1 = all cores).

-1
n_chunks int | None

number of row chunks (defaults to 4 * n_jobs or 8).

None
backend str

Joblib backend ("loky" processes, "threading" threads).

'loky'

Returns:

Type Description
ndarray | dict

The stacked predictions — an array (single output) or a dict of arrays.

multi_start_cmeans

multi_start_cmeans(X: ndarray, c: int, n_starts: int = 8, n_jobs: int = -1, backend: str = 'loky', **kwargs) -> ClusterResult

Run :func:~fuzzytool.cluster.fuzzy_cmeans from many seeds; keep the best.

Fuzzy c-means converges to a local optimum that depends on initialization; running several seeds and keeping the lowest-objective result is a standard safeguard. The runs are independent, so they parallelize cleanly. Extra keyword arguments are forwarded to :func:~fuzzytool.cluster.fuzzy_cmeans.

Parameters:

Name Type Description Default
X ndarray

data, shape (n_samples, n_features).

required
c int

number of clusters.

required
n_starts int

number of random restarts (seeds 0 .. n_starts - 1).

8
n_jobs int

Joblib worker count (-1 = all cores).

-1
backend str

Joblib backend.

'loky'

Returns:

Type Description
ClusterResult

The best :class:~fuzzytool.cluster.ClusterResult (minimum objective).

dask_predict

dask_predict(system: Mamdani | TSK, X: ndarray, columns: list[str] | None = None, n_chunks: int | None = None) -> np.ndarray | dict

Run chunked batch inference on a Dask scheduler.

Mirrors :func:parallel_predict but builds a Dask graph (dask.delayed) and computes it, so it scales to a distributed cluster.

Parameters:

Name Type Description Default
system Mamdani | TSK

a Mamdani or TSK system.

required
X ndarray

inputs, shape (n_samples, n_inputs).

required
columns list[str] | None

input variable names matching X's columns.

None
n_chunks int | None

number of row chunks (default 8).

None

Returns:

Type Description
ndarray | dict

The stacked predictions — an array or a dict of arrays.

Integrations — LLM agents

fuzzytool.integrations.agents

LLM-agent integration: expose a fuzzy system as an explainable tool.

Install with pip install fuzzytool[agents]. A fuzzy inference system is an unusually good citizen for tool-using LLMs: it is deterministic, bounded, and — unlike a black-box model — it can say why it produced an answer by reporting which rules fired and how strongly.

  • :func:explain — run a system and return its crisp output plus the fired rules (no third-party dependency; useful on its own).
  • :func:inference_tool — wrap a system as a LangChain StructuredTool an agent can call.

explain

explain(system, **inputs) -> dict

Run system on inputs and explain the result.

Returns a dict with the crisp output (a float, or a dict for a multi-output Mamdani) and fired_rules: the rules whose firing strength is positive, each {"rule", "firing"}, sorted strongest-first. This is the payload an agent (or a human) needs to trust the answer.

inference_tool

inference_tool(system: Mamdani | TSK, columns: list[str] | None = None, name: str = 'fuzzy_inference', description: str | None = None) -> StructuredTool

Wrap a fuzzy system as a LangChain StructuredTool.

The tool takes one float argument per input variable and returns the crisp output together with the rules that fired — so the agent can both use and explain the system.

Parameters:

Name Type Description Default
system Mamdani | TSK

a Mamdani or TSK system.

required
columns list[str] | None

input variable names (the tool's arguments). Defaults to the variables the rules reference.

None
name str

tool name exposed to the agent.

'fuzzy_inference'
description str | None

tool description; a sensible default is generated.

None

Returns:

Type Description
StructuredTool

A langchain_core.tools.StructuredTool.

Datasets

fuzzytool.datasets

Ready-made example systems.

credit_risk

credit_risk() -> tuple[Mamdani, Variable, Variable, Variable]

A credit-risk-premium Mamdani system.

Given a borrower's credit score (300-850) and dti (debt-to-income ratio, 0-50%), recommend the premium (risk points, 0-12) a lender should add on top of its base interest rate. Returns (system, score, dti, premium) so callers can inspect the variables (e.g. for plotting).

sys, score, dti, premium = credit_risk() safe = sys(score=800, dti=10) # great score, low leverage risky = sys(score=520, dti=42) # poor score, high leverage safe < risky True

credit_risk_it2

credit_risk_it2() -> tuple[IT2Mamdani, Variable, Variable, Variable]

An interval type-2 version of :func:credit_risk.

The score and premium terms carry a footprint of uncertainty (uncertain Gaussian means), modeling vagueness in how a "good" score or a "low" premium is defined. Returns (system, score, dti, premium).

sys, score, dti, premium = credit_risk_it2() sys(score=800, dti=10) < sys(score=520, dti=42) True

make_blobs

make_blobs(centers=((0.0, 0.0), (6.0, 6.0), (0.0, 6.0)), n_per: int = 60, spread: float = 0.7, seed: int | None = 0) -> np.ndarray

Synthetic isotropic Gaussian blobs for clustering demos and tests.

Returns the stacked data X of shape (len(centers) * n_per, n_features).

X = make_blobs(seed=0) X.shape (180, 2)