一、FCM聚类
1.简介
模糊C均值聚类(FCM),即模糊ISODATA,是用隶属度确定每个数据点属于某个聚类的程度的一种聚类算法。1973年,Bezdek提出了该算法,作为早期硬C均值聚类(HCM)方法的一种改进。
2.基本步骤
(1)选择初始聚类中心Zi(0)
(2)计算初始隶属度矩阵U(0)
(3)求各类的新的聚类中心Zi(L)
(4)计算新的隶属度矩阵U(L+1)
(5) 回到第(3)步,重复至收敛
(6)类别调整:①合并②分解③删除
3.FCM算法原理
模糊C均值(Fuzzy C-means)算法简称FCM算法,是一种基于目标函数划分的模糊聚类算法,主要用于数据的聚类分析。它的思想就是使得被划分到同一簇的对象之间相似度最大,而不同簇之间的相似度最小。
FCM把n个向量xi(i=1,2,…,n)分为c个模糊组,并求每组的聚类中心,使得非相似性指标的价值函数达到最小。FCM使得每个给定数据点用值在0,1间的隶属度来确定其属于各个组的程度。隶属矩阵U允许有取值在0,1间的元素。不过,加上归一化规定,一个数据集的隶属度的和总等于1
这里uij介于0,1间;ci为模糊组I的聚类中心,dij=||ci-xj||为第I个聚类中心与第j个数据点间的欧几里德距离;且m∈[1,∞)是一个加权指数。
构造如下新的目标函数,可求得使(6.10)式达到最小值的必要条件:
这里λj,j=1到n,是(6.9)式的n个约束式的拉格朗日乘子。对所有输入参量求导,使式(6.10)达到最小的必要条件为
由上述两个必要条件,模糊C均值聚类算法是一个简单的迭代过程。
二、代码实现
1.数据集介绍
测试数据集用的是鸢尾花(iris)数据集。下载地址
2.代码
function [U, V,objFcn] = myfcm(data, c, T, m, epsm)
% fuzzy c-means algorithm
% 输入: data: 待聚类数据,n行s列,n为数据个数,s为每个数据的特征数
% c : 聚类中心个数
% m : 模糊系数
% 输出: U : 隶属度矩阵,c行n列,元素uij表示第j个数据隶属于第i类的程度
% V : 聚类中心向量,c行s列,有c个中心,每个中心有s维特征
% written by Zhang Jin
% see also : mydist.m myplot.m
if nargin < 3
T = 100; %默认迭代次数为100
end
if nargin < 5
epsm = 1.0e-6; %默认收敛精度
end
if nargin < 4
m = 2; %默认模糊系数值为2
end
[n, s] = size(data);
% 初始化隶属度矩阵U(0),并归一化
U0 = rand(c, n);
temp = sum(U0,1);
for i=1:n
U0(:,i) = U0(:,i)./temp(i);
end
iter = 0;
V(c,s) = 0; U(c,n) = 0; distance(c,n) = 0;
while( iter<T )
iter = iter + 1;
% U = U0;
% 更新V(t)
Um = U0.^m;
V = Um*data./(sum(Um,2)*ones(1,s)); % MATLAB矩阵相乘啊,好东西
% 更新U(t)
for i = 1:c
for j = 1:n
distance(i,j) = mydist(data(j,:),V(i,:));
end
end
U=1./(distance.m.*(ones(c,1)*sum(distance.(-m))));
objFcn(iter) = sum(sum(Um.*distance.^2));
% FCM算法停止条件
if norm(U-U0,Inf)<epsm
break
end
U0=U;
end
myplot(U,objFcn);
function d = mydist(X,Y)
% 计算向量Y到向量X的欧氏距离的开方
d = sqrt(sum((X-Y).^2));
end
function myplot(U,objFcn)
% 将隶属度U矩阵可视化
figure(1)
subplot(3,1,1);
plot(U(1,:),’-b’);
title(‘隶属度矩阵值’)
ylabel(‘第一类’)
subplot(3,1,2);
plot(U(2,:),’-r’);
ylabel(‘第二类’)
subplot(3,1,3);
plot(U(3,:),’-g’);
xlabel(‘样本数’)
ylabel(‘第三类’)
figure(2)
grid on
plot(objFcn);
title(‘目标函数变化值’);
xlabel(‘迭代次数’)
ylabel(‘目标函数值’)
3.结果截图
可以看到,大约迭代了8次左右,目标函数开始收敛,从隶属度矩阵上可以看出,第一类与其它类区分较为明显,第二类和第三类比较相似,区分度有所降低。
三、K-means聚类实现
1.K-means算法基本原理
k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法。其实现过程如下:
第一步:从文件中读取数据,点用元组表示;确定聚类个数k。
第二步:初始化k个聚类中心。在所获得的的样本区间范围内随机产生k个值作为初始质心。
第三步:对每个数据点进行分类,选择相似度最高的质心所在的簇作为该样本的类别,形成k个簇。
第四步:计算每个簇中所有点的平均值,更新聚类中心。
第五步:迭代3~4步,直至聚类中心不再更改或达到最大迭代次数,算法结束。
2.Matlab代码
与上述FCM聚类算法实现一样,首先进行数据导入(主程序):
fid=fopen(‘wine.txt’);
spec=’%f %f %f %f %f %f %f %f %f %f %f %f ‘;
quality=textscan(fid,spec,‘Delimiter’,’;’);
data=zeros(2024,11);
flag=zeros(1,11);
for i=1:2024
k=1;
for j=1:11
flag(1,k)=quality{1,j}(i,1);
k=k+1;
end
data(i,:)=flag;
end
[ subCenter,centroids ] = kMeans1(data, 11);
随机选取质心:
function [ centroids ] = randCent( dataSet, k ) %% 取得随机中心
[m,n] = size(dataSet);%取得列数
centroids = zeros(k, n);
for j = 1:n
minJ = min(dataSet(:,j));
rangeJ = max(dataSet(:,j))-min(dataSet(:,j));
centroids(:,j) = minJ+rand(k,1)*rangeJ;%产生区间上的随机数
end
end
计算相似性:
function [ dist ] = distence( vecA, vecB )
dist = (vecA-vecB)*(vecA-vecB)’;%这里取欧式距离的平方
end
K-means主程序:
function [ subCenter,centroids ] = kMeans1( dataSet, k ) %% kMeans的核心程序,不断迭代求解聚类中心
[m,n] = size(dataSet);
%初始化聚类中心
centroids = randCent(dataSet, k);
subCenter = zeros(m,2); %做一个m*2的矩阵,第一列存储类别,第二列存储距离
change = 1;%判断是否改变
while change == 1
change = 0;
%对每一组数据计算距离
for i = 1:m
minDist = inf;
minIndex = 0;
for j = 1:k
dist= distence(dataSet(i,:), centroids(j,:));
if dist < minDist
minDist = dist;
minIndex = j;
end
end
if subCenter(i,1) ~= minIndex
change = 1;
subCenter(i,:)=[minIndex, minDist];
end
end
%对k类重新计算聚类中心
for j = 1:k
sum = zeros(1,n);
r = 0;%数量
for i = 1:m
if subCenter(i,1) == j
sum = sum + dataSet(i,:);
r = r+1;
end
end
if r~=0
centroids(j,:) = sum./r;
end
end
end
end
三、结果分析
K-Means聚类算法的优点主要集中在:
1.算法快速、简单;
2.对大数据集有较高的效率并且是可伸缩性的;
3.时间复杂度近于线性,而且适合挖掘大规模数据集。K-Means聚类算法的时间复杂度是O(nkt) ,其中n代表数据集中对象的数量,t代表着算法迭代的次数,k代表着簇的数目。
K-Means聚类算法的缺点:
① 在 K-means 算法中 K 是事先给定的,这个 K 值的选定是非常难以估计的。很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适。这也是 K-means 算法的一个不足。
② 在 K-means 算法中,首先需要根据初始聚类中心来确定一个初始划分,然后对初始划分进行优化。这个初始聚类中心的选择对聚类结果有较大的影响,一旦初始值选择的不好,可能无法得到有效的聚类结果,这也成为 K-means算法的一个主要问题。
③ 从 K-means 算法框架可以看出,该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的。所以需要对算法的时间复杂度进行分析、改进,提高算法应用范围。