FCM算法

  之前有看过关于FCM算法的资料,接下来的这几天我就自己学到的一些东西与大家分享~

一 FCM算法概述

FCM算法的全称是模糊C均值聚类算法,和K-means算法同属于聚类算法,但却有着本质的区别,就其命名而言,模糊二字无疑是该算法的重点,下面就先简单介绍一下:

1. 隶属度和模糊集

  隶属度函数用来描述元素x属于一个集合B的程度,假定为UB(x),其中x为B中的任意元素,UB(x)的取值范围为[0,1]。在隶属度函数的基础上,称空间上X={x}上的隶属度函数为一个模糊集合。

2. 模糊聚类分析

  传统的聚类分析是把每个元素严格的划分到一个类中,属于硬划分。模糊聚类分析将聚类生成的每个簇均看做模糊集合,通过隶属度来确定聚类关系,是一种柔性划分,得到元素属于各个簇的不确定性程度,使得聚类结果更加准确灵活,因此,模糊聚类分析逐渐成为聚类分析的主流。

3.FCM

FCM算法是将N个L维向量分为C个模糊组,通过迭代不断更新隶属度以及聚类中心,最小化目标函数对数据进行聚类。

其中,目标函数为:

约束条件为:

根据隶属度的非负性,有。这里,m指的是模糊加权系数,它的值大于1;d(xi,vc)表示的是第i个数据点与第c个聚类中心的欧式距离;uic是隶属度矩阵中的元素,且[0,1];vc是对应于每个聚类的聚类中心。

为了求含有约束条件的目标函数的极值,引入拉格朗日因子构造新的目标函数:

对于目标函数求极值的最优化条件如下:

       

从而得到隶属度和聚类中心的计算公式为:

        

根据上述公式不断迭代求出满足条件的隶属度以及聚类中心。具体的FCM算法步骤如下:

首先,给定一个由N个L维向量组成的数据集X以及所要分得的类别个数C,自定义隶属度矩阵

(1)设定类别的个数C和模糊系数m;

(2)?初始化隶属度矩阵且满足公式(2)中的归一化条件;

(3)根据公式(5)计算聚类中心;

(4)根据公式(4)更新隶属度矩阵;

(5)根据矩阵范数比较迭代的隶属度矩阵,如果,迭代停止,否则返回(3)。

二 MATLAB实现

根据上述公式及步骤,采用MATLAB实现,具体如下:

(1)选取UCI数据库中的wine数据实现,代码:

clear all
clc;
%% 导入数据
load wine.txt;
cluster_n=6;

data = wine;
data(:,1) = [];
data(:,size(data,2)) = [];
data_n = size(data, 1); %数据的个数
in_n = size(data, 2);% 数据维数

%% 定义变量
default_options = [10;    % 隶属度函数的幂次方
        300;    % 最大迭代次数
        1e-5;    %步长
        1];    % 判定条件

options = default_options;
expo = options(1);        % Exponent for U 隶属度函数的幂次方
max_iter = options(2);        % Max. iteration 最大迭代次数
min_impro = options(3);        % Min. improvement  最小进化步长
display = options(4);        % Display info or not 显示信息与否
obj_fcn = zeros(max_iter, 1);    % Array for objective function

tic
%% 初始化隶属度矩阵并归一
U = rand(cluster_n, data_n); %rand()产生随机矩阵
col_sum = sum(U);
U = U./col_sum(ones(cluster_n, 1), :);%归一化

