基于模糊 C 均值(Fuzzy C-Means, FCM)聚类

基于模糊 C 均值(Fuzzy C-Means, FCM)聚类

模糊 C 均值(Fuzzy C-Means, FCM) 是一种 软聚类算法,与 KMeans 不同,它允许数据点 部分地属于多个簇,适用于 图像分割、医学诊断、推荐系统等任务


1. Fuzzy C-Means vs. KMeans

方法适用情况主要区别
Fuzzy C-Means (FCM)适用于模糊分类、软聚类数据点可部分属于多个簇(隶属度)
KMeans适用于硬聚类(每个点只能属于一个簇)数据点必须完全属于某个簇

示例

  • KMeans:每个样本完全属于一个簇。
  • FCM:每个样本以一定的 概率(隶属度) 归属于多个簇。

2. Fuzzy C-Means 代码示例

(1) 训练 Fuzzy C-Means

FCM 需要安装 skfuzzy

pip install scikit-fuzzy
import numpy as np
import skfuzzy as fuzz
import matplotlib.pyplot as plt

# 生成数据
X = np.random.rand(100, 2).T  # 100 个二维点(转置以符合 FCM 格式)

# 训练 FCM 聚类模型
n_clusters = 3
cntr, u, _, _, _, _, _ = fuzz.cmeans(X, c=n_clusters, m=2, error=0.005, maxiter=1000)

# 获取聚类标签
labels = np.argmax(u, axis=0)
print("Fuzzy C-Means 簇标签:", labels[:10])

解释

  • fuzz.cmeans() 训练 Fuzzy C-Means
  • c=n_clusters=3:设定 3 个簇。
  • m=2:模糊因子,控制数据点的模糊程度(m=1 退化为 KMeans)。
  • u:隶属度矩阵,表示数据点属于各个簇的概率。
  • labels = np.argmax(u, axis=0) 获取每个数据点最可能的簇标签。

3. Fuzzy C-Means 主要参数

