FCM算法

FCM算法

一、FCM简述

FCM算法是基于对目标函数的优化基础上的一种数据聚类方法。聚类结果是每一个数据点对聚类中心的隶属程度,该隶属程度用一个数值来表示。该算法允许同一数据属于多个不同的类。
FCM算法是一种无监督的模糊聚类方法,在算法实现过程中不需要人为的干预。
这种算法的不足之处:首先,算法中需要设定一些参数,若参数的初始化选取的不合适,可能影响聚类结果的正确性;其次,当数据样本集合较大并且特征数目较多时,算法的实时性不太好。
K-means也叫硬C均值聚类(HCM),而FCM是模糊C均值聚类,它是HCM的延伸与拓展,HCM与FCM最大的区别在于隶属函数(划分矩阵)的取值不同,HCM的隶属函数只取两个值:0和1,而FCM的隶属函数可以取[0,1]之间的任何数。K-means和FCM都需要事先给定聚类的类别数,而FCM还需要选取恰当的加权指数α,α的选取对结果有一定的影响,α属于[0,+∞)。

二、算法描述

1、目标函数

在这里插入图片描述
在这里插入图片描述

2、算法优化

对于FCM算法采用拉格朗日乘子法进行优化:
在这里插入图片描述迭代公式:
在这里插入图片描述

3、算法流程

在这里插入图片描述

4、Matlab实现

FCM1.m代码:

clear all;
close all;
ClustringMethod = 'FCM_test';
DataSet = input('input dataset:','s');
%% 读入不同的数据集
%% iris
% data=importdata([DataSet,'iris_data.txt']);
% id=importdata([DataSet,'iris_id.txt']);
% [data_num,data_dim]=size(data);
% id_label=min(id):max(id);
% center_num=max(id)-min(id)+1;
DataFile = ['D:\matlab_text\Data\',DataSet,'iris_data.txt'];
data = load(DataFile);%data
IdFile = ['D:\matlab_text\Data\',DataSet,'iris_id.txt'];
id = load(IdFile);%id
DataSet_name = 'iris';

% 读取数据信息
id_label = min(id):max(id);
[data_num,data_dim] = size(data);
center_num = max(id)-min(id)+1;
%% 参数设置
alpha=2;
threshold=1e-6;
loopnum = 100;
%% 输出文件
ResultDirection=['Result\',DataSet,'\',ClustringMethod,'\',DataSet_name];
if ~exist(ResultDirection,'dir')
    mkdir(ResultDirection);
end
Resultfile = [ResultDirection,'\alpha',num2str(alpha),'_',DataSet_name,'.txt'];
fp_result = fopen(Resultfile,'wt');
%% 将数据归一化到[0,1],采用min_max方法
data = (data-(ones(data_num,1)*min(data)))./(ones(data_num,1)*(max(data)-min(data)));
% ***************************************************************************************
% 避免陷入局部最优,重复计算100% ***************************************************************************************
for loop = 1:loopnum
    U = zeros(data_num,center_num);
    C = zeros(center_num,data_dim);
    % 初始化聚类中心--根据类中心初始化
    for i = 1:center_num
        temp = find(id==id_label(i));
        C(i,:) = data(temp(ceil(rand(1,1)*length(temp))),:);
    end
    iteration = 0;
    objfunc_old=0;
    %% Start----------FCM
    while(1)
        % 根据初始化的C计算隶属度U
        % 计算数据到聚类中心的距离
        distance_C = zeros(center_num,data_num);
        for i = 1:center_num
            distance_C(i,:) = ((bsxfun(@minus,C(i,:),data)).^2)*ones(1,data_dim)';
        end
        U = 1./(bsxfun(@times,(distance_C').^(1/(alpha-1)),sum((distance_C').^(-1/(alpha-1)),2)));
        U(distance_C'==0)=1;
        % 计算目标函数
        objfunc=sum(sum((U.^alpha).*(distance_C')));
        % 判断迭代终止条件
        if (abs(objfunc-objfunc_old)<threshold)
            break;
        end
        objfunc_old = objfunc;
        iteration = iteration + 1;
        % 更新聚类中心C
        Um = U.^alpha;
        C = bsxfun(@times,(Um')*data,((sum(Um))').^(-1));
    end
    %% End----------FCM
    % 将输出的隶属度U转换成id形式
    [~,id_U] = max(U,[],2);
    id_U = id_U - 1;
    % Compute the ACC
    [ACC,id_U_result] = Function_ACC( center_num,data_num,id_U,id_label,id );
    % Compute the NMI
    NMI = Function_NMI( id_U_result,id );
    % Output the ITE
    ITE = iteration;
    % Calculate the average value of evaluation indexes
    ACC_max = max(ACC,ACC_max);
    ACC_average = ACC_average + ACC/loopnum;
    NMI_average = NMI_average + NMI/loopnum;
    ITE_average = ITE_average + ITE/loopnum;
end
%% Output final results to .txt
fprintf(fp_result,'DataSet = %s\t',DataSet_name);
fprintf(fp_result,'ACC_max = %f\t',ACC_max);
fprintf(fp_result,'ACC_average = %f\t',ACC_average);
fprintf(fp_result,'NMI_average = %f\t',NMI_average);
fprintf(fp_result,'ITE_average = %f\n',ITE_average);
%% Output final results to terminal
fprintf('DataSet=%s\t ACC_max=%d\t ACC_average=%f\t NMI_average=%f\t ITE_average=%f\n',DataSet_name,ACC_max,ACC_average,NMI_average,ITE_average);

Function_ACC代码:

function [ accuracy_max,id_U_result ] = Function_ACC( center_num,data_num,id_U,id_label,id )
accuracy_max = 0;
% function_ACC 计算评价指标----准确率
% 全排列
id_permutation = perms(id_label);
id_temp = zeros(data_num,factorial(center_num));
for i = 1:factorial(center_num)
    for k = 1:center_num
        for j = 1:data_num
            if(id_U(j) == id_permutation(i,k))
                id_temp(j,i)=id_label(k);
            end
        end
    end
end
%分别计算每一种排列组合下的准确率
error = zeros(data_num,factorial(center_num));
for i = 1:data_num
    error(i,:) = (abs(id_temp(i,:)-id(i))>0)*1;%错误数
end
accuracy = max((data_num-sum(error))/data_num);
%得到准确率最高时的分类结果
id_U_result = id_temp(:,find((data_num-sum(error))/data_num==accuracy));
accuracy_max = max(accuracy,accuracy_max);
end

Function_NMI代码:

function [ NMI ] = Function_NMI( id_new,id_real )
% Function_NMI:hard clustering measure: normalized mutual information
% [data_num,center_num]=size(U);
data_num = length(id_real);
center_num = max(id_real(:))-min(id_real(:))+1;
id_label=min(id_real(:)):max(id_real(:));
%% compute the number of each cluster
Pn_id_new = zeros(1,center_num);
Pn_id_real = zeros(1,center_num);
P_id_new = zeros(1,center_num);
P_id_real = zeros(1,center_num);
for i = 1:center_num
    Pn_id_new(i) = length(find(id_new(:)==id_label(i)));
    Pn_id_real(i) = length(find(id_real(:)==id_label(i)));
    P_id_new(i) = length(find(id_new(:)==id_label(i)))/data_num;
    P_id_real(i) = length(find(id_real(:)==id_label(i)))/data_num;
end
%% compute entropy
H_new = 0;
H_real = 0;
for i = 1:center_num
    H_new = H_new - P_id_new(i)*log2(P_id_new(i));
    H_real = H_real-P_id_real(i)*log2(P_id_real(i));    
end
%% compute the number of mutual information
count_new_real=zeros(center_num,center_num);%同时隶属于Ri与Qj的数据点的个数
for i = 1:center_num
    for j = 1:center_num
        for n = 1:data_num
            if ((id_new(n) == id_label(i)) && (id_real(n) == id_label(j)))
                count_new_real(i,j) = count_new_real(i,j) + 1;
            end
        end
    end
end
P_new_real=count_new_real/data_num;
NMI=0;
for i=1:center_num
    for j=1:center_num
        if(P_new_real(i,j) ~= 0)
            NMI = NMI + P_new_real(i,j)*log2(P_new_real(i,j)/(P_id_new(i)*P_id_real(j)));
        end
    end
end
NMI = NMI/sqrt(H_new*H_real);
end

结果:
在这里插入图片描述
数据:
iris

三、参考文献

1.认识FCM算法
2.FCM算法的matlab程序
3.FCM理论详解

<think>好的,我现在需要帮助用户了解模糊C均值聚类算法FCM)的相关信息或实现方法。首先,我得回忆一下FCM的基本概念,确保自己理解正确。FCM是一种基于模糊理论的聚类算法,与传统K均值不同,它允许数据点属于多个簇,通过隶属度来表示这种不确定性。这可能在图像分割、模式识别等领域有应用。 接下来,用户可能需要知道FCM的核心思想和数学公式。我需要整理算法的步骤,比如初始化隶属度矩阵、计算聚类中心、更新隶属度等。这里需要注意数学表达式的正确性,根据用户提供的系统级指令,行内公式用$...$,独立公式用$$...$$。例如,目标函数应该用独立公式,而像更新隶属度的行内公式则需要正确使用LaTeX语法。 然后,用户可能关心如何实现FCM。我应该考虑提供一个Python的示例代码,这样用户可以直接参考。代码需要包括初始化、迭代更新步骤,以及停止条件。同时要注意代码的清晰性,比如使用numpy进行矩阵运算,循环迭代直到收敛。 另外,用户的问题可能涉及到FCM的优缺点和应用场景。需要列举几个优缺点,比如对噪声敏感,计算量大,但适合边界模糊的数据。应用方面,可以提到图像处理、生物信息学等。同时,根据用户提供的引用,比如引用[1]提到的k-means,可以对比FCM和K均值的不同之处,突出模糊聚类的优势。 用户还可能对相关算法或扩展感兴趣,比如遗传算法(引用[3]中的内容),虽然FCM本身是确定性的,但或许可以提到优化方法中的启发式算法,或者结合其他算法改进FCM的性能。此外,引用[2]提到的离群点检测可能与FCM的鲁棒性有关,可以简要提及如何处理噪声数据。 在整理回答时,需要确保结构清晰,分步骤解释,符合用户要求的“帮助用户逐步解决问题”。同时,生成的相关问题要围绕FCM展开,比如原理、参数选择、与其他算法的比较、优化方法等,这些问题能引导用户进一步探索。 最后,检查所有公式的LaTeX格式是否正确,行内和独立公式区分明确,引用标识是否正确添加,比如在提到目标函数时引用相关的文献,但根据用户提供的引用,可能没有直接对应的,所以需要确认是否有合适的引用位置,或者是否需要调整引用标注。 总结一下,回答的结构应该是:概述、算法步骤、数学公式、实现代码、优缺点、应用场景、相关问题。确保每个部分都简洁明了,符合用户的要求,并且正确使用格式和引用。</think>### 模糊C均值聚类(FCM算法详解 #### 1. **算法概述** 模糊C均值聚类(Fuzzy C-Means, FCM)是一种基于模糊集合理论的聚类方法,允许数据点以不同隶属度属于多个簇。与硬聚类(如K均值)不同,FCM更适合处理边界模糊的数据[^1]。 #### 2. **算法步骤** 1. **初始化**:随机生成隶属度矩阵$U=[u_{ij}]$,满足$\sum_{j=1}^c u_{ij}=1$,其中$c$为簇数。 2. **计算聚类中心**:通过隶属度加权计算簇中心$v_j$: $$ v_j = \frac{\sum_{i=1}^n (u_{ij})^m x_i}{\sum_{i=1}^n (u_{ij})^m} $$ 其中$m>1$为模糊因子,控制聚类模糊程度。 3. **更新隶属度**: $$ u_{ij} = \left[ \sum_{k=1}^c \left( \frac{\|x_i - v_j\|}{\|x_i - v_k\|} \right)^{\frac{2}{m-1}} \right]^{-1} $$ 4. **迭代终止**:重复步骤2-3,直到目标函数$J$变化小于阈值$\epsilon$: $$ J = \sum_{i=1}^n \sum_{j=1}^c u_{ij}^m \|x_i - v_j\|^2 $$ #### 3. **Python实现示例** ```python import numpy as np def fuzzy_c_means(X, c, m=2, max_iter=100, eps=1e-5): n, d = X.shape U = np.random.rand(n, c) U = U / U.sum(axis=1, keepdims=True) # 归一化 for _ in range(max_iter): # 计算簇中心 centers = (U.T ** m) @ X / (U.T ** m).sum(axis=1, keepdims=True) # 计算距离矩阵 dist = np.linalg.norm(X[:, None] - centers, axis=2) # 更新隶属度 new_U = 1 / (dist ** (2/(m-1)) * (1 / dist ** (2/(m-1))).sum(axis=1, keepdims=True)) # 判断收敛 if np.linalg.norm(new_U - U) < eps: break U = new_U return U, centers ``` #### 4. **优缺点分析** - **优点**: - 适用于边界模糊的数据(如医学图像分割)。 - 通过隶属度提供更丰富的信息[^1]。 - **缺点**: - 对初始值敏感,可能陷入局部最优。 - 计算复杂度较高($O(nc^2d)$)。 #### 5. **应用场景** - 图像分割(如MRI图像组织分类) - 文本聚类(文档主题模糊划分) - 生物信息学(基因表达模式分析)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值