【机器学习】10.K-means算法

1.归类:

    聚类属于非监督学习

    无类别标记


2.举例

                                                                


3.K-means算法

    3.1 Clustering中的经典算法,数据挖掘十大经典算法之一

    3.2 算法接受参数k,然后将事先输入的n个数据对象划分为k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高,而不同聚类中的对象相似度较小。

    3.3 算法思想:

        以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直到得到最好的聚类结果。

    3.4 算法描述:

        (1)适当选择c个类的初始中心;

        (2)在第k次迭代中,对任意一个样本,求其到c各中心的距离,将该样本归到距离最短的中心所在的类;

        (3)利用均值等方法更新该类的中心值

        (4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束。否则继续迭代。

    3.5 算法流程:

        输入:k,data[n]

            (1)选择k个初始中心点,例如c[0]=data[0],...c[k-1]=data[k-1];

            (2)对于data[0],....,data[n],分别与c[0]...c[k-1]比较,假定与c[i]差值最少,就标记为i;

            (3)对于所有标记为i点,重新计算c[i]={所有标记为i的data[j]之和}/标记为i的个数;

            (4)重复(2)(3),直到所有c[i]的值的变化小于给定阈值,


4.举例

                                                    

                                    

                                                    

                                                        (D0上下两行分别表示各个点到A点和到B点距离)


                                                            (BCD归为1类,A单独归为1类)


                                                             (新的中心点)

                                                    

                                                    (中心点更新后)

                                                        

                                                             

              


                                                        (新的中心点)

                                                        

                                                        (再次更新中心点后)

                和上一轮结果一样,所以停止。

                                        

        优点:速度快,简单

        缺点:最终结果跟初始点选择有关,容易陷入局部最优,需直到k值。

5.Python实现

import numpy as np
from scipy.cluster.hierarchy import centroid

def kmeans(X,k,maxIt):                      #输入数据、k值,最大迭代次数
    numPoints,numDim=X.shape
    dataSet=np.zeros((numPoints,numDim+1))
    dataSet[:,:-1]=X
    
    #随机选取k个中心点作为初始化中心点
    centroids=dataSet[np.random.randint(numPoints,size=k)]  #随机选行2行数,选所有列数
    centroids[:,-1]=range(1,k+1)                            #所有行赋标签
    
    iterations=0
    oldCentroids=None                                       
    
    while not shouldStop(oldCentroids,centroids,iterations,maxIt):
        print"iteration:\n",iterations
        print"dataSet:\n",dataSet
        print"centroids:\n",centroids
        
        oldCentroids=np.copy(centroids)                     #深复制
        iterations+=1
        
        updateLabels(dataSet,centroids)
        centroids=getCentroids(dataSet,k)
        
    return dataSet

##判断是否需要结束迭代
def shouldStop(oldCentroids,centroids,iterations,maxIt):
    if iterations>maxIt:                                        #是否超过迭代次数
        return True
    return np.array_equal(oldCentroids,centroids)               #比较值是否相等
##

def updateLabels(dataSet,centroids):
    numPoints,numDim=dataSet.shape
    for i in range(0,numPoints):
        dataSet[i][-1]=getLabelFromClosestCentroid(dataSet[i,:-1],centroids)                #把距离最近的中心点的标签赋给此数据
        
def getLabelFromClosestCentroid(dataSetRow,centroids):
    label=centroids[0,-1]
    minDist=np.linalg.norm(dataSetRow-centroids[0,:-1])                     #此函数返回两个向量的距离
    for i in range(1,centroids.shape[0]):
        dist=np.linalg.norm(dataSetRow-centroids[i,:-1])    
        if dist<minDist:
            minDist=dist
            label=centroids[i,-1]
    print"minDist",minDist 
    return label   

def getCentroids(dataSet,k):
    result=np.zeros((k,dataSet.shape[1]))
    for i in range(1,k+1):
        oneCluster=dataSet[dataSet[:,-1]==i,:-1]                #所有标签为i的点
        result[i-1,:-1]=np.mean(oneCluster,axis=0)              #横跨所有行,求均值
        result[i-1,-1]=i
        
    return result

x1=np.array([1,1])
x2=np.array([2,1])
x3=np.array([4,3])
x4=np.array([5,4])
testX=np.vstack(x1,x2,x3,x4)                                      #传入矩阵

result=kmeans(testX,2,10)
print"final result:"
print result         
        

阅读更多

没有更多推荐了,返回首页