fuzz.cmeans(X, c=3, m=2, error=0.005, maxiter=1000)
参数说明
X数据集(形状: (features, samples)
c簇数(类似 KMeansn_clusters
m模糊指数(默认 2,值越大,聚类越模糊)
error误差阈值(默认 0.005,用于收敛判断)
maxiter最大迭代次数(默认 1000

4. 计算隶属度(Soft Clustering)

print("前 5 个样本的隶属度:\n", u[:, :5])

解释

  • u[i, j] 表示第 j 个样本属于第 i 个簇的概率

5. Fuzzy C-Means 可视化

import seaborn as sns

sns.scatterplot(x=X[0], y=X[1], hue=labels, palette="coolwarm")
plt.scatter(cntr[:, 0], cntr[:, 1], s=200, c="black", marker="X", label="Centroids")
plt.legend()
plt.title("Fuzzy C-Means 聚类结果")
plt.show()

解释

  • 黑色 X 标记簇中心

6. Fuzzy C-Means vs. KMeans(软聚类)

from sklearn.cluster import KMeans

# 训练 KMeans
kmeans = KMeans(n_clusters=3, random_state=42)
labels_kmeans = kmeans.fit_predict(X.T)

# 可视化
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].scatter(X[0], X[1], c=labels_kmeans, cmap="coolwarm")
axes[0].set_title("KMeans 硬聚类")
axes[1].scatter(X[0], X[1], c=labels, cmap="coolwarm")
axes[1].set_title("Fuzzy C-Means 软聚类")
plt.show()

解释

  • KMeans 只能进行硬聚类(数据点只能属于一个簇)。
  • Fuzzy C-Means 允许数据点部分属于多个簇(软聚类)。

7. 计算聚类性能

from sklearn.metrics import silhouette_score

score = silhouette_score(X.T, labels)
print("轮廓系数:", score)

解释

  • silhouette_score(X.T, labels) 评估聚类效果(值越大越好)。

关于 sklearn 是否支持 FCM

需要注意的是,scikit-learn 并未内置 FCM 算法的支持。其主要提供硬聚类方法(如 K-Means),而 FCM 属于软聚类范畴。如果希望使用 sklearn 中的功能扩展到 FCM,则需自行实现或借助第三方库完成。

然而,可以通过继承 BaseEstimatorClusterMixin 类来自定义一个类似的接口封装 skfuzzy 的 FCM 功能。下面是一个简单的自定义封装例子:

from sklearn.base import BaseEstimator, ClusterMixin
import skfuzzy as fuzz

class FuzzyCMeans(BaseEstimator, ClusterMixin):
    def __init__(self, n_clusters=2, m=2, error=0.005, max_iter=1000):
        self.n_clusters = n_clusters
        self.m = m
        self.error = error
        self.max_iter = max_iter
    
    def fit(self, X):
        self.centers_, self.u_, _, _, _, _, _ = fuzz.cluster.cmeans(
            X.T, self.n_clusters, self.m, error=self.error, maxiter=self.max_iter, init=None
        )
        return self
    
    def predict(self, X):
        _, u_predict, _, _, _, _ = fuzz.cluster.cmeans_predict(
            X.T, self.centers_, self.m, error=self.error, maxiter=self.max_iter
        )
        return np.argmax(u_predict, axis=0)

# 示例调用
model = FuzzyCMeans(n_clusters=3, m=2, error=0.005, max_iter=1000)
model.fit(data.T)
predictions = model.predict(data.T)
print(predictions[:10])

此封装允许用户像操作其他 sklearn 模型一样使用 FCM 方法。


8. 适用场景

  • 医学诊断(如病人可能属于多个疾病类别)。
  • 推荐系统(如用户可能对多个类别有兴趣)。
  • 图像分割(如边界区域的像素可以部分属于多个区域)。

9. 结论

  • Fuzzy C-Means 适用于软聚类任务,每个数据点可以部分属于多个簇,适用于医学、推荐系统、图像分割,相比 KMeans 更灵活但计算复杂度更高。
### 模糊C均值聚类 (Fuzzy C-Means, FCM) 算法原理 #### 定义与目标函数 模糊C均值聚类是一种聚类技术,允许数据点属于多个簇,并赋予不同的隶属度。每个数据点到各个簇心的距离决定了其隶属于不同簇的程度。FCM的目标是最小化以下目标函数: \[ J_m(U,C)= \sum_{i=1}^{c}\sum_{j=1}^{n}(u_{ij})^m d^2(x_j,c_i) \] 其中 \( u_{ij} \) 表示第 j 个样本对第 i 类的隶属度;\( c_i \) 是第 i 类的聚类中心;\( m \geq 1 \) 是模糊指数;\( d(\cdot,\cdot) \) 计算的是欧氏距离。 #### 聚类中心更新公式 在每次迭代过程中,聚类中心会依据当前的数据点及其对应的隶属度重新计算。具体来说,在第 t 次迭代时,第 i 个聚类中心 \( C_i^{(t)} \) 的更新方式为[^2]: \[ C_i^{(t+1)}=\frac{\sum_{j=1}^{N}{(U_{ij}^{(t)})^md_j}}{\sum_{j=1}^{N}{(U_{ij}^{(t)})^m}} \] 这里 \( U_{ij} \) 表示第 j 个对象对于第 i 类别的隶属程度矩阵中的元素,\( d_j \) 则代表相应对象的位置向量。 ### MATLAB 实现基于 PSO 的 FCM 算法 为了改善传统 FCM 易陷入局部最优解的问题,可以通过引入粒子群优化(Particle Swarm Optimization, PSO) 来寻找更优的初始聚类中心位置。通过合理调整这些参数,可以有效提高PSO优化FCM聚类效果[^1]。 ```matlab function [centers, U, objFuncHist] = pso_fcm(data, numClusters, maxIter, popSize) % 初始化种群... for iter = 1:maxIter % 更新速度和位置... % 使用当前位置作为初始化条件运行一次标准FCM算法... [~,~,objVal] = fcm(data',numClusters,'Centers',currentPositions'); % 存储最佳个体的历史记录... end end ``` 此代码片段展示了如何利用 PSO 对 FCM 进行改进,从而获得更好的全局搜索能力并提升最终模型性能。 ### 应用场景 - **图像分割**:通过对像素颜色特征进行分组来区分前景背景或其他感兴趣区域。 - **客户细分**:帮助企业识别具有相似消费行为模式的不同顾客群体以便制定针对性营销策略。 - **基因表达数据分析**:用于生物信息学领域中发现潜在的功能模块或调控网络。 - **异常检测**:监测工业过程控制系统的健康状态变化趋势,及时预警可能出现的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬彬侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值