優點:容易實現。
缺點:可能收斂到區域性最小值,在大規模資料集上收斂較慢。
適用資料型別:數值型資料
k-均值演算法:
先隨機確定k個初始點作為質心,然後將資料集中的每個點分配到乙個簇中,具體來講為每個點找距其最近的質心,並將其分配給該質心所對應的簇。
再每個簇更新質心為該簇所有點的平均值。
import numpy as np
#載入資料
defloaddataset
(filename):
datamat =
fr = open(filename)
for line in fr:
curline = line.strip().split('\t')
fltline = list(map(float, curline))
return datamat
#歐氏距離
defdisteclud
(veca, vecb):
#這裡直接用系統自帶的sum方法會出錯
return np.sqrt(np.sum(np.power(veca - vecb,2)))
defrandcent
(dataset, k):
n = np.shape(dataset)[1]
centroids = np.mat(np.zeros((k,n)))
for j in range(n):
mins = min(dataset[:,j])
ranges = float(max(dataset[:,j]) - mins)
centroids[:,j] = mins + np.random.rand(k,1)*ranges
'''dataset = matrix([[ 1., 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 0.],
[ 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0.],
[ 0., 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 0., 1.]])
k = 4
||||
\ /
\/centroids = matrix([[ 0.88338869, 0.94654424, 0.86819242, 0.73792633, 0.88794344,
0.82862507],
[ 0.28036179, 0.73843775, 0.96017969, 0.65308858, 0.10413186,
0.13752974],
[ 0.34094064, 0.27335544, 0.87242206, 0.89623225, 0.67307911,
0.33853315],
[ 0.99018662, 0.72860503, 0.31156304, 0.29371852, 0.45232003,
0.09021325]])
'''return centroids
#kmeans演算法
defkmeans
(dataset, k, distmeas=disteclud, createcent=randcent):
m = np.shape(dataset)[0]
#用來記錄每條記錄的簇中心位置和距離
clusterassment = np.mat(np.zeros((m,2)))
centroids = createcent(dataset, k)
clusterchanged = true
while clusterchanged:
clusterchanged = false
for i in range(m):
mindist = np.inf;
minindex = -1;
#計算每條記錄與每個簇中心點,得到最近中心點
for j in range(k):
distji = distmeas(centroids[j,:], dataset[i,:])
if distji < mindist:
mindist = distji;
minindex = j
#只要有一條記錄的簇中心變化了,則改動clusterchanged為true
#如果clusterchanged一直沒變,也就是說演算法已經收斂了
if clusterassment[i,0] != minindex:
clusterchanged = true
#記錄這條記錄最近的簇中心位置和距離
clusterassment[i,:] = minindex, mindist**2
print(centroids)
#改變簇中心位置為:
# 以這個簇中心為中心的所有記錄的距離的平均值;
# centroids = mean(以這個為中心的資料集.distences)
for cent in range(k):
ptsinclust = dataset[np.nonzero(clusterassment[:,0].a==cent)[0]]
centroids[cent,:] = np.mean(ptsinclust, axis = 0)
return centroids, clusterassment
#二分k-均值演算法
def bikmeans(dataset, k, distmeas=disteclud):
m = np.shape(dataset)[0]
#用來記錄每條記錄的簇中心位置和距離
clusterassment = np.mat(np.zeros((m,2)))
#將整個資料集劃分為乙個簇
#由於np.mat需要後面取[0]
centroids0 = np.mean(dataset, axis=0).tolist()[0]
#記錄centlist = [centroids0]
#初始化資料集的簇中心位置標記和距離
for j in range(m):
clusterassment[j,1] = distmeas(dataset[j,1],np.mat(centroids0))**2
while len(centlist) < k:
lowestsee = np.inf
for i in range(len(centlist)):
#得到當前的簇的資料集
ptsincurrcluster = dataset[np.nonzero(clusterassment[:,0].a==i)[0],:]
#用之前的kmeans演算法將這個資料集劃分為兩個簇
#得到劃分好的簇中心和資料集
centroidmat, splitclustass = kmeans(ptsincurrcluster, 2, distmeas)
#誤差平方和
#也就是所有記錄與簇中心的距離平方和
#計算當前已經劃分好的資料集的誤差平方和
ssesplit = sum(splitclustass[:,1])
#計算剩下的資料集的誤差平方和
ssenotsplit = sum(clusterassment[np.nonzero(clusterassment[:,0].a!=i)[0],1])
#對比+替換
if (ssesplit + ssenotsplit) < lowestsee:
bestcenttosplit = i
bestnewcents = centroidmat
bestclustass = splitclustass.copy()
lowestsee = ssenotsplit + ssesplit
#將最優劃分的兩個簇的第乙個簇資料集標記為原本centlist的長度
bestclustass[np.nonzero(bestclustass[:,0].a == 1)[0], 0] = len(centlist)
#第二個簇資料集標記為原本的簇的標記
bestclustass[np.nonzero(bestclustass[:,0].a == 0)[0], 0] = bestcenttosplit
#將原本劃分的簇替代為最新劃分的兩個簇的前乙個
centlist[bestcenttosplit] = bestnewcents[0,:]
#追加乙個簇為最新劃分的後乙個
#將clusterassment中bestcenttosplit簇資料集
#替換為劃分完的兩個簇標記的資料集
clusterassment[np.nonzero(clusterassment[:,0].a == bestcenttosplit)[0],:] = bestclustass
print(centlist)
return centlist, clusterassment
機器學習筆記之K means聚類
k means聚類是聚類分析中比較基礎的演算法,屬於典型的非監督學習演算法。其定義為對未知標記的資料集,按照資料內部存在的資料特徵將資料集劃分為多個不同的類別,使類別內的資料盡可能接近,類別間的資料相似度比較大。用於衡量距離的方法主要有曼哈頓距離 歐氏距離 切比雪夫距離,其中歐氏距離較為常用。演算法...
機器學習之Kmeans聚類
本次學習總結 1 理解相似度度量的各種方法及其相互聯絡 2 掌握k means演算法思路及其使用條件 3 層次聚類的思路和方法 4 密度聚類並能夠應用於實踐 dbscan 密度最大值聚類 5 譜聚類演算法 譜聚類演算法與pca之間的關係 聚類的定義 聚類就是將大量未知標註的資料,按照資料的內在相似性...
機器學習之聚類演算法 K Means
參考 聚類演算法可以分為 中心點方法 層次聚類方法 基於密度方法 基於網格 基於模型方法。其中最為經典的是k means演算法 k means屬於中心點方法 也有叫劃分方法 演算法經典簡單。演算法 人工選取k值,並選取k個點作為k個簇的質心 對所有樣本分別計算到k個簇的質心的距離 歐式或者曼哈頓 取...