模糊聚类允许每个数据点以不同的隶属度属于多个簇。它不再简单地将一个点硬性分配给某一个组,而是捕捉该点与每个簇的关联强度。
- 使用介于 0 和 1 之间的隶属度分数
- 能够处理重叠或界限不清的簇边界
- 比硬聚类方法更加灵活
- 当数据点不能整齐地归入单一组别时非常有用
!Fuzzy-硬聚类 vs 模糊聚类
模糊聚类的工作原理
模糊聚类会为每个数据点分配属于每个簇的隶属度,并通过迭代过程更新这些值。下面让我们来看看它是如何工作的:
第1步:随机初始化隶属度值: 为每个数据点针对所有簇分配随机的隶属度分数。一个点可以部分地属于多个簇。
例如,对于 2 个簇和 4 个数据点,一个初始化的隶属度矩阵 (\gamma) 可能如下所示:
(1,3)
(4,8)
—
—
0.8
0.2
0.2
0.8
第2步:计算簇质心: 质心是作为加权平均值计算的,其中的权重是隶属度值的模糊参数 m 次方:
> V{ij} = \frac{\sum{k=1}^{n} \gamma{ik}^m \cdot x{kj}} {\sum{k=1}^{n} \gamma{ik}^m}
其中:
- \gamma_{ik} = 点 k 在簇 i 中的隶属度。
- m = 模糊度参数(通常为 2)。
- x_{kj} = 点 k 在特征 j 上的值。
第3步:计算数据点与质心之间的距离: 计算每个点与每个质心之间的欧几里得距离,以确定接近程度,这将用于更新隶属度。以点 (1,3) 为例:
> D_{11} = \sqrt{(1 – 1.568)^2 + (3 – 4.051)^2} = 1.2
>
> D_{12} = \sqrt{(1 – 5.35)^2 + (3 – 8.215)^2} = 6.79
类似地,计算所有其他点到这两个质心的距离。
第4步:更新隶属度值: 隶属度值会根据这些距离进行反比例更新。距离质心越近的点,其隶属度越高。
点 k 在簇 i 中更新后的隶属度 \gamma_{ik} 为:
> \gamma = \sum \limits1^n {(d{ki}^2 /d_{kj}^2)}^{1/m-1} ]^{-1}
第5步:重复直到收敛: 重复步骤 2–4,直到隶属度值趋于稳定,这意味着下一次迭代与上一次相比没有显著变化。这表明聚类已达到最佳状态。
模糊聚类的实现
用于机器学习的模糊 scikit learn 库具有预定义的模糊 C 均值函数,可以在 Python 中使用。为了使用模糊 C 均值,我们需要安装 skfuzzy 库。
> pip install scikit-fuzzy
第1步:导入必要的库
我们将使用 numpy 进行数值运算,使用 skfuzzy 实现 Fuzzy C-Means 聚类算法,并使用 matplotlib 绘制结果。
Python
CODEBLOCK_b3e6bcf9
第2步:生成示例数据
我们将创建 100 个使用高斯噪声聚类的二维点。
- 设置随机种子: 确保每次运行代码时结果都是可复现的。
- 定义 center = 0.5 和 spread = 0.1: 簇点将以 0.5 为中心,并带有一些变化。
- 生成数据: 使用 高斯(正态)分布 在二维空间中创建 100 个随机点。
- 裁剪值: 确保所有点都位于 [0,1] 范围内(保持数据有界)。
Python
CODEBLOCK_b64f4222
第3步:设置模糊 C 均值参数
这些参数控制聚类的行为:簇的数量、模糊度、停止容差以及最大迭代次数以实现收敛。
- n_clusters = 3: 我们希望将数据分为 3 个簇。
- m = 1.7: 模糊度参数;值越高,簇的隶属度越柔和(点可以属于多个簇)。
- error = 1e-5: 停止容差;如果变化小于此阈值,算法将停止。
- maxiter = 2000: 允许达到收敛的最大迭代次数。
Python
CODEBLOCK_9741cdb8
第4步:执行模糊 C 均值聚类并将每个点分配给硬簇
通过为每个点选择具有最高隶属度的簇,将模糊隶属度转换为硬簇分配。
- cntr: 最终的簇中心
- u:隶属度矩阵