機器學習中有兩類的大問題,乙個是分類,乙個是聚類。分類是根據一些給定的已知類別標號的樣本,訓練某種學習機器,使它能夠對未知類別的樣本進行分類。這屬於supervised learning(監督學習)。而聚類指事先並不知道任何樣本的類別標號,希望通過某種演算法來把一組未知類別的樣本劃分成若干類別,這在機器學習中被稱作 unsupervised learning (無監督學習)。在本文中,我們關注其中乙個比較簡單的聚類演算法:k-means演算法。
k-means演算法是一種很常見的聚類演算法,它的基本思想是:通過迭代尋找k個聚類的一種劃分方案,使得用這k個聚類的均值來代表相應各類樣本時所得的總體誤差最小。
其python實現的**如下:
#encoding:utf-8
from numpy import *
def loaddataset(filename):
datamat = #建立元祖
fr = open(filename)
for line in fr.readlines():
curline = line.strip().split("\t")
fltline = map(float,curline) #使用map函式將curline裡的數全部轉換為float型
return datamat
def disteclud(veca,vecb): #計算兩個向量的歐式距離
return sqrt(sum(power(veca-vecb,2)))
def randcent(dataset,k): #位給定資料集構建乙個包含k個隨機質心的集合
n = shape(dataset)[1] #shape函式此時返回的是dataset元祖的列數
centroids = mat(zeros((k,n))) #mat函式建立k行n列的矩陣,centroids存放簇中心
for j in range(n):
minj = min(dataset[:,j]) #第j列的最小值
rangej = float(max(dataset[:,j]) - minj)
centroids[:,j] = minj + rangej * random.rand(k,1) #random.rand(k,1)產生shape(k,1)的矩陣
return centroids
def kmeans(dataset,k,dismeas = disteclud,createcent = randcent):
m = shape(dataset)[0] #shape函式此時返回的是dataset元祖的行數
clusterassment = mat(zeros((m,2))) #建立乙個m行2列的矩陣,第一列存放索引值,第二列存放誤差,誤差用來評價聚類效果
centroids = createcent(dataset,k) #建立k個質心,呼叫createcent()函式
clusterchanged =true #標誌變數,若為true則繼續迭代
print "質心位置更新過程變化:"
while clusterchanged:
clusterchanged = false
for i in range(m):
mindist = inf #inf為正無窮大
minindex = -1 #建立索引
for j in range(k):
#尋找最近的質心
disji = dismeas(centroids[j,:],dataset[i,:]) #計算每個點到質心的歐氏距離
if disji(array([0, 0, 1]), array([0, 2, 0]))
#print array(nonzero(b2))
#=>[[0, 0, 1],[0, 2, 0]]
centroids[cent,:] = mean(ptsinclust,axis=0) #計算所有點的均值,選項axis=0表示沿矩陣的列方向進行均值計算
return centroids,clusterassment #返回所有的類質心與點分配結果
datmat = mat(loaddataset('data.txt'))
mycentroids,clustassing = kmeans(datmat,2)
print "最終質心:\n",mycentroids
print "索引值和均值:\n",clustassing
k-means演算法比較簡單,但也有幾個比較大的缺點:
1)k值的選擇是使用者指定的,不同的k得到的結果會有挺大的不同,如下圖所示,左邊是k=3的結果,這個就太稀疏了,藍色的那個簇其實是可以再劃分成兩個簇的。而右圖是k=5的結果,可以看到紅色菱形和藍色菱形這兩個簇應該是可以合併成乙個簇的:
2)對k個初始質心的選擇比較敏感,容易陷入區域性最小值。例如,我們上面的演算法執行的時候,有可能會得到不同的結果,如下面這兩種情況。k-means也是收斂了,只是收斂到了區域性最小值:
3)存在侷限性,如下面這種非球狀的資料分布就搞不定了
4)資料庫比較大的時候,收斂會比較慢.
k均值聚類中簇的值k是使用者預先定義的乙個引數,那麼使用者如何才能知道k的選擇是否正確?如何才能知道生成的簇比較好?在計算的過程中保留了每個點的誤差,即該點到簇質心的距離平方值,下面將討論利用該誤差來評價聚類***壞的方法,引入度量聚類效果的指標sse(sum of squared error,誤差平方和),sse值越小,越接近於他們的質心,聚類效果也越好,有一種可以肯定減小sse值得方法是增加k的數目,但這個違背了聚類的目標,聚類的目標是在保持簇數目不變的情況下提高簇的質量。
參考:
K均值 K means 聚類演算法
j.b.macqueen 在 1967 年提出的k means演算法 22 到目前為止用於科學和工業應用的諸多聚類演算法中一種極有影響的技術。它是聚類方法中乙個基本的劃分方法,常常採用誤差平方和準則函式作為聚類準則函式,誤差平方和準則函式定義為 3 1 其中,是類 中資料物件的均值,即 j 1,2,...
K 均值聚類演算法 K means
k means是一種無監督的學習,將相似的物件歸到同乙個簇中.可以將一批資料分為k個不同的簇,並且每個簇的中心採用簇中所含樣本的均值計算而成.k means演算法的k值需要由使用者指定,演算法開始時隨機選擇k個初始點作為質心,然後將資料集中的每個點分配到乙個簇中.那麼,如何確定某一組資料歸於哪個簇中...
K均值聚類演算法 K Means
將資料集中的資料按照距離質心的遠近分到各個簇中 將各個簇中的資料求平均值,作為新的質心,重複上一步,直到所有的簇不再改變 from numpy import defloaddataset filename dataset f open filename for line in f.readlines...