小白如何用matlab实现高维K-means算法

K-means认识

本算法与之前的最速下降法一样是机器学习里的一个基本算法,广泛运用于人工智能领域里图像识别等。K-means算法通常可以应用于维数、数值都很小且连续的数据集,比如:从随机分布的事物集合中将相同事物进行分组。

数据集在此,提取码为u1s1

代码

clear; %清除工作空间的内容
clc; %清除命令窗口的内容
data=xlsread('sonar.xls','A1:BH208'); %读取excel文件里的数据
daan=xlsread('sonar.xls','BI1:BI208'); %读取最后一列作为分类的标准答案
[m,n]=size(data); %m为行数,n为列数
C1=data(randperm(m,1),:); %随机初始化第一个聚类中心
C2=data(randperm(m,1),:); %随机初始化第二个聚类中心
pd=zeros(m,100); %创建一个矩阵存放每一个点所属的类
num=0; %初始化迭代次数
L1=zeros(1,n); %初始化存放第一类点的矩阵
L2=zeros(1,n); %初始化存放第一类点的矩阵
distance=[]; %建立一个矩阵,记录两个中心点随迭代次数改变而距离改变的值
while 1 %迭代开始
    L1=[]; %初始化存放第一类点的矩阵
    L2=[]; %初始化存放第一类点的矩阵
    numL1=0; %初始化每一类中点的个数
    numL2=0; %初始化每一类中点的个数
    num=num+1; %记录迭代的次数
    for i=1:m
        x_temp=data(i,:); %将每一个点都拿出来计算与两个中心点的距离
        d1=norm(x_temp-C1); %计算该点距离第一类中心点的距离
        d2=norm(x_temp-C2); %计算该点距离第二类中心点的距离
        if (d1<=d2) %若该点的距离到第一个中心点的距离更小
            pd(i,num)=1; %则将该点定义为第一类
            L1=[L1;data(i,:)]; %将该行向量存放到L1矩阵内
            numL1=numL1+1; %更新第一类中点的个数
        else
            pd(i,num)=2; %否则该点为第二类
            L2=[L2;data(i,:)]; %将该行向量存放到L2矩阵内
            numL2=numL2+1; %更新第二类中点的个数
        end
    end
    epsilon=0.01; %定义一个epsilon的值
    C11=C1; %保留前一次的第一类中心点C1
    C22=C2; %保留前一次的第一类中心点C2
    C1=mean(L1); %求出第一个簇的重心,更新中心点
    C2=mean(L2); %求出第二个簇的重心,更新中心点
    distance=[distance;norm(C11-C22)]; %记录最新中心点的距离
    dc1=norm(C1-C11); %计算第一个簇前后两个中心点的距离
    dc2=norm(C2-C22); %计算第二个簇前后两个中心点的距离
    if (dc1<epsilon&&dc2<epsilon) %判断距离是否小于epsilon
        break; %若小于epsilon,则停止迭代
    end
end
Center=[C1;C2]; %输出两个中心点
%现在开始计算每一次迭代的正确率,并作图
accuracy=zeros(1,num); %创建一个存放每一次迭代正确率的矩阵
for i=1:num  %每一列比较
    trueA=0; %初始化第一种情况对的个数
    trueB=0; %初始化第二种情况对的个数
    for j=1:m
        if(abs(daan(j,1)-pd(j,i))==1) %第一种情况,比较第i次迭代出的结果分类与标准分类相反
            trueA=trueA+1; %更新对的个数
        end
    end
    for j=1:m
        if(abs(daan(j,1)-pd(j,i))==0) %第二种情况,比较第i次迭代出的结果分类与标准分类相同
            trueB=trueB+1;  %更新对的个数
        end
    end
    if (trueA>=trueB) %比较两种情况对的个数,保证迭代的正确率最大
        true=trueA; %将正确率相对较高的情况保留
    end
    if (trueA<trueB) %比较两种情况对的个数,保证迭代的正确率最大
        true=trueB; %将正确率相对较高的情况保留
    end
    zql=true/m; %计算正确率
    accuracy(1,i)=zql; %将每一次的正确率保留到矩阵内
end
disp(Center); %输出两个中心点
t=1:1:num;
ax1=subplot(2,1,1); %创建子图一
plot(ax1,t,accuracy,'r-*'); %作出正确率随迭代次数更新而变化的图像
title(ax1,'K-means accuracy curve'); %设置图像标题
xlabel(ax1,'number of iterations'); %设置x轴说明
ylabel(ax1,'accuracy'); %设置y轴说明
distance=distance'; %列向量转置为行向量
k=1:1:num;
ax2=subplot(2,1,2); %创建子图二
plot(ax2,k,distance,'c-o'); %作出两个簇心随迭代次数改变距离的改变图像
title(ax2,'K-means heart distance cluster'); %设置图像标题
xlabel(ax2,'number of iterations'); %设置x轴说明
ylabel(ax2,'heart distance cluster'); %设置y轴说明
        
        
        

实现结果

心得体会

1、数据是一个六十维的点集,但此程序并无用到降维的方法。
2、第一幅子图显示的是每一次迭代的正确率的变化,上图只是其中某一次的结果图,事实上每一次的运行结果迭代的正确率曲线并不相同,有时会上升有时会下降,这取决于一开始随机选的簇心的位置。通过大量运行结果表明,但此算法的正确率最终会稳定在0.54-0.57之间。通过matlab自带的K-means函数进行测试发现,正确率几乎是一样的。
3、第二幅图是我用来记录两个簇心之间的距离的,最终会稳定在1.25左右。
通过改变epsilon的值我发现,在epsilon在0.01小于等于时,迭代次数几乎不会改变,因此在这里我把epsilon设置为0.01。
4、在每一次迭代的过程中,都会有两个新的簇心产生,通过再次分析每一个数据与簇心间的欧氏距离来划分为新的类,实现类的更新。
在计算正确率的时候,因为两个类是一个相对的关系,我们应该选取正确率高的分类方式,每一次得出的正确率都应该大于0.5。
5、本程序运用到了文件的读取、矩阵的基本使用方法、函数的使用、作图等方式实现。

本算法存在的缺陷

1、 不同初始点的选取会导致聚类结果不同,因为我采取的是随机选取一个点,所以每一次运行出来的簇心并不相同。
2、 K值需要预先设定,在本算法中K为2,但是一般情况下我们需要判断并选取合适的K值,正因如此,本题难度大大地降低了。
3、 正确率较低,可能与没有用到降维有关?且规定的是欧氏距离,还有曼哈顿距离、余弦距离等计算两个点之间距离的方法。

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值