%% 开始迭代
for i = 1:max_iter,%迭代次数控制
    tic
    mf = U.^expo;      % MF matrix after exponential modification
    center = mf*data./((ones(size(data, 2), 1)*sum((mf‘)))‘); % 建立新的聚类中心

       out = zeros(size(center, 1), size(data, 1));  %每个点到每个中心的距离,行数为中心数

        if size(center, 2) > 1,%样本的维数大于一执行以下程序
            for k = 1:size(center, 1),%给K赋值
                abc = ((data-ones(size(data,1),1) * center(k,:)).^2)‘;
                  out(k, :) = sqrt(sum(abc));%得到欧氏距离
            end
       else    % 1-D data
            for k = 1:size(center, 1),
                  out(k, :) = abs(center(k)-data)‘;
            end
        end

    obj_fcn(i) = sum(sum((out.^2).*mf));  % 目标函数
    tmp = out.^(-2/(expo-1));      % 根据新的隶属度矩阵求解公式求出
    U= tmp./(ones(cluster_n, 1)*sum(tmp));  % 新的隶属度矩阵

    if display,
        fprintf(‘Iteration count = %d, obj. fcn = %f\n‘, i, obj_fcn(i));
        %输出迭代次数和函数的结果
    end
    % check termination condition
    if i > 1,  %进化步长控制
        if abs(obj_fcn(i) - obj_fcn(i-1)) < min_impro, break; end,
    end
    toc
end
toc

plot(U(1,:),‘-ro‘);
grid on
hold on
plot(U(2,:),‘-g*‘);
plot(U(3,:),‘-b+‘);

ylabel(‘Membership degrees‘)
legend(‘FCM1‘,‘FCM2‘,‘FCM3‘,‘location‘,‘northeast‘);

toc

结果如下:

      

(2)选取一张MRI图像,进行图像分割,代码如下:

clear all
clc;

a=imread(‘MRI.jpg‘);
I=imnoise(a,‘salt & pepper‘,0.05);
figure(1);
 imshow(I);title(‘加噪图像‘);

[height,width,c]=size(a);
if c~=1
    a=rgb2gray(a);
end

a=double(a);
[row,column]=size(a);
data = a(:);
data_n = size(data,1);

cluster_num = 4;
default_options = [2.0;    % 隶属度函数的幂次方
        300;    % 最大迭代次数
        1e-5;    %步长
        1];    % 判定条件

options = default_options;

expo = options(1);        % Exponent for U 隶属度函数的幂次方
max_iter = options(2);        % Max. iteration 最大迭代次数
min_impro = options(3);        % Min. improvement  最小进化步长
display = options(4);        % Display info or not 显示信息与否

obj_fcn = zeros(max_iter, 1);    % Array for objective function
membership = zeros(height,width,cluster_num);
center = zeros(cluster_num,1);

tic
% 初始化隶属度并归一
for i=1:height
    for j=1:width
        member_sum=0;
        for k=1:cluster_num
            membership(i,j,k)=rand();
            member_sum = member_sum + membership(i,j,k);
        end
        for p =1:cluster_num
            membership(i,j,p) = membership(i,j,p) / member_sum;
        end
    end
end

tic
for i = 1:max_iter,%迭代次数控制
    mf = membership.^expo;
    %%%%%%%%建立聚类中心
    for m = 1:cluster_num
        to = 0;
        tp =0;
        for j = 1:height
            for t = 1:width
                to = to + membership(j,t,m) * a(j,t);
                tp = tp + membership(j,t,m);
            end
        end
        center(m,1) = to / tp;
    end

    %%%%%%%得到欧式距离以及目标函数
    out = zeros(height,width,cluster_num);
    for m =1:height
        for j =1:width
            for t = 1:cluster_num
                out(m,j,t) = abs(a(m,j) - center(t,1));
                obj_fcn(i) = obj_fcn(i) + (membership(m,j,t).^expo) * (out(m,j,t).^2);
            end
        end
    end

    for m = 1:height
        for j = 1:width
            for r = 1:cluster_num
                top =0;
                for t = 1:cluster_num
                    top = top + (out(m,j,r) / out(m,j,t)).^(expo - 1);
                end
                membership(m,j,r) = 1 / top;
            end
        end
    end

    %%%%%%归一化隶属度
    for m=1:height
        for j = 1:width
            member_sum = 0;
            for k = 1:cluster_num
                member_sum = member_sum + membership(m,j,k);
            end
            for p = 1:cluster_num
                membership(m,j,p) = membership(m,j,p) / member_sum;
            end
        end
    end

     if display,
        fprintf(‘Iteration count = %d, obj. fcn = %f\n‘, i, obj_fcn(i));
        %输出迭代次数和函数的结果
    end
    % check termination condition
    if i > 1,  %进化步长控制
        if abs(obj_fcn(i) - obj_fcn(i-1)) < min_impro, break; end,
    end
