K-Means

1.算法简述


分类是指分类器(classifier)根据已标注类别的训练集,通过训练可以对未知类别的样本进行分类。分类被称为监督学习(supervised learning)。如果训练集的样本没有标注类别,那么就需要用到聚类。聚类是把相似的样本聚成一类,这种相似性通常以距离来度量。聚类被称为无监督学习(unspervised learning)。


k-means是聚类算法中常用的一种,其中k的含义是指有k个cluster。由聚类的定义可知,一个样本应距离其所属cluster的质心是最近的(相较于其他k-1个cluster)。实际上,k-means的本质是最小化目标函数:


x为样本点,c为cluster。为了表示cluster,最简单有效的是取所有样本点平均,即质心(cluster centroid);这便是取名means的来由。


k-means算法流程如下:

选取初始k个质心(通常随机选取)

循环重复直至收敛

{    对每个样本,计算出与k个质心距离最近的那个,将其归为距离最新质心所对应的cluster

    重新计算质心,当质心不再变化即为收敛

}


代码参考[1,2],结果可视化请参考[2]

[python] view plaincopy在CODE上查看代码片派生到我的代码片
  1. import numpy as np  
  2. import scipy.spatial.distance as ssd  
  3. import matplotlib.pyplot as plt   
  4.   
  5. def read_file(fn):  
  6.     raw_file=open(fn)  
  7.     dataSet=[]  
  8.     for raw_row in raw_file.readlines():  
  9.         row=raw_row.strip().split('\t')  
  10.         dataSet.append((float(row[0]),float(row[1])))  
  11.   
  12.     return np.array(dataSet)  
  13.   
  14. def firstCentroids(k,dataSet):  
  15.     """create the first centroids"""  
  16.   
  17.     num_columns=dataSet.shape[1]  
  18.     centroids=np.zeros((k,num_columns))  
  19.     for j in range(num_columns):  
  20.         minJ=min(dataSet[:,j])  
  21.         rangeJ=max(dataSet[:,j])-minJ  
  22.         for i in range(k):  
  23.             centroids[i,j]=minJ+rangeJ*np.random.uniform(0,1)  
  24.     return np.array(centroids)  
  25.   
  26. def kmeans(k,dataSet):  
  27.     num_rows,num_columns=dataSet.shape  
  28.     centroids=firstCentroids(k,dataSet)  
  29.       
  30.     #store the cluster that the samples belong to  
  31.     clusterAssment=np.zeros((num_rows,2))  
  32.     clusterChanged=True  
  33.     while clusterChanged:  
  34.         clusterChanged=False  
  35.          
  36.         #find the closet centroid  
  37.         for i in range(num_rows):  
  38.             minDis=np.inf;minIndex=-1  
  39.             for j in range(k):  
  40.                 distance=ssd.euclidean(dataSet[i,:],centroids[j,:])  
  41.                 if distance<minDis:  
  42.                     minDis=distance;minIndex=j  
  43.   
  44.             if(clusterAssment[i,0]!=minIndex): clusterChanged=True  
  45.             clusterAssment[i,:]=minIndex,minDis**2  
  46.           
  47.         #update the centroid location  
  48.         for cent in range(k):  
  49.             ptsInCent=dataSet[np.nonzero(clusterAssment[:,0]==cent)[0]]  
  50.             centroids[cent,:]=np.mean(ptsInCent,axis=0)  
  51.   
  52.     return centroids,clusterAssment  


缺点:

  1. k-means是局部最优,因而对初始质心的选取敏感。换句话说,选取不同的初始质心,会导致不同的分类结果(当然包括差的了)。
  2. 选择能达到目标函数最优的k值是非常困难的。

2. Referrence


[1] Peter Harrington, machine learning in action.

[2] zouxy09, 机器学习算法与Python实践之(五)k均值聚类(k-means).

[3] the top ten algorithm in data mining, CRC Press.

posted @ 2015-11-14 21:27  StevenLuke  阅读(187)  评论(0编辑  收藏  举报