Fuzzy C-Means Clustering(模糊C均值)

2023-05-16

别看了 有错的 我懒得改了

强推https://www.bilibili.com/video/BV18J411a7yY?t=591

看完你还不会那我也没办法了









\

算法原理

  模糊c-均值聚类算法 fuzzy c-means algorithm (FCMA)或称(FCM)。在众多模糊聚类算法中,模糊C-均值(FCM)算法应用最广泛且较成功,它通过优化目标函数得到每个样本点对所有类中心的隶属度,从而决定样本点的类属以达到自动对样本数据进行分类的目的。
  先来讲讲这个算法的名字噢,什么叫Fuzzy,什么叫模糊呢,在经典的集合理论,一个元素是否属于集合,只有真或者假两种情况,也可以说只有0和1两种情况,0为假1为真。比如我们想要定义一个集合表示“年轻人”,那么我们需要设置一个阈值,当一个人的年龄小于这阈值的时候,就认为这个人属于这个集合,反之则不属于。假如用A表示年轻人这个集合,以20岁为阈值。则这个集合的隶属度函数可以表示如下:
μ A ( z ) = { 1 , z < 20 0 , z ≥ 20 \mu_A(z)= \begin{cases} 1, z < 20 \\ 0, z \geq 20 \end{cases} μA(z)={1,z<200,z20
上面的公式可以用下面左图表示:
在这里插入图片描述
  使用经典的集合理论,我们会面临着一些实际的问题,比如当一个人的年龄是20岁零1秒的时候,这个人就不再是年轻人了,这种粗暴的分类方式,在实际中并不实用。因此我们需要有过渡的函数来描述这个情况。上图中右边的图提供了一种解决方法,图中的斜线表示年龄的过渡。
于是就可以定义三个隶属度函数来确定年龄与三个模糊子集的关系:
μ A ( z ) = { 1 , z ≤ 20 30 − z 10 , 20 < z < 30 0 , z ≥ 30 \mu_A(z)= \begin{cases} 1, z \leq 20 \\ \frac {30-z}{10}, 20< z < 30 \\ 0, z \geq 30 \end{cases} μA(z)=1,z201030z,20<z<300,z30
  OK,模糊的概念大概懂了,那么C-Means的C又是什么东西呢,额这个,好像没有什么含义,就像K-Means的k一样,只是代表聚类的个数,可能是cluster的c?又可能是模糊控制器(Fuzzy Controller)里的c。但是这个无关紧要,懂得模糊的概念就好了。

  然后我们来正式说一下模糊c-均值是什么。模糊c-均值是一种允许一个数据属于一个或多个簇的方法,它不同于K-Means一个数据只能属于一个簇,它自发明以来广泛应用于模式识别中。
  那么这种算法它的优化目标、目标函数是什么呢?看下面的公式:
m i n    J m = ∑ i = 1 N ∑ j = 1 C μ i j m ∣ ∣ x i − v j ∣ ∣ 2 , 1 < m < ∞ s . t .    ∑ j = 1 C μ i j = 1 (1) min\ \ J_m=\sum_{i=1}^N \sum_{j=1}^C \mu_{ij}^m||x_i-v_j||^2, 1<m<\infty \tag1\\ s.t.\ \ \sum_{j=1}^C \mu_{ij}=1 min  Jm=i=1Nj=1Cμijmxivj2,1<m<s.t.  j=1Cμij=1(1)
符号定义:
N : N: N: 是样本总个数
C : C: C: 簇心数目,就是一开始输入的参数,你想这N个数据分成3份就将C置为3,5份就置为5,懂吧
μ : \mu: μ: 一个 N × C N\times C N×C的矩阵,其中 μ i j \mu_{ij} μij x i x_i xi属于类别 j j j的隶属度
v j : v_j: vj: j j j个类别的中心
m : m: m: C C C一样是自己设置的参数,不同的 m m m会有不同的聚类效果,需要根据不同的数据集进行调节

这个公式呢就是说每一个数据 x i x_i xi到每一个聚类中心 v j v_j vj距离的二范式再乘上 x i x_i xi属于类别 j j j的隶属度的 m m m次方,要最小化它们的总和,直观一点就是希望每一个数据尽可能与它们所属的聚类中心接近。

  那么就开始求如何使这个函数最小化了,(众所周知),求最小嘛,基本操作将它对某个变量求偏导,令偏导结果为零即可,因为有一个等式约束,我们先引入拉格朗日乘子 λ \lambda λ,于是原式可以写成:

m i n    J = ∑ i = 1 N ∑ j = 1 C μ i j m ∣ ∣ x i − v j ∣ ∣ 2 − λ ( ∑ j = 1 C μ i j − 1 ) (2) min\ \ J=\sum_{i=1}^N \sum_{j=1}^C \mu_{ij}^m||x_i-v_j||^2 -\lambda(\sum_{j=1}^C \mu_{ij}-1) \tag2 min  J=i=1Nj=1Cμijmxivj2λ(j=1Cμij1)(2)
然后对 λ \lambda λ求偏导并令其为零,得:
∂ J ∂ λ = ∑ j = 1 C μ i j − 1 = 0 (3) \frac{\partial J}{\partial\lambda}=\sum_{j=1}^C \mu_{ij}-1=0 \tag3 λJ=j=1Cμij1=0(3)
再对 μ i j \mu_{ij} μij求偏导并令其为零,得:
∂ J ∂ μ i j = m ⋅ μ i j m − 1 ∣ ∣ x i − v j ∣ ∣ 2 − λ = 0 (4) \frac{\partial J}{\partial\mu_{ij}}=m\cdot \mu_{ij}^{m-1} ||x_i-v_j||^2 -\lambda=0 \tag4 μijJ=mμijm1xivj2λ=0(4)
由(4)可得
μ i j = ( λ m ∣ ∣ x i − v j ∣ ∣ 2 ) 1 m − 1 (5) \mu_{ij}=\left( \frac{\lambda}{m||x_i-v_j||^2}\right)^\frac{1}{m-1} \tag5 μij=(mxivj2λ)m11(5)
将(5)代入(3)得:
∑ j = 1 C ( λ m ∣ ∣ x i − v j ∣ ∣ 2 ) 1 m − 1 − 1 = 0 ∑ j = 1 C ( λ m ) 1 m − 1 ( 1 ∣ ∣ x i − v j ∣ ∣ 2 ) 1 m − 1 − 1 = 0 ( λ m ) 1 m − 1 ∑ j = 1 C ( 1 ∣ ∣ x i − v j ∣ ∣ 2 ) 1 m − 1 − 1 = 0 \begin{aligned} \sum_{j=1}^C \left( \frac{\lambda}{m||x_i-v_j||^2}\right)^\frac{1}{m-1}-1 &=0 \\ \sum_{j=1}^C \left( \frac{\lambda}{m}\right)^\frac{1}{m-1} \left( \frac1{||x_i-v_j||^2}\right)^\frac{1}{m-1}-1 &=0 \\ \left( \frac{\lambda}{m}\right)^\frac{1}{m-1}\sum_{j=1}^C \left( \frac1{||x_i-v_j||^2}\right)^\frac{1}{m-1}-1 &=0 \end{aligned} j=1C(mxivj2λ)m111j=1C(mλ)m11(xivj21)m111(mλ)m11j=1C(xivj21)m111=0=0=0
于是我们就可以得到:
( λ m ) 1 m − 1 = 1 ∑ j = 1 C ( 1 ∣ ∣ x i − v j ∣ ∣ 2 ) 1 m − 1 (6) \left( \frac{\lambda}{m}\right)^\frac{1}{m-1} =\frac1{\sum_{j=1}^C \left( \frac1{||x_i-v_j||^2}\right)^\frac{1}{m-1}} \tag6 (mλ)m11=j=1C(xivj21)m111(6)
将(6)再代入(4)得:
μ i j = 1 ∑ k = 1 C ( 1 ∣ ∣ x i − v k ∣ ∣ 2 ) 1 m − 1 ( 1 ∣ ∣ x i − v j ∣ ∣ 2 ) 1 m − 1 = 1 ∑ k = 1 C ( ∣ ∣ x i − v j ∣ ∣ 2 ∣ ∣ x i − v k ∣ ∣ 2 ) 1 m − 1 (7) \mu_{ij} = \frac1{\sum_{k=1}^C \left( \frac1{||x_i-v_k||^2}\right)^\frac{1}{m-1}} \left( \frac1{||x_i-v_j||^2}\right)^\frac{1}{m-1} = \frac1{\sum_{k=1}^C \left( \frac{||x_i-v_j||^2}{||x_i-v_k||^2}\right)^\frac{1}{m-1}} \tag7 μij=k=1C(xivk21)m111(xivj21)m11=k=1C(xivk2xivj2)m111(7)

再对 v i v_i vi求偏导并令其为零,得:
∂ J ∂ v i = − 2 ∑ i = 1 N μ i j m ( x i − v j ) (8) \frac{\partial J}{\partial v_i}=-2\sum_{i=1}^N\mu_{ij}^m(x_i-v_j) \tag8 viJ=2i=1Nμijm(xivj)(8)
v j = ∑ i = 1 N μ i j m x i ∑ i = 1 N μ i j m (9) v_j=\frac{\sum_{i=1}^N\mu_{ij}^mx_i}{\sum_{i=1}^N\mu_{ij}^m}\tag9 vj=i=1Nμijmi=1Nμijmxi(9)
式(9)即为聚类中心 v j v_j vj的更新公式。

总结一下模糊C均值的更新公式如下:
μ i j = 1 ∑ k = 1 C ( ∣ ∣ x i − v j ∣ ∣ 2 ∣ ∣ x i − v k ∣ ∣ 2 ) 1 m − 1          v j = ∑ i = 1 N μ i j m x i ∑ i = 1 N μ i j m \mu_{ij}=\frac1{\sum_{k=1}^C \left( \frac{||x_i-v_j||^2}{||x_i-v_k||^2}\right)^\frac{1}{m-1}}\ \ \ \ \ \ \ \ v_j=\frac{\sum_{i=1}^N\mu_{ij}^mx_i}{\sum_{i=1}^N\mu_{ij}^m} μij=k=1C(xivk2xivj2)m111        vj=i=1Nμijmi=1Nμijmxi

算法步骤


  1. 确定类别数C,参数m,和迭代停止误差 ε \varepsilon ε以及最大迭代次数T
  2. 初始化聚类中心 V = { v 1 , v 2 , . . . , v C } V=\lbrace{v_1,v_2,...,v_C\rbrace} V={v1,v2,...,vC}
  3. For t=1 to T:
      Calculate U t U_t Ut with V t − 1 V_{t-1} Vt1 and (7)
      Calculate V t V_t Vt with U t U_t Ut and (9)
      If E t = ∣ ∣ V t − V t − 1 ∣ ∣ e r r ≤ ε E_t=||V_t-V_{t-1}||_{err} \leq \varepsilon Et=VtVt1errε
      Stop and put ( U f , V f ) = ( U t , V t ) (U_f, V_f)=(U_t, V_t) (Uf,Vf)=(Ut,Vt); Else
    Next t

举个例子

我们考虑FCM在一维下应用的情况。 使用二十个数据和三个聚类来初始化算法并计算U矩阵。 下图显示了每个基准面和每个聚类的成员隶属度。 根据隶属函数,数据的颜色是最近的群集的颜色。

在这里插入图片描述

在上图所示的仿真中,我们使用了模糊系数 m = 2 m = 2 m=2,其中模糊分布取决于簇的特定位置。 因为尚未执行任何步骤,所以无法很好地识别群集。 现在可以运行算法,直到验证停止条件为止。 下图显示了在第8步达到的最终条件,其中 m = 2 m = 2 m=2 ε = 0.3 \varepsilon= 0.3 ε=0.3

在这里插入图片描述
不同的初始化会导致算法的不同演化,它们可以收敛到相同的结果,但是迭代步骤的数量就不一样了。

python实现FCM对iris数据集进行聚类

import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
import scipy.io as scio

C = 3
m = 2
# T = 5000
# EPS = 0.0000001
colors = ['r', 'b', 'g']

def norm2(x):
    x = np.mat(x)
    return np.dot(x.reshape(1, -1), x.reshape(-1, 1))


def cal(x_i, c_j, c_k):
    x_i = np.mat(x_i).reshape(1, -1)
    c_j = np.mat(c_j).reshape(1, -1)
    c_k = np.mat(c_k).reshape(1, -1)
    return float(np.power(norm2(x_i-c_j)/norm2(x_i-c_k), 2.0/(m-1)))


def fuzzy_c_means(data, m, C, EPS, T):
    data = np.mat(data)
    n, p = data.shape
    V = [np.random.random([1, p]) for _ in range(C)]
    U = [[0 for i in range(C)] for j in range(n)]
    for i in range(n):
        for j in range(C):
            down = 0
            for k in range(C):
                down += cal(data[i], V[j], V[k])
            U[i][j] = 1.0/down
    for _ in range(T):
        for j in range(C):
            down = 0
            V[j] = np.zeros([1, p])
            for i in range(n):
                u_i_j_m = pow(U[i][j], m)
                V[j] += data[i]*u_i_j_m
                down += u_i_j_m
            V[j] /= down

        upgrade = 0
        for i in range(n):
            for j in range(C):
                down = 0
                for k in range(C):
                    down += cal(data[i], V[j], V[k])
                tmp = 1.0 / down
                upgrade += abs(U[i][j]-tmp)
                U[i][j] = tmp

        if upgrade < EPS:
            break
    for i in range(n):
        idx = np.argmax(U[i])
        plt.scatter(float(data[i][:, 0]), float(data[i][:, 1]), c=colors[idx])
    plt.show()


if __name__ == '__main__':
    a = datasets.load_iris()
    data = a['data']
    pca = PCA(n_components=2)
    data = pca.fit_transform(data)
    fuzzy_c_means(data=data, m=2, C=C, EPS=1e-7, T=5000)


原数据通过PCA降到二维空间中的分布情况如下图所示
在这里插入图片描述
通过FCM进行聚类后的结果如下图所示
在这里插入图片描述

参考博客

http://home.deib.polimi.it/matteucc/Clustering/tutorial_html/cmeans.html
https://blog.csdn.net/einsdrw/article/details/37930331

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Fuzzy C-Means Clustering(模糊C均值) 的相关文章

随机推荐

  • PX4:【uORB通讯机制】

    uORB xff1a Micro Object Request Broker PX4进程间的通讯机制 xff1a 多对多的信息发布与订阅方式 发布消息 xff1a 1 公告 advertise xff1a 相当于初始化 xff0c 在发布消
  • PX4:【传感器校准】

    sensor的校准校准步骤 xff1a 文件目录 xff1a 代码入口 xff1a 求解模型计算公式 sensor的校准 校准步骤 xff1a 首先通过地面站QGC进行校准 xff0c QGC将校准参数设置到sh文件中 此后再基于QGC的校
  • PX4:【sensor_combined】

    功能介绍消息内容sensor combined 产生机制 amp 代码流程 功能介绍 sensor combined 是一个冗余传感器集合的消息 xff0c 通过订阅多个传感器的数据 xff0c 将冗余的数据经过VoteSensorsUpd
  • PX4:【地面站传感器数据校准】

    上电 gt rsC 运行 sensor start commander start 入口函数 xff1a 位于commander文件夹中 Commader cpp Commander run xff08 xff09 commander lo
  • Windows和Linux双系统安装教程

    最近刚刚完成了Windows和Linux双系统 xff08 这里以Ubuntu安装为例 xff09 的安装 xff0c 应某奔同学要求 xff0c 这里简单记录下安装过程 系统启动盘准备Windows系统安装分出给Linux系统的磁盘空间安
  • MSCKF系列论文阅读与代码流程

    MSCKF原理与代码总结 算法原理前端理论 xff08 图像的特征提取与跟踪 xff09 后端理论 xff08 误差状态卡尔曼滤波模型 xff09 1 IMU状态预测1 1 IMU状态传播 xff08 p v q 4阶Runge Kutta
  • open_vins(二):rosbag精度测试

    一 xff0e ros读取与轨迹保存二 xff0e euroc数据集测试三 结论 一 xff0e ros读取与轨迹保存 运行open vins launch 读取ros数据包 xff1a roslaunch pgeneva ros eth
  • open_vins(三):imu静止初始化

    一 xff0e 静止初始化原理二 xff0e 理论公式三 xff0e 相关代码四 xff0e 小结 xff1a 初始化是指在系统启动阶段 xff0c 需要估计重力方向 gravity direction 加速度计以及陀螺仪biases ac
  • ros数据集录制:rosbag record

    1 查看话题 查看topic列表 xff1a rostopic list 打印topic内容 xff1a rostopic echo topic xff12 话题录制rosbag record 用于在ros系统中录取系统中其他ros节点发出
  • git pull的时候:您对下列文件的本地修改将被合并操作覆盖,请在合并前提交或贮藏您的修改。 正在终止

    使用git pull的时候报错 xff1a 更新 span class token number 008728 span e span class token punctuation span span class token number
  • 使用webpack-dev-server自动打包并实现debug调试

    webpack dev server 是一个开发服务器 xff0c 它的功能就是可以实现热加载 xff0c 并且自动刷新浏览器 准备工作 xff1a 创建一个程序目录test xff0c 将html页面拷贝进来 xff0c 在目录下新建sr
  • ROS实现串口GPS数据的解析与通信

    1 配置串口 配置串口时 xff0c 利用ROS自带的serial功能包进行串口数据的读取 xff0c 具体来说就是创建一个串口对象 xff0c 用成员函数read进行读取 xff0c 需要注意的是其中Timeout的设置以及read在调用
  • sumo之使用netedit绘制路网并进行简单模拟

    1 基本路网的构建 xff08 十字路口 xff09 在下载完成sumo后 xff0c bin目录下有一个可以运行的nete exe xff0c 点击可以进入界面进行路网的编辑 xff0c 编辑生成 net xml文件 点击进去后 xff0
  • sumo之模拟行人

    在前面的文章中介绍了模拟车辆以及交通工具 公共汽车 xff0c 在道路上除了车辆外还有行人参与 在本文中介绍添加行人 详细的方法和参数可以前往官网查看 本部分的模拟路网全部沿用上次公共汽车模拟的环境 xff0c 只需要对部分代码进行修改 首
  • 【开发工具】VScode连接远程服务器+设置免密登录

    文章目录 前言连接远程服务器免密登录注意事项参考资料 前言 本文介绍如何使用VScode搭建自己的远程开发平台 xff0c 以便于我们可以随时拿着自己心爱的PC xff0c 去开发让自己脱发的项目 连接远程服务器 首先 xff0c 我们去官
  • 2.3、Segment Routing基础之IGP Segment 类型详解

    本文将重点介绍IGP Segment 分发场景下常见的几种Segment类型 xff0c 同时为各位介绍了这些Segment类型在在Segment Routing转发过程中的转发动作以及转发特性 本文将对各位理解Segment Routin
  • IDEA日常填坑:Cannot resolve plugin org.apache.maven.plugins:maven-war-plugin

    问题描述 xff1a 我太难了o o xff0c 这个问题竟然困扰了我一个下午加上一个晚上 xff0c 为了解决它 xff0c 估计浏览器都要被我弄崩了吧 xff0c 此前我将所能找到的方法全都试了个遍 xff0c 甚至是将 IDEA 卸载
  • 判断点在多边形内(射线法)

    射线法 用来判断点在多边形的内外 适用于任意多边形 时间复杂度 xff1a O n 从该点引出一条水平射线 xff0c 观察射线与多变形的交点个数 当射线与多边形的交点个数是奇数时 xff0c P在多边形内 偶数时 xff0c P在多边形外
  • 线性判别分析(Linear Discriminant Analysis, LDA)(含类内散度矩阵 类间散度矩阵 全局散度矩阵推导

    LDA算法概述 xff1a 线性判别式分析 Linear Discriminant Analysis LDA xff0c 也叫做Fisher线性判别 Fisher Linear Discriminant FLD xff0c 是模式识别的经典
  • Fuzzy C-Means Clustering(模糊C均值)

    别看了 有错的 我懒得改了 强推https www bilibili com video BV18J411a7yY t 61 591 看完你还不会那我也没办法了 算法原理 模糊c 均值聚类算法 fuzzy c means algorithm