1. 程式人生 > >K-Means聚類演算法小結

K-Means聚類演算法小結

1.基本概念

K-Means演算法是一種很典型的基於距離的聚類演算法,採用距離作為相似性的評價標準,認為兩個物件的距離越近,那麼相似度就越大。把簇作為距離靠近的物件組成的,最終得到的是緊湊和獨立的簇。對於聚類分析來說,用於發現數據物件之間的關係。組內的相似性越大,組間的相似性越小,可以說效果越好。K個初始類聚類中心點的選取對聚類結果具有比較大的影響。在演算法的第一步中隨機的選取了K個初始聚類的中心,代表了一個簇。在每次迭代的過程中,對資料集中剩餘的每個物件。根據每個簇中心的距離將每個物件重新賦給最近的族。

2.演算法的基本過程為:

1.首先從N個文件中選取K個文件

2.對剩餘的每個文件測量其到質心的距離,並把它歸到最近的質心的類。

3.重新計算已經得到的各個類的質心。

4.迭代2~3步直至新的質心與原質心相等或小於指定閾值。

3.工作原理

輸入:聚類個數k,以及包含n個數據物件的資料庫。

輸出:滿足方差最小標準的k個聚類。

相關程式碼:

from numpy import *
import kMeans

def Kmeans(dataSet,k,distMeans=distEclud,createCent = randCent):
    #樣本數
    m = shape(dataSet)[0]
    #m*2的矩陣
    clusterAssment = mat(zeros(m,2))
    #初始化k箇中心
    centroids = createCent(dataSet,k)
    clusterChanged = True
    #當聚類不在變化
    while clusterChanged:
        clusterChanged = False
        for i in range(m):
            minDist = inf
            minIndex = -1;
            #找到最近的距離
            for j in range(k):
                distJI = distMeas(centroids[j,:],dataSet[i,:])
                if distJI < minDist:
                    minDist = distJI
                    minIndex = j

            if clusterAssment[i,:] != minIndex:
                clusterChanged = True;
            #第一列為所屬質心,第二列為距離
            clusterAssment[i,:] = minIndex,minDist**2;
        print(centroids)

        #更改質心位置
        for cent in range(k):
            ptsInClust = dataSet[nonzero(clusterAssment[:,0].A == cent)[0]]
            centroids[cent,:] = mean(ptsInClust,axis=0)
    return centroids,clusterAssment

def loadDataSet(fileName):
    dataMat = []
    fr = open(fileName)
    for line in fr.readline():
        curLine = line.strip().split('\t')
        fltLine = map(float,curLine)
        dataMat.append(fltLine)

def distEclud(vecA,vecB):
    return sqrt(sum(power(vecA - vecB,2)))

def randCent(dataSet,k):
    n = shape(dataSet)[i]
    #create centroid mat
    centroids = mat(zeros((k,n)))
    for j in range(n):
        minJ = min(dataSet[:,j])
        rangeJ = float(max(dataSet[:,j]) - min)
        centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1))
    return centroids

a = array([1,0,0],[0,1,2],[2,0,0])
print(nonzero(a))

4.演算法的優缺點:

優點在於:

1.演算法快速,簡單

2.對大資料集有較高的效率並且是可伸縮性的

3.時間複雜度近於線性、適合挖掘大規模資料集。

缺點在於:

1.k是要事先給定,導致非常難以估計

2.在初始聚類中心來確定一個初始劃分,然後對初始劃分進行優化。初始劃分對結果有較大的影響。

3.不要不斷的進行樣本分類調整、不斷的計算新的聚類中心、當資料量非常大時,演算法的開銷時間非常大。