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)