K-means算法及Matlab实现


K-MEANS CLUSTERING

方法介绍

K-means 是经典的聚类算法,也是数据挖掘十大经典算法之一。聚类思想就是无监督学习中将较为相似的数据归为一类的,正所谓“物以类聚,人以群分”,大约就是这样,而 K- means 就是聚类算法中最为简洁,高效的一种,他是用于在无监督学习中,在一群未标注的数据中寻找聚类(culster)和聚类中心(cluster center)的方法。

  • 核心思想:选定 K 个聚类中心, 通过算法不断迭代移动中心位置以极小化聚类集群内部的方差总和。

算法介绍

  • 当我们给定了初始中心以后,K-means 算法交替进行两个步骤:
    1、对每一个中心我们识别出比起别的任何聚类点离某个聚类点更近的子群。
    2、计算出每个集群中的数据点的特征均值,这个均值向量就成为这个集群的新的中心。 重复迭代这两步,直到算法收敛。

K-means 优缺点

  • 优点:
    1、 计算时间短,收敛速度快。
    2、需要调参的话就只要 K 一个参数。(iii) 容易解释。
  • 缺点:
    1、初始 K 值需要预先给定:而这个很大程度取决于经验,但是这个 K 值是否能正确选取,也决定了 K-means 能否有效率的正确分类。
    2、K-means 相当依赖一开始选取的聚类中心,而开始的聚类中心是随机选取的也就是说有相当比例的只能取得局部最小值而无法取得全局最小值。
    3、K-means 无法适用于所有的数据集类型。
    4、对于过于离散的点和奇异点的聚类效果也不好。

CODE

MATLAB代码
主程序

%% input the data  
A = load('testSet.txt');  
  
%% 计算质心  
centroids = kMeans(A, 4);  

随机选取质心

%% 取得随机中心  
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的主程序

[plain] view plain copy
%% kMeans的核心程序,不断迭代求解聚类中心  
	function [ centroids ] = kMeans( dataSet, k )  
	    [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  
	            centroids(j,:) = sum./r;  
	        end  
	    end  
	      
	    %% 完成作图  
	    hold on  
	    for i = 1:m  
	        switch subCenter(i,1)  
	            case 1  
	                plot(dataSet(i,1), dataSet(i,2), '.b');  
	            case 2  
	                plot(dataSet(i,1), dataSet(i,2), '.g');  
	            case 3  
	                plot(dataSet(i,1), dataSet(i,2), '.r');  
	            otherwise  
	                plot(dataSet(i,1), dataSet(i,2), '.c');  
	        end  
	    end  
	    plot(centroids(:,1),centroids(:,2),'+k');  
	end  

实验验证

       取一散点数据集,包含 90 组二维数据,如图 1 所示:
在这里插入图片描述
       通过观察我们选取 K=4,即希望将数据分为四类,目测观察我们可知数据大致上是左上, 左下,右上,右下四类,运行算法后我们得到图 2。
图 1.2. 利用 K-means 得到的正确的聚类结果

图 1.2. 利用 K-means 得到的正确的聚类结果

       图 2 基本满足我们原本对于数据聚类的预期。但是是否每次都是得到图 2 这样的表示呢?
       事实上并不是的,对于其中的某些奇异点在大部分聚类中,摇摆不定的状态。当我连续出图 20-50 张的时候我们发现了有一定比例会得到类似于       图 3 右上角的分类状态(试验次数较小并 不能完全确定正确率,当实验 50 次的时候错误率大约在 10—15%),也就是即使我们选对了 K 的值,当初始的点没有随机到正确的集群的时候,分类也会出现偏差。
       同时我们选取了不同的 K 值,3,4,5,6 在的得到的实验结果中我们选取图 3 为例,可 以观察到不同 K 值对分类是否正确有着决定性作用的。
在这里插入图片描述

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值