K-MEANS

1、K-均值聚類(K-means)算法

k-means算法是一種簡單的迭代型聚類算法,採用距離做爲類似性指標,從而發現給定數據集中的K個類,且每一個類的中心是根據類中全部值的均值獲得,每一個類用聚類中心來描述。對於給定的一個包含n個d維數據點的數據集X以及要分得的類別K,選取歐式距離做爲類似度指標,聚類目標是使得各種的聚類平方和最小,即最小化:app

                                                      

結合最小二乘法和拉格朗日原理,聚類中心爲對應類別中各數據點的平均值,同時爲了使得算法收斂,在迭代過程當中,應使最終的聚類中心儘量的不變。dom

 

2、算法步驟函數

K-means是一個反覆迭代的過程,算法分爲四個步驟:spa

1) 選取數據空間中的K個對象做爲初始中心,每一個對象表明一個聚類中心;3d

2) 對於樣本中的數據對象,根據它們與這些聚類中心的歐氏距離,按距離最近的準則將它們分到距離它們最近的聚類中心(最類似)所對應的類;code

3) 更新聚類中心:將每一個類別中全部對象所對應的均值做爲該類別的聚類中心,計算目標函數的值;對象

4) 判斷聚類中心和目標函數的值是否發生改變,若不變,則輸出結果,若改變,則返回2)。blog

 

3、實例element

# -*- coding: UTF-8 -*-
import numpy
import random
import matplotlib.pyplot as plt
 
def calculateDistance(vecA, vecB):   
 
    return numpy.sqrt(numpy.sum(numpy.square(vecA - vecB)))

def findCentroids(data_get, k):
return random.sample(data_get, k) def minDistance(data_get, centroidList): clusterDict = dict() for element in data_get: vecA = numpy.array(element) flag = 0 minDis = float("inf") for i in range(len(centroidList)): vecB = numpy.array(centroidList[i]) distance = calculateDistance(vecA, vecB) if distance < minDis: minDis = distance flag = i if flag not in clusterDict.keys(): clusterDict[flag] = list() clusterDict[flag].append(element) return clusterDict def calculate_Var(clusterDict, centroidList): sum = 0.0 for key in clusterDict.keys(): vecA = numpy.array(centroidList[key]) distance = 0.0 for item in clusterDict[key]: vecB = numpy.array(item) distance += calculateDistance(vecA, vecB) sum += distance return sum
def getCentroids(clusterDict):
 
    centroidList = list() for key in clusterDict.keys(): centroid = numpy.mean(numpy.array(clusterDict[key]), axis=0) centroidList.append(centroid) return numpy.array(centroidList).tolist()

def showCluster(centroidList, clusterDict): colorMark
= ['or', 'ob', 'og', 'ok', 'oy', 'ow'] centroidMark = ['dr', 'db', 'dg', 'dk', 'dy', 'dw'] for key in clusterDict.keys(): plt.plot(centroidList[key][0], centroidList[key][1], centroidMark[key], markersize=12) for item in clusterDict[key]: plt.plot(item[0], item[1], colorMark[key]) plt.show() data = [[0.0, 0.0], [3.0, 8.0], [2.0, 2.0], [1.0, 1.0], [5.0, 3.0], [4.0, 8.0], [6.0, 3.0], [5.0, 4.0], [6.0, 4.0], [7.0, 5.0]] if __name__ == '__main__': centroidList = findCentroids(data, 3) clusterDict = minDistance(data, centroidList) newVar = calculate_Var(clusterDict, centroidList) oldVar = -0.0001 print('***** 第1次迭代 *****') for key in clusterDict.keys(): print('聚類中心: ', centroidList[key]) print('對應聚類: ',clusterDict[key]) print('平均均方偏差: ', newVar) showCluster(centroidList, clusterDict) k = 2 while abs(newVar - oldVar) >= 0.0001: centroidList = getCentroids(clusterDict) clusterDict = minDistance(data, centroidList) oldVar = newVar newVar = calculate_Var(clusterDict, centroidList) print('***** 第%d次迭代 *****' % k) for key in clusterDict.keys(): print('聚類中心: ', centroidList[key]) print('對應聚類: ', clusterDict[key]) print('平均均方偏差: ', newVar) showCluster(centroidList, clusterDict) k += 1

結果:

相關文章
相關標籤/搜索