bulanik.scales
scales ¶
Linguistic scales: named terms mapped to fuzzy numbers.
A LinguisticScale turns the words experts use
("high", "very important") into fuzzy numbers of one type, so that rating
tables written as strings can be converted with
convert before aggregation.
Built-in scales: SAATY_TFN (Saaty's 1-9 values as
triangles) and FUZZY_BWM_TFN (the best-worst
method scale of Guo and Zhao). Besides these, the built-ins
EXAMPLE_IFN_5,
EXAMPLE_IFN_7 and
EXAMPLE_TFN_7 are example scales: illustrative
values shipped without attribution (source=None).
Examples:
>>> from bulanik.scales import SAATY_TFN
>>> SAATY_TFN["3"]
TFN(l=2.0, m=3.0, u=4.0)
SAATY_TFN
module-attribute
¶
SAATY_TFN = LinguisticScale('Saaty 1-9 triangular scale', {'1': TFN(1, 1, 1), **{str(k): TFN(k - 1, k, k + 1) for k in range(2, 9)}, '9': TFN(9, 9, 9)}, source='Saaty 1980 (crisp 1-9 values); the +/-1 triangular spread is a common convention')
Saaty's 1-9 scale as triangular numbers: "1" = (1,1,1), "k" = (k-1,k,k+1)
for k = 2..8, "9" = (9,9,9). The crisp 1-9 values are from Saaty (1980); the +/-1
triangular spread is a common convention with no single canonical source.
FUZZY_BWM_TFN
module-attribute
¶
FUZZY_BWM_TFN = LinguisticScale('fuzzy BWM linguistic scale', {'EI': TFN(1, 1, 1), 'WI': TFN(2 / 3, 1, 3 / 2), 'FI': TFN(3 / 2, 2, 5 / 2), 'VI': TFN(5 / 2, 3, 7 / 2), 'AI': TFN(7 / 2, 4, 9 / 2)}, source='Guo & Zhao 2017, Knowledge-Based Systems 121:23-31')
The fuzzy best-worst method scale of Guo and Zhao (2017, Knowledge-Based Systems
121:23-31): equally (EI), weakly (WI), fairly (FI), very (VI) and absolutely (AI)
important, as triangular numbers. Their consistency indices are given by
fuzzy_bwm_consistency_index
(3.00, 3.80, 5.29, 6.69, 8.04).
EXAMPLE_IFN_5
module-attribute
¶
EXAMPLE_IFN_5 = LinguisticScale('example IFN 5-term scale', {'VL': IFN(0.1, 0.8), 'L': IFN(0.3, 0.6), 'M': IFN(0.5, 0.4), 'H': IFN(0.7, 0.2), 'VH': IFN(0.9, 0.05)})
Example 5-term intuitionistic scale (VL, L, M, H, VH); illustrative values with no source.
EXAMPLE_IFN_7
module-attribute
¶
EXAMPLE_IFN_7 = LinguisticScale('example IFN 7-term scale', {'EL': IFN(0.05, 0.9), 'VL': IFN(0.15, 0.8), 'L': IFN(0.3, 0.6), 'M': IFN(0.5, 0.4), 'H': IFN(0.7, 0.25), 'VH': IFN(0.85, 0.1), 'EH': IFN(0.95, 0.05)})
Example 7-term intuitionistic scale (EL, VL, L, M, H, VH, EH); illustrative values with no source.
EXAMPLE_TFN_7
module-attribute
¶
EXAMPLE_TFN_7 = LinguisticScale('example TFN 7-term scale', {'VP': TFN(0, 0, 1), 'P': TFN(0, 1, 3), 'MP': TFN(1, 3, 5), 'F': TFN(3, 5, 7), 'MG': TFN(5, 7, 9), 'G': TFN(7, 9, 10), 'VG': TFN(9, 10, 10)})
Example 7-term triangular rating scale on 0-10 (VP, P, MP, F, MG, G, VG); illustrative values with no source.
LinguisticScale ¶
LinguisticScale(name: str, terms: Mapping[str, FuzzyNumber], source: str | None = None)
An ordered set of linguistic terms, all fuzzy numbers of one type.
Terms are looked up with scale["term"] and tested with "term" in scale;
the term order is the insertion order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A descriptive name of the scale. |
required |
terms
|
Mapping[str, FuzzyNumber]
|
Mapping from term name to fuzzy number; all numbers must be of the same class (and rung). |
required |
source
|
str | None
|
Where the values come from, or |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
TypeError
|
If a term is not a fuzzy number, or the numbers mix types. |
Attributes:
| Name | Type | Description |
|---|---|---|
name |
The scale name. |
|
source |
The attribution string, or |
|
number_type |
type
|
The class shared by all term numbers. |
Examples:
>>> from bulanik import TFN
>>> from bulanik.scales import LinguisticScale
>>> s = LinguisticScale("mine", {"low": TFN(0, 0, 5), "high": TFN(5, 10, 10)})
>>> s.terms
('low', 'high')
>>> s["high"]
TFN(l=5.0, m=10.0, u=10.0)
>>> "low" in s
True
>>> s.number_type.__name__
'TFN'
convert ¶
convert(nested: Any) -> Any
Map term strings at any list depth to their numbers (lists stay lists).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nested
|
Any
|
A term name, or a list or tuple of them, nested to any depth. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The number for a term name; a list with the same nesting otherwise |
Any
|
(tuples become lists). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If an item is neither a string nor a list or tuple. |
KeyError
|
If a term name is not in the scale. |
Examples:
>>> from bulanik.scales import SAATY_TFN
>>> SAATY_TFN.convert([["1", "9"], "5"])
[[TFN(l=1.0, m=1.0, u=1.0), TFN(l=9.0, m=9.0, u=9.0)], TFN(l=4.0, m=5.0, u=6.0)]
reciprocal ¶
reciprocal(term: str) -> TFN
Reciprocal of a term's number (TFN scales only).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
term
|
str
|
A term name. |
required |
Returns:
| Type | Description |
|---|---|
TFN
|
The reciprocal |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the scale does not hold |
KeyError
|
If the term does not exist. |
ValueError
|
If the support of the term's number contains 0. |
Examples:
>>> from bulanik.scales import SAATY_TFN
>>> r = SAATY_TFN.reciprocal("3")
>>> round(r.l, 4), round(r.m, 4), round(r.u, 4)
(0.25, 0.3333, 0.5)