機器學習-聚類(clustering)算法:K-means算法

1. 歸類:python

      聚類(clustering):屬於非監督學習(unsupervised learning)算法

      無類別標記(class label)dom

2. 舉例:學習

          

 

3. Kmeans算法spa

    3.1 clustering中的經典算法,數據挖掘十大經典算法之一3d

    3.2 算法接受參數k;將事先輸入的n個數據對象劃分爲k個類以便使得得到的聚類知足:同一類中對象之間類似度較高,不一樣類之間對象類似度較小。orm

    3.3 算法思想對象

         以空間中k個點爲中心進行聚類,對最靠近他們的對象歸類。經過迭代的方法,逐次更新各聚類中心的值,直至獲得最好的聚類結果。blog

    3.4 算法描述utf-8

        1) 選擇適當的c個類的初始中心;

        2) 在第k次迭代中,對任意一個樣本,求其到c各中心的距離,將該樣本劃歸到距離最近的中心所在的類。

        3) 利用均值的方法更新該類的中心值,即經過求當前類全部點的均值來更新c的中心值

        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]之間的距離,將其劃分到距離最近的中心所屬的類,如data[j] 與c[i]距離最近,data[j]就標記爲i。

          3) 採用均值思想更新類中心,如對於全部標記爲i的點,從新計算c[i]={全部標記爲i的data[i]之和}/標記爲i的個數。

          4) 重複2) 3),直到全部的類中心值的變化小於給定閾值。

          流程圖:

           

 

      舉例:

             

      每一個實例對應座標:

 

 

 

                        

                        距離

                                           歸類

                                            中心點

                         更新後中心點

                           距離

                                                       歸類

                          更新中心點

                         更新後中心點

                        距離

                                                      歸類

                   中止!!!

           

 

    3.5 算法優缺點

       優勢:速度快、簡單

       缺點:最終結果和初始點選擇有關,容易陷入局部最優,須要知道k值。

 

# -*- coding:utf-8 -*-

import numpy as np

def kmeans(x, k, maxIt):

    numPoints, numDim = x.shape

    dataSet = np.zeros((numPoints, numDim + 1))
    dataSet[:, : -1] = x #dataSet全部行,從第一列到倒數第二列都等於x

    #隨機選取中心點 全部數據點 隨機選k行
    centrods = dataSet[np.random.randint(numPoints, size = k), :]
    #中心點的最後一列初始化值(類標籤):1到k
    centrods[:, -1] = range(1, k+1)

    iterations = 0

    oldCentrods = None

    while not shouldStop(oldCentrods, centrods, iterations, maxIt):
        print("iteration: \n", iterations)
        print("dataSet: \n", dataSet)
        print("centroids: \n", centrods)

        #爲何用copy而不是= 由於後面會作修改 oldCentrods和centrods是兩部份內容
        oldCentrods = np.copy(centrods)
        iterations += 1

        #更新類標籤
        updateLabels(dataSet, centrods)

        #更新中心點
        centrods = 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] = getLabelFromCosestCentroid(dataSet[i, : -1], centroids)

def getLabelFromCosestCentroid(dataSetRow, centroids):
    label = centroids[0, -1]#初始化本條數據類標籤爲第一個中心點的類標籤
    minDis = np.linalg.norm(dataSetRow - centroids[0, : -1]) #調用內嵌的方法算距離 一直在更新
    for i in range(1, centroids.shape[0]):#求與每一箇中心點之間的距離
        dis = np.linalg.norm(dataSetRow - centroids[i, : -1])
        if dis < minDis:
            minDis = dis
            label = centroids[i, -1]
    print("minDist:", minDis)
    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("result:" ,result)
相關文章
相關標籤/搜索