用matlab实现k-means聚类
来源:互联网 发布:西安软件测试招聘 编辑:程序博客网 时间:2024/06/04 23:26
用matlab实现k-means聚类
本文是大三下学期课程《数据分析方法》中的一些简单实现,部分内容摘自《大数据分析:方法和应用》一书。本文仅作为学习总结用,不作商用
本文思路:
聚类的概念
k-means算法的思路和步骤
matlab的实现
运行结果分析
一、聚类的概念
聚类是数据挖掘比较常见的方法,也相对比较简单。
聚类分析的目的在于把分类对象按一定的规则分成若干类,这些类没有预先给定,而是根据数据的特征而确定的,对于类的数目以及类的结构不用作任何假定。聚类和分类是不一样的,聚类的类似并没有事先确定,聚类属于搜索簇的无监督学习过程。而分类,就是根据文本的特征或属性,将待分类点划分到已有的类别中。分类属于有监督学习。
聚类分析根据分类对象的不同还分为Q型聚类分析和R型聚类分析。Q型聚类分析是指对样品的聚类,R型聚类分析是指对变量的聚类。
二、k-means算法的思路和步骤
k-means算法是一种应用范围比较广的聚类方法。其思想在于在给定的聚类数k时,通过最小化组内误差平方和来得到每一个样本点的分类。
步骤:
- 1.先在所有的样本(n个)中随机选择k个样本点作为初始的聚类中心;
- 2.计算k个聚类中心到剩下的n-k个样本点的距离,根据剩下的n-k个样与聚类中心的距离,分别将它们分到与其最近的中心的类中;
- 3.计算每个新类的聚类中心;
- 4.重复2、3,直到所有样本点的分类不再改变或者类中心不再改变。
三、matlab的实现
由于我使用的是学生成绩作为训练集,学生成绩分为两类(及格和不及格),因此在训练的时候,k=2,这里的k是通用的,可以是其他值。
使用工具:matlab2015b
训练集:88个学生成绩,每个样本维数为2,平时成绩和期末成绩,其中及格人数为51,不及格人数为37。
程序一
这个程序是刚开始做的,当时想着找一个“容器”来储存类别,后来发现元胞数组能实现这种功能(储存“一堆”行数不同的矩阵),元胞数组其实有点像R语言中的“dataframe”,其中的元素可以多种多样
function [Class,temp,new_C,iter] =k_means(train,k)%train是训练的样本,k是自行设定的聚类数%这个程序是针对k的聚类,元胞数组,添加了IDX[n,dim]=size(train);train=[train zeros(n,1)];r=randsample(n,k);%r是从n中随机不重复抽出k个整数C=train(r,1:end-1);delta=ones(1,1);tao=0.001;iter=0;while delta>=tao D=[];train(:,end)=0; %计算样本到聚类中心的距离 for j=1:k D=[D,sqrt(sum((repmat(C(j,:),n,1)-train(:,1:end-1)).^2,2))]; end Class=cell(k,1);%将样本归类 for i=1:n [~,d]=min(D(i,:)); Class{d,1}(i,:)=train(i,:); train(i,dim+1)=d; end new_C=zeros(k,dim); %计算新的聚类中心 for j=1:k M=cell2mat(Class(j,1)); M(all(M==0,2),:)=[]; Class{j,1}=M; new_C(j,:)=mean(Class{j,1}(:,1:end-1)); end delta=norm(new_C-C);%计算上一次的聚类中心与新的聚类中心的距离 C=new_C; iter=iter+1; temp=train;endend
运行结果
>> [Class,temp,new_C,iter] =k_means(train,k)Class = [36x3 double] [52x3 double]temp = 60 0 2 50 53 2 70 76 1 60 61 2 90 59 1 60 25 2 80 78 1 90 59 1 90 80 1 60 76 2 70 60 2 60 53 2 80 53 1 90 61 1 95 65 1 100 41 1 90 68 1 60 64 2 100 69 1 80 38 2 90 76 1 60 61 2 100 73 1 100 71 1 60 48 2 60 61 2 60 58 2 100 53 1 80 43 2 100 69 1 100 59 1 60 73 2 90 32 2 100 76 1 100 83 1 75 38 2 80 59 1 60 60 2 50 73 2 80 40 2 70 43 2 70 46 2 80 73 1 70 71 2 100 71 1 100 53 1 80 67 1 100 65 1 50 33 2 50 53 2 50 46 2 90 48 1 60 25 2 100 78 1 60 25 2 70 62 2 90 59 1 60 51 2 60 68 2 60 70 2 100 40 1 100 50 1 60 53 2 60 56 2 60 51 2 50 31 2 60 11 2 60 58 2 70 20 2 70 43 2 60 38 2 95 63 1 90 48 1 70 56 2 60 48 2 60 36 2 80 63 1 100 66 1 60 38 2 60 63 2 100 63 1 70 69 2 60 25 2 60 50 2 90 64 1 70 59 2 70 68 2 60 35 2new_C = 92.7778 63.8611 62.9808 48.4231iter = 5
程序二
这个程序比前面的改进了,没有用元胞数组来储存类,而是在每一次归类的时候在训练集train后面直接添加索引。
function [temp,new_C,iter,k1,k2] =k_means2(train,k)%改进版,不用元胞数组[n,dim]=size(train);train=[train zeros(n,1)];r=randsample(n,k);%r是从n中随机不重复抽出k个整数C=train(r,1:end-1);delta=ones(1,1);tao=0.001;iter=0;while delta>tao D=[];train(:,end)=0;%在训练样本的最后添加一列,用来记录类号 for j=1:k D=[D,sqrt(sum((repmat(C(j,:),n,1)-train(:,1:end-1)).^2,2))]; end for i=1:n [~,d]=min(D(i,:)); train(i,dim+1)=d; end new_C=zeros(k,dim); for j=1:k new_C(j,:)=mean(train(train(:,end)==j,1:dim)); end delta=norm(new_C-C);%计算上一次的聚类中心与新的聚类中心的聚离 C=new_C; iter=iter+1; temp=train;%temp最后输出的是带有类号的训练集endplot(temp(temp(:,end)==1,1),temp(temp(:,end)==1,2),'b*');hold on;plot(temp(temp(:,end)==2,1),temp(temp(:,end)==2,2),'r*');k1=size(temp(temp(:,end)==1,:),1);%统计1类的数目k2=size(temp(temp(:,end)==2,:),1);%统计2类的数目end
运行结果
>> [temp,new_C,iter,k1,k2] =k_means2(train,k)temp = 60 0 2 50 53 2 70 76 1 60 61 2 90 59 1 60 25 2 80 78 1 90 59 1 90 80 1 60 76 2 70 60 2 60 53 2 80 53 1 90 61 1 95 65 1 100 41 1 90 68 1 60 64 2 100 69 1 80 38 2 90 76 1 60 61 2 100 73 1 100 71 1 60 48 2 60 61 2 60 58 2 100 53 1 80 43 2 100 69 1 100 59 1 60 73 2 90 32 1 100 76 1 100 83 1 75 38 2 80 59 1 60 60 2 50 73 2 80 40 2 70 43 2 70 46 2 80 73 1 70 71 2 100 71 1 100 53 1 80 67 1 100 65 1 50 33 2 50 53 2 50 46 2 90 48 1 60 25 2 100 78 1 60 25 2 70 62 2 90 59 1 60 51 2 60 68 2 60 70 2 100 40 1 100 50 1 60 53 2 60 56 2 60 51 2 50 31 2 60 11 2 60 58 2 70 20 2 70 43 2 60 38 2 95 63 1 90 48 1 70 56 2 60 48 2 60 36 2 80 63 1 100 66 1 60 38 2 60 63 2 100 63 1 70 69 2 60 25 2 60 50 2 90 64 1 70 59 2 70 68 2 60 35 2new_C = 92.7027 63.0000 62.4510 48.7451iter = 4k1 = 37
结果分析:
- 程序一和程序二的运行时间和聚类效果别无二致,思路也大致相同。但是程序二更加好理解,因为不用元胞数组。
- 实现的k-means聚出来的类数和实际情况有时会有差别(最多差别3个),也存在误判的情况,误判主要集中的边界处。
- 聚类分析更加适合于大样本数据,样本数据少时,聚类效果不会很好。
k-means聚类存在的问题
- 容易受到初始聚类中心选择的影响,在分类数据上分辨力不强,不适用于非凸问题,容易受到异常数据的影响。
- 用matlab实现k-means聚类
- matlab实现k-means聚类
- K-Means聚类MATLAB实现
- k-means 算法matlab实现
- k-Means算法Matlab实现
- MATLAB实现K-means算法
- Matlab实现k-means聚类算法
- matlab下K-means Cluster 算法实现
- K-Means聚类算法 --Matlab实现
- K-means原理及Matlab实现
- matlab练习程序(k-means聚类)
- matlab练习程序(k-means聚类)
- K-Means 和K-Medoids算法及其MATLAB实现
- K-Means 和K-Medoids算法及其MATLAB实现
- K-means 熟悉matlab
- K-means Matlab代码
- K-means matlab
- MapReduce 实现k-means聚类
- Android 蓝牙开发(十)A2DP源码分析
- C++ vector容器类型
- 有关Unity3D在VR领域的优化措施
- MicroPython是未来?当Python遇上单片机!
- tensorflow:tf.nn.conv2d是怎样实现卷积的?
- 用matlab实现k-means聚类
- a:hover实例
- The Blocks Problem-UVA 101
- UILabel + UITextView 字间距和行间距
- 个人学习总结一机器学习入门(三)
- React Native 开发常见错误
- POJ 1178 Camelot 最短路 Floyd +枚举
- Node.js 定时器
- WKWebView 遇到过的坑