簡介
又叫k-均值演算法,是非監督學習中的聚類演算法。
基本思想
k-means演算法比較簡單。在k-means演算法中,用cluster來表示簇;容易證明k-means演算法收斂等同於所有質心不再發生變化。基本的k-means演算法流程如下:
選取k個初始質心(作為初始cluster,每個初始cluster只包含乙個點);
repeat:
對每個樣本點,計算得到距其最近的質心,將其類別標為該質心所對應的cluster;
重新計算k個cluster對應的質心(質心是cluster中樣本點的均值);
until 質心不再發生變化
repeat的次數決定了演算法的迭代次數。實際上,k-means的本質是最小化目標函式,目標函式為每個點到其簇質心的距離的平方和:
n是元素個數,x表示元素,c(j)表示第j簇的質心
即:
初始化選擇 k 個質心 (隨機選擇, 或者領域知識選擇)
, 該選擇決定了聚類的速度與效果
為所有點劃分簇
計算該種劃分的損失
當該損失還能減小時迴圈以下:
對於每個質心(k個)執行:
a. 隨機選擇乙個新的點
b. 以新的點代替這個質心
c. 重新對所有資料劃分簇
d. 計算劃分的損失
e. 若 新的損失小於原先的損失, 則 用新的點代替原質心
演算法複雜度
時間複雜度是o(nkt) ,其中n代表元素個數,t代表演算法迭代的次數,k代表簇的數目
優缺點
優點
簡單、快速;
對大資料集有較高的效率並且是可伸縮性的;
時間複雜度近於線性,適合挖掘大規模資料集。
缺點k-means是區域性最優,因而對初始質心的選取敏感;
選擇能達到目標函式最優的k值是非常困難的。
**
**已在github上實現,這裡也貼出來
# coding:utf-8
import numpy as np
import matplotlib.pyplot as plt
defloaddataset
(filename)
:'''
載入測試資料集,返回乙個列表,列表的元素是乙個座標
'''datalist =
with
open
(filename)
as fr:
for line in fr.readlines():
curline = line.strip(
).split(
'\t'
) fltline =
list
(map
(float
,curline)
)return datalist
defrandcent
(dataset, k)
:'''
隨機生成k個初始的質心
'''n = np.shape(dataset)[1
]# n表示資料集的維度
centroids = np.mat(np.zeros(
(k,n)))
for j in
range
(n):
minj =
min(dataset[
:,j]
) rangej =
float
(max
(dataset[
:,j]
)- minj)
centroids[
:,j]
= np.mat(minj + rangej * np.random.rand(k,1)
)return centroids
defkmeans
(dataset, k)
:'''
kmeans演算法,返回最終的質心座標和每個點所在的簇
'''m = np.shape(dataset)[0
]# m表示資料集的長度(個數)
clusterassment = np.mat(np.zeros(
(m,2))
) centroids = randcent(dataset, k)
# 儲存k個初始質心的座標
clusterchanged =
true
iterindex=
1# 迭代次數
while clusterchanged:
clusterchanged =
false
for i in
range
(m):
mindist = np.inf; minindex =-1
for j in
range
(k):
distji = np.linalg.norm(np.array(centroids[j,:]
)-np.array(dataset[i,:]
))if distji < mindist:
mindist = distji; minindex = j
if clusterassment[i,0]
!= minindex: clusterchanged =
true
clusterassment[i,:]
= minindex,mindist**
2print
("第%d次迭代後%d個質心的座標:\n%s"
%(iterindex,k,centroids)
)# 第一次迭代的質心座標就是初始的質心座標
iterindex+=
1for cent in
range
(k):
ptsinclust = dataset[np.nonzero(clusterassment[:,
0].a==cent)[0
]]#get all the point in this cluster
centroids[cent,:]
= np.mean(ptsinclust, axis=0)
return centroids, clusterassment
defshowcluster
(dataset, k, centroids, clusterassment)
:'''
資料視覺化,只能畫二維的圖(若是三維的座標圖則直接返回1)
'''numsamples, dim = dataset.shape
if dim !=2:
return
1 mark =
['or'
,'ob'
,'og'
,'ok'
,'oy'
,'om'
,'oc'
,'^r'
,'+r'
,'sr'
,'dr',',
'pr'
]# draw all samples
for i in
range
(numsamples)
: markindex =
int(clusterassment[i,0]
) plt.plot(dataset[i,0]
, dataset[i,1]
, mark[markindex]
) mark =
['pr'
,'pb'
,'pg'
,'pk'
,'py'
,'pm'
,'pc'
,'^b'
,'+b'
,'sb'
,'db',',
'pb'
]# draw the centroids
for i in
range
(k):
plt.plot(centroids[i,0]
, centroids[i,1]
, mark[i]
, markersize =12)
plt.show(
)if __name__ ==
'__main__'
: datamat = np.mat(loaddataset(
'./testset'))
#mat是numpy中的函式,將列表轉化成矩陣
k =4# 選定k值,也就是簇的個數(可以指定為其他數)
cent, clust = kmeans(datamat, k)
showcluster(datamat, k, cent, clust)
機器學習 K Means演算法應用
import matplotlib.pyplot as plt from sklearn.datasets.samples generator import make blobs 聚類資料測試工具 在sklearn中,隨機生成1000個樣本,每個樣本2個特徵,共4個簇,簇中心在 1,1 0,0 1,...
機器學習筆記 k means演算法
k means是一種無監督的聚類演算法,也就是不給標籤,演算法自動來進行分類,最終分成k個簇。輸入 k 簇的個數 訓練集 無標籤的樣本集合 輸出 k個簇 k應該比樣本數量小 1 隨機初始化k個均值向量 代表k個簇的中心 可以隨機選取k個訓練樣本作為初始均值向量。2 開始迴圈 1 對每個樣本進行遍歷,...
機器學習之k means演算法
從資料集中隨機選擇k個聚類樣本作為初始的聚類中心,然後計算資料集中每個樣本到這k個聚類中心的距離,並將此樣本分到距離最小的聚類中心所對應的類中。將所有樣本歸類後,對於每個類別重新計算每個類別的聚類中心即每個類中所有樣本的質心,重複以上操作直到聚類中心不變為止。k means存在缺點 1 k mean...