历史通用模糊标度¶
Universal Fuzzy Scale(通用模糊标度)是 FuzzyRoutines 的历史五级预设:
Min → Low → Med → High → Max(最低、低、中、高、最高)。本例保留原始系数,
并展示如何用现代不可变 API 重建同一分类器。“通用”是历史名称,并不表示这些参数
适用于所有应用。它不是默认的三级 FuzzyScale,也不是五个等间距三角形。
左图使用历史接口计算,右图使用现代接口计算。 Min 在 0.125 附近快速下降,Low、Med、High 具有平顶和二次曲线肩部, Max 在 0.77 到 0.95 之间上升。Min 的微小正尾部仍然存在,只是在图上难以分辨。
网络安全与风险等级¶
该标度可将归一化评分映射为语言等级,用于网络安全与风险评估,例如资产风险、
安全问题的严重程度或防护措施的有效性。首先应明确如何将观测数据或专家评价转换为
[0, 1] 内的评分,以及评分增大所表示的含义。风险升高与防护能力增强对决策的意义
相反,即使两者都采用 Min、Low、Med、High 和 Max 五个等级。
例如,设风险评分为 0.75,历史标度选出的等级为 High,其隶属度为 1。
这表示在该模型中完全隶属于 High;这两个数值均不表示安全事件的发生概率。
应在保留所选等级的同时保留各等级的隶属度,以反映等级之间的过渡。
归一化、评价聚合及响应规则应根据具体应用制定,并依据领域数据进行验证;
对弱覆盖区域也应显式处理,具体方法见下文。该标度用于对输入评分作语言解释,
本身并不构成风险度量方法,也不规定安全事件响应策略。
原始定义¶
| 级别 | 历史函数族 / 现代构造函数 | 历史 supportSet |
|---|---|---|
| Min | hyperbolic / Hyperbolic(8, 20, 0) |
[0, 0.23] |
| Low | bell / Bell(0.17, 0.23, 0.34) |
[0.17, 0.40] |
| Med | bell / Bell(0.34, 0.40, 0.60) |
[0.34, 0.66] |
| High | bell / Bell(0.60, 0.66, 0.77) |
[0.60, 0.83] |
| Max | parabolic / SShoulder(0.77, 0.95) |
[0.77, 1] |
此处的 supportSet 是历史质心计算的有限积分区间。
UniversalFuzzyScale.Fuzzy(x) 直接调用 mFunction.mju(x),不会按该区间截断函数。
例如,Min 在 0.23 之后仍为正。因此现代重建为所有项指定共同的闭论域 [0,1]。
把五个历史积分区间分别当成各项论域会改变行为,且多数输入无法完成分类。
对归一化坐标 \(0\le x\le1\),先定义二次上升肩函数:
钟形函数的右端点为 \(c+b-a\),核为整个区间 \([b,c]\)。 隶属度之和不一定为 1,也不是概率。示例与绘图测试使用这些独立公式核对数值。
历史接口的用法¶
from math import isclose
from fuzzyroutines.FuzzyRoutines import UniversalFuzzyScale
scale = UniversalFuzzyScale()
assert [level["name"] for level in scale.levels] == ["Min", "Low", "Med", "High", "Max"]
grades = {level["name"]: level["fSet"].mFunction.mju(0.2) for level in scale.levels}
assert isclose(grades["Low"], 0.5)
assert scale.Fuzzy(0.2)["name"] == "Low"
assert scale.GetLevelByName("Med")["fSet"].supportSet == (0.34, 0.66)
assert scale.GetLevelByName("Min")["fSet"].mFunction.mju(0.5) > 0
print(grades, scale.Fuzzy(0.2)["name"])
兼容接口保留旧名称与构造方式。本例在 2.0 中执行,并不承诺保留 1.0.3 中的数值错误。 质心修正参见迁移说明。
使用现代 API 显式构造¶
from math import isclose
from fuzzyroutines import (
Bell, ContinuousUniverse, FuzzificationPolicy, Hyperbolic,
LinguisticScale, LinguisticTerm, ScalarFuzzySet, SShoulder,
)
from fuzzyroutines.FuzzyRoutines import UniversalFuzzyScale
universe = ContinuousUniverse(0, 1, leftClosed=True, rightClosed=True)
models = (
("Min", Hyperbolic(8, 20, 0)),
("Low", Bell(0.17, 0.23, 0.34)),
("Med", Bell(0.34, 0.40, 0.60)),
("High", Bell(0.60, 0.66, 0.77)),
("Max", SShoulder(0.77, 0.95)),
)
scale = LinguisticScale(tuple(
LinguisticTerm(name, ScalarFuzzySet(universe, model))
for name, model in models
))
legacy = UniversalFuzzyScale()
policy = FuzzificationPolicy(tiePolicy="last", tieTolerance=0)
for coordinate in (0, 0.125, 0.17, 0.2, 0.37, 0.5, 0.63, 0.81, 0.86, 1):
result = scale.Fuzzify(coordinate, policy)
for item, previous in zip(result.memberships, legacy.levels, strict=True):
assert isclose(item.grade, previous["fSet"].mFunction.mju(coordinate), abs_tol=1e-12)
assert result.selectedTerms[0].name == legacy.Fuzzy(coordinate)["name"]
assert isclose(scale.Fuzzify(0.125).confidence, 0.5)
assert not scale.Fuzzify(0.17, FuzzificationPolicy(minimumConfidence=0.1)).isMatch
assert not scale.Fuzzify(0.125, FuzzificationPolicy(minimumConfidence=0.5)).isMatch
print([(item.term.name, item.grade) for item in scale.Fuzzify(0.2).memberships])
历史 parabolic 对应现代 SShoulder,并非无限延伸的抛物线。
保留项的顺序并设置 tiePolicy="last",才能在最大值精确相等时选择后面的项。
现代默认策略选择第一个精确最大值,因此迁移时必须显式指定策略。
数值、边界与决策¶
| 坐标 | 结果 / 隶属度 |
|---|---|
| 0 | Min = 1;包含左端点 |
| 0.125 | Min = 0.5 |
| 0.17 | Min ≈ 0.002129589894;Low = 0,覆盖较弱 |
| 0.20 | Low = 0.5;Min ≈ 0.000082711220 |
| 0.50 | Med = 1;Min ≈ 9.094947018 × 10⁻¹³ |
| 0.81 | High ≈ 2/9,Max ≈ 8/81;选择 High |
| 0.86 | Max ≈ 0.5 |
| 1 | Max = 1;包含右端点 |
Min 与 Low 之间的弱覆盖来自历史系数,本例不调整参数。
在 0.17 处,历史分类器选择 Min,而现代策略 minimumConfidence=0.1 返回无匹配。
最大隶属度等于阈值时也返回无匹配:必须严格大于阈值。
该阈值不是分类正确的概率。
在精确实数运算中,相邻钟形函数在 0.37 和 0.63 处相等。
但浮点计算在 0.37 处得到 Low ≈ 0.5000000000000009、Med ≈ 0.4999999999999991,
所以历史选择为 Low。tieTolerance=0 保留精确比较;正容差会有意改变近似并列的处理方式。
现代示例拒绝 [0,1] 之外的输入。历史接口仍计算其他有限坐标,例如 −0.1 选择 Min,
1.1 选择 Max。应显式校验与归一化物理量,不要静默截断。
若要重现历史质心,也必须使用各级原有积分区间,不能统一改成 [0,1]。
复现与验证¶
python examples/guide.py --scenario universal-fuzzy-scale
示例在 1001 个坐标 0, 0.001, …, 1 上用独立公式核对两种 API,
并验证标签、阈值拒绝与 Min 的正尾部。绘图测试逐一核对十条曲线各自的 401 个坐标。
有限网格提供回归证据,不构成对所有实数的证明。参见图形复现
与历史参数记录。