end
toc

%%%%%%证得如自定义图像中的MCR不能计算,故在此继续尝试直接用newing和A相比较

A = ones(height,width,1);
for i = 1:height
    for j = 1:width
        if (fix(a(i,j) / 85) == 1)
            A(i,j,1) = 2;
        end
        if (fix(a(i,j) / 85) == 2)
            A(i,j,1) = 3;
        end
        if (fix(a(i,j,1) / 85) == 3)
            A(i,j,1) = 4;
        end
    end
end
A = reshape(A,1,data_n);

  newing = zeros(row,column);
for i=1:row
    for j=1:column
        maxmembership=membership(i,j,1);
        index=1;
        for k=2:cluster_num
            if(membership(i,j,k)>maxmembership)
                maxmembership=membership(i,j,k);
                index=k;
            end
        end
        newing(i,j) = round(255 * (1-(index-1)/(cluster_num-1)));
    end
end

B = reshape(newing,1,data_n);
b = fix((max(B) - B(1,1)) / cluster_num);
for i = 2:data_n
    if B(1,i) == B(1,1)
        B(1,i) = 1;
    elseif (fix(B(1,i) / b) == 2)
        B(1,i) = 2;
    elseif (fix(B(1,i) / b)  == 3)
        B(1,i) = 3;
    else
        B(1,i) = 4;
    end
end
B(1,1) = 1;

sum = 0;
for i = 1:data_n
    if ( A(1,i) ~= B(1,i))
        sum = sum + 1;
    end
end
MCR = sum / data_n;
fprintf(‘MCR = %d\n‘,MCR);

S = 0;
for i = 1:data_n
    S = S + (A(1,i) - B(1,i)).^2;
end

RMS = sqrt(S / (data_n * (data_n -1)));
fprintf(‘RMS = %d\n‘,RMS);

figure(2);
imshow((uint8(newing)));
title(‘FCM分割后的图像‘);   

结果如下:

                

(3)还可以自定义图像进行测试,代码如下:

clear all
clc;

image = zeros(96,96); 

for i = 1:58
    for j = 49:96
        image(i,j) = 75;
    end
end

for i = 59:77
    for j = 1:96
        image(i,j) = 50;
    end
end

for i = 78:96
    for j = 1:48
        image(i,j) = 50;
    end
end

for i = 78:96
    for j = 49:96
        image(i,j) = 25;
    end
end

a = image;

noise = uint8(image);
noise = imnoise(noise,‘gaussian‘,100 / (255 * 255));
figure(1);
imagesc(noise);
colormap(gray);
title(‘加噪图像‘);

[height,width,c]=size(a);
if c~=1
    a=rgb2gray(a);
end

a=double(a);
[row,column]=size(a);
data = a(:);
data_n = size(data,1);

cluster_num = 4;
default_options = [10;    % 隶属度函数的幂次方
        300;    % 最大迭代次数
        1e-5;    %步长
        1];    % 判定条件

options = default_options;

expo = options(1);        % Exponent for U 隶属度函数的幂次方
max_iter = options(2);        % Max. iteration 最大迭代次数
min_impro = options(3);        % Min. improvement  最小进化步长
display = options(4);        % Display info or not 显示信息与否

obj_fcn = zeros(max_iter, 1);    % Array for objective function
membership = zeros(height,width,cluster_num);
center = zeros(cluster_num,1);

tic
% 初始化隶属度并归一
for i=1:height
    for j=1:width
        member_sum=0;
        for k=1:cluster_num
            membership(i,j,k)=rand();
            member_sum = member_sum + membership(i,j,k);
        end
        for p =1:cluster_num
            membership(i,j,p) = membership(i,j,p) / member_sum;
        end
    end
end

tic
for i = 1:max_iter,%迭代次数控制
    mf = membership.^expo;
    %%%%%%%%建立聚类中心
    for m = 1:cluster_num
        to = 0;
        tp =0;
        for j = 1:height
            for t = 1:width
                to = to + membership(j,t,m) * a(j,t);
                tp = tp + membership(j,t,m);
            end
        end
        center(m,1) = to / tp;
    end

    %%%%%%%得到欧式距离以及目标函数
    out = zeros(height,width,cluster_num);
    for m =1:height
        for j =1:width
            for t = 1:cluster_num
                out(m,j,t) = abs(a(m,j) - center(t,1));
                obj_fcn(i) = obj_fcn(i) + (membership(m,j,t).^expo) * (out(m,j,t).^2);
            end
        end
    end

    for m = 1:height
        for j = 1:width
            for r = 1:cluster_num
                top =0;
                for t = 1:cluster_num
                    top = top + (out(m,j,r) / out(m,j,t)).^(expo - 1);
                end
                membership(m,j,r) = 1 / top;
            end
        end
    end

    %%%%%%归一化隶属度
    for m=1:height
        for j = 1:width
            member_sum = 0;
            for k = 1:cluster_num
                member_sum = member_sum + membership(m,j,k);
            end
            for p = 1:cluster_num
                membership(m,j,p) = membership(m,j,p) / member_sum;
            end
        end
    end

     if display,
        fprintf(‘Iteration count = %d, obj. fcn = %f\n‘, i, obj_fcn(i));
        %输出迭代次数和函数的结果
    end
    % check termination condition
    if i > 1,  %进化步长控制
        if abs(obj_fcn(i) - obj_fcn(i-1)) < min_impro, break; end,
    end
end
toc
 A = ones(height,width,1);
for i = 1:height
    for j = 1:width
        if (a(i,j) == 75)
            A(i,j,1) = 2;
        end
        if (a(i,j) == 50)
            A(i,j,1) = 3;
        end
        if (a(i,j,1) == 25)
            A(i,j,1) = 4;
        end
    end
end
A = reshape(A,1,data_n);

  B = ones(row,column,1);
for i=1:row
    for j=1:column
        maxmembership=membership(i,j,1);
        for k=2:cluster_num
            if(membership(i,j,k)>maxmembership)
                maxmembership = membership(i,j,k);
                B(i,j,1)=k;
            end
        end
    end
end

B = reshape(B,1,data_n);

t = MCR(A,B);

%输出图像
  newing = zeros(row,column);
for i=1:row
    for j=1:column
        maxmembership=membership(i,j,1);
        index=1;
        for k=2:cluster_num
            if(membership(i,j,k)>maxmembership)
                maxmembership=membership(i,j,k);
                index=k;
            end
        end
        newing(i,j) = round(255 * (1-(index-1)/(cluster_num-1)));
    end
end
figure(2);
imagesc(uint8(newing));
colormap(gray);
title(‘FCM分割后的图像‘);    

结果如下:

                   

结果分析:

综上所示,计算得出误分类率为38.9%,所以说此算法还是准确率还有待提高。且当数据的特征复杂集合较大时,算法的实时性不是很可观;与许多聚类算法一样,FCM选择欧氏距离作为样本点与相应聚类中心之间的非相似性指标,致使算法趋向于发现具有相近尺度和密度的球星簇。

今天就先到这儿,之后将进一步对算法进行优化~

时间: 2024-10-05 04:01:31

FCM算法的相关文章

FCM算法文献总结

近年来,FCM 算法越来越受欢迎,被应用到各个领域范围,针对FCM算法的改进也越来越多.本文总结了近两年来的算法改进,如有改进算法不全请自己查找哦,论文太多啦.由于参考文献均为英文论文,这里就不翻译了,毕竟俺不是歪果仁. 2014年 D-FICCA (Density-based Fuzzy Imperialist Competitive Clustering Algorithm )参考文献:D-FICCA: a density-based fuzzy imperialist competitiv

聚类之详解FCM算法原理及应用

(一)原理部分 模糊C均值(Fuzzy C-means)算法简称FCM算法,是一种基于目标函数的模糊聚类算法,主要用于数据的聚类分析.理论成熟,应用广泛,是一种优秀的聚类算法.本文关于FCM算法的一些原理推导部分介绍等参考下面视频,加上自己的理解以文字的形式呈现出来,视频参考如下,比较长,看不懂的可以再去看看: FCM原理介绍 FCM分析1 FCM分析2 FCM分析3 首先介绍一下模糊这个概念,所谓模糊就是不确定,确定性的东西是什么那就是什么,而不确定性的东西就说很像什么.比如说把20岁作为年轻

FCM算法的matlab程序(初步)

FCM算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648430.html文章中已经介绍了FCM算法,现在用matlab程序实现它. 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.采用iris数据库 iris_data.txt 5.1 3.5 1.4 0.2 4.9 3 1.4 0.2 4.7 3.2 1.3 0.2 4.6 3.1 1.5 0.2 5 3.6 1.4 0.2 5.4 3.

FCM算法的matlab程序2

FCM算法的matlab程序2 在"FCM算法的matlab程序"这篇文章中已经用matlab程序对iris数据库进行实现,并求解准确度.下面的程序是另一种方法,是最常用的方法:先初始化聚类中心,在进行迭代(此方法由于循环较多,时间复杂度相对较高,但更严谨.就时间性而言,推荐使用"FCM算法的matlab程序"这个程序). 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.采用iris数据库 iris_data.tx

FCM聚类算法介绍

FCM算法是一种基于划分的聚类算法,它的思想就是使得被划分到同一簇的对象之间相似度最大,而不同簇之间的相似度最小.模糊C均值算法是普通C均值算法的改进,普通C均值算法对于数据的划分是硬性的,而FCM则是一种柔性的模糊划分.在介绍FCM具体算法之前我们先介绍一些模糊集合的基本知识. 1 模糊集基本知识 首先说明隶属度函数的概念.隶属度函数是表示一个对象x隶属于集合A的程度的函数,通常记做μA(x),其自变量范围是所有可能属于集合A的对象(即集合A所在空间中的所有点),取值范围是[0,1],即0<=

FCM

1. FCM初识 FCM的C跟K-Means的K是一样的,指的是聚类的数目.F—Fuzzy是模糊的意思,指的是”一个事件发生的程度“.用在我们的聚类上面,第一条记录以怎样的概率或者说程度属于第一类,又以怎样的程度属于第二类等等.跟传统的聚类有所区别的地方就是,他改变了分类的时候非此即彼的一个现象,一个对象可以以不同的程度同时属于多个类.这个其实是跟我们的现实世界是更契合的.比如说,“秃与不秃”,一个人有多少发量就说他是秃的,下面这几张图:     究竟那几个可以分成:秃“,这个就具有一定的模糊性

机器学习之实战朴素贝叶斯算法

贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类,而朴素贝叶斯分类可谓是里面最简单.入门的一种. 首先关于贝叶斯定理,感觉简单而伟大,前些天一直在看吴军的数学之美(没看过的极力推荐)系列文章,看到自然语言处理从规则模型到统计模型转变的时候,语言的识别准确率上升好几个等级,以至于今天的语言识别到达很强大的地步,同时对于搜索引擎,网页搜索的准确率,也上升好多.这其中的最最重要的就是使用了贝叶斯准则,运用一种统计学的概念,将识别搜索的结果可能性最大化.由此我联想到当今的

聚类——FCM的matlab程序

聚类--FCM的matlab程序 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 在聚类--FCM文章中已介绍了FCM算法的理论知识,现在用matlab进行实现. 1.matlab程序 FCM_main.m function [ave_acc_FCM,max_acc_FCM,min_acc_FCM,ave_iter_FCM,ave_run_time]=FCM_main(X,real_label,K) %输入K:聚的类,max_iter是最大迭代次数

MATLAB程序:用FCM分割脑图像

MATLAB程序:用FCM分割脑图像 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 脑图像基础知识请看:脑图像:FCM算法介绍请看:聚类——FCM:数据来源:BrainWeb: Simulated Brain Database,只选取脑图像中的0.1.2.3类,其余类别设为0.本文用到的数据:Simulated Brain Database 1. MATLAB程序 FCM_image_main.m function [accuracy,iter_F