Advertisement

FCM算法的matlab实现(Fuzzy C-means 算法)

阅读量:

FCM算法是一种基于模糊聚类的划分式聚类方法,用于将数据集划分为多个模糊类。其核心思想是通过模糊隶属度矩阵来表示样本对各类的归属程度,而非严格属于某一类别。算法通过迭代优化隶属度矩阵和聚类中心,使得目标函数(样本到聚类中心的加权距离平方和)逐步减小,最终收敛到最优解。
FCM算法的实现主要包括以下几个步骤:
初始化模糊隶属度矩阵,通常采用随机生成的方法,并进行归一化处理。
计算聚类中心,通过模糊隶属度矩阵和样本数据更新聚类中心。
计算样本到聚类中心的距离,并更新模糊隶属度矩阵。
重复上述步骤,直到目标函数值收敛或达到最大迭代次数。
Matlab实现中,主函数FCMCluster负责调用初始化函数、距离计算函数和逐步聚类函数,完成整个聚类过程。通过设置不同的参数(如指数幂、最大迭代次数和收敛阈值),可以控制聚类的详细过程。运行结果表明,该算法能够有效划分数据集,并生成清晰的聚类图。

FCM算法

  • FCM算法简介
  • FCM算法原理
  • FCM算法实现(matlab)

FCM算法简介

FCM算法归类于划分式聚类算法,通过模糊数学方法处理聚类问题。基于一个初始划分,算法需要预先设定聚类数目,并定义一个最优化聚类标准,即目标函数作为衡量各类样本分布代价的函数FCM算法将N个数据向量划分为C个模糊类,每个类的聚类中心代表该类。通过反复迭代计算,算法逐步减小目标函数的误差值,当目标函数收敛时,最终获得所需的聚类结果。

FCM算法原理

符号定义:
x_i代表第i个样本
N表示样本总数
l为样本的维度数
C代表样本的类别划分
V表示聚类中心
u_{ik}表示第i个数据点属于第k类的隶属度
d(x_i, v_k)表示第i个样本与第k个聚类中心的欧氏距离,即d(x_i, v_k) = \sqrt{\sum_{p=1}^{L} (x_{ip} - v_{kp})^2}

FCM算法的目标函数定义为:
J_{FCM}(u,v)=\sum_{k=1}^C\sum_{i=1}^Nu_{ik}^md^2(x_i,v_k)
其中,隶属度的约束条件为:
\sum_{k=1}^Cu_{ik}=1 \quad (i=1,2,\dots,N)
将欧氏距离代入目标函数公式:
J_{FCM}(u,v)=\sum_{i=1}^N\sum_{k=1}^C(u_{ik}^2)\sum_{p=1}^L(x_{ip}-v_{kp})^2\quad (k\in\{1,2,\dots,C\})\quad (p\in\{1,2,\dots,L\})
v_{kp}求偏导数,令其等于零,得:
\frac{\partial{J_{FCM}}}{\partial v_{kp}} =2\sum_{i=1}^N (u_{ik})^2(x_{ip}-v_{kp})=0
解得:
v_{kp}=\frac{\sum_{i=1}^N(u_{ik})^2x_{ip}}{\sum_{i=1}^N(u_{ik})^2}
构建拉格朗日函数:
J_{FCM}(u,v,\lambda)=\sum_{i=1}^N\sum_{k=1}^C(u_{ik})^{d^2(x_{i}-v_{k})}-\sum_{i=1}^N\lambda_i\left(\sum_{k=1}^Cu_{ik}-1\right)\quad (r\in\{1,2,\dots,N\},\ s\in\{1,2,\dots,C\})
u_{rs}求偏导数,令其等于零,得:

\frac{\partial {J_{FCM}(u,v)}}{\partial u_{rs}}=2(u_{us}d^2(x_r-\lambda_r))=0
u_{rs}=\frac{\lambda_r}{2d^2{(x_r,v_s)}}

在约束条件下,我们有\sum_{k=1}^Cu_{rk}=1,由此可得:\sum_{k=1}^C\frac{\lambda_r}{2d^2(x_r,v_k)}=1,即:
\lambda_r=\frac{1}{\sum_{k=1}^C\frac{1}{2d^2(x_r,v_k)}}
\lambda_r代入后可得:
v_k=\frac{\sum_{i=1}^N(u_{ik})^m x_i}{\sum_{i=1}^N(u_{ik})^m}
通过隶属度更新公式,我们得到:
u_{ik}=\frac{ \frac{1} {d^2(x_i,v_k)} }{{\sum_{r=1}^C }\frac{1} {d^2(x_i,v_r)}}

FCM算法实现(matlab)

该系统包含四个核心函数:
核心函数 FCM聚类算法.m
初始化模糊关系矩阵:initfcm.m
基于欧氏距离的相似度计算:distfcm.m
基于逐次优化的聚类方法:stepfcm.m

复制代码
    function [center,U,obj_fun]=FCMCluster(data,n,options)
    
    % 采用模糊c均值聚类,将数据集分为n类
    % data 数据集 n 类别数 
    % options 4*1 矩阵
    % option(1):隶属度函数矩阵的加权指数,默认为2
    % option(2):最大迭代次数,默认100次
    % option(3):隶属度最小变化量,默认为1e-5
    % option(4):每次迭代是否输出信息标志,默认输出,值为1
    % center 聚类中心
    % U 隶属度矩阵
    % obj_fun 目标函数值
    
    %确定或给定参数
    if nargin~=2 && nargin ~=3
    error('Too many ot too few input agruments');
    end
    
    %默认参数
    default_options=[2;100;1e-5;1];
    
    % 参数配置
    if nargin==2
       options=default_options;
    
    else
    if length(options)<4
        tmp=default_options;
        tmp(1:length(options))=options;
        options=tmp;
    end
    nan_index=find(isnan(options)==1);
    options(nan_index)=default_options(nan_index);
    if options(1)<=1
        error('The exponent should be greater than 1!');
    end
    end
    
    %参量初始化
    
    expo=options(1);            %指数的次幂
    max_iter=options(2);        %最大迭代次数
    min_impro=options(3);       %精度
    display=options(4);         %是否显示最终函数值
    obj_fun=zeros(max_iter,1);  %储存聚类函数在每次迭代中的值
    
    data_n=size(data,1);        %行数,即样本个数
    in_n=size(data,2);          %样本的维数     
    U=initfcm(n,data_n);        % 初始化模糊分配矩阵  
    
    % 主程序
    for i=1:max_iter  
    [U,center,obj_fun(i)]=stepfcm(data,U,n,expo);
    
    %显示聚类最终的函数值
    if display
        fprintf('FCM:Iteration count=%d,obj_fun=%f\n',i,obj_fun(i));
    end
    
    % 终止条件判断
    if i>1
        if abs(obj_fun(i)-obj_fun(i-1))<min_impro
            break;
        end
    end
    
    end
    
    iter_n=i;
    obj_fun(iter_n+1:max_iter)=[];
    end
复制代码
    function U=initfcm(n,data_n)
    %子函数  模糊矩阵初始化
    % data_n 样本个数
    % n 分类个数
    % U(i,j)  第j个数据点属于第i个类的隶属度
    
    %取随机矩阵,且进行归一化(即,列和为1)
    
    U=rand(n,data_n);    
    col_sum=sum(U);
    U=U./col_sum(ones(n,1),:);
    end
复制代码
    function [U_new,center,obj_fun]=stepfcm(data,U,n,expo)
    % 逐步聚类
    
    %聚类中心
    mf=(U.^expo);           
    center=mf*data./((ones(size(data,2),1)* sum(mf'))');
    
    %聚类函数对应函数值
    dist=distfcm(center,data);
    obj_fun=sum( sum( (dist.^2).* mf) );
    
    %更新隶属度矩阵
    tmp=dist.^(-2/(expo-1));
    U_new=tmp./(ones(n,1)*sum(tmp));
    
    end
复制代码
    function out=distfcm(center,data)
    % 计算样本到聚类中的距离,欧几里得距离
    
    out = zeros(size(center,1),size(data,1));
    
    for k=1:size(center,1)
    out(k,:)=sqrt( sum(((data-ones(size(data,1),1) * center(k,:)).^2)',1));
    end
    
    end

下面利用随机生成的100个二维数据来对算法进行验证:

复制代码
    function fmean
    clear,clc
    close all
    data=rand(100,2);
    N=10;
    [center,U,obj_fcn]=FCMCluster(data,N);
    plot(data(:,1),data(:,2),'ro');
    hold on
    
    U_max=max(U);
    for j=1:100
    row(:,j)=find(U(:,j)==U_max(j)); %列数对应相应的数据位置,矩阵元素对应其类别    
    end
    
    for i=1:N
    col=find(row==i);      %max(U)返回隶属度列最大值所在行一致的分为一类
    plot(data(col,1),data(col,2),'*');
    hold on
    
    end
    grid on
    %画出聚类中心
    plot(center(:,1),center(:,2),'p','color','m','MarkerSize',8);
    end

运行的结果:

输出迭代次数,目标函数值

聚类图:

聚类结果图示

PS:如果有问题或疑问可以联系我。

全部评论 (0)

还没有任何评论哟~