kmeans聚類的python實現


1. kmeans算法簡介

待補充

2. python實現

2.1 基礎版

kmeans算法,前幾天的一道面試在線編程題目。好久不用python手法都生疏了,寫的很慢。不過后來對比了下網絡上的其他kmeans的python實現,感覺自己的實現相對簡潔美觀,代碼量少。這主要依賴於numpy包的使用。
廢話少說,直接上代碼.
對於輸入數據的說明
data是一個\(n*m\)的數組,\(data\in R^{n*m}\)\(n\)是訓練數據的樣本個數,\(m\)是feature的維數,\(k\)是設定好的聚類數

import numpy as np
def kmeans(data, n, m, k):
	rarray = np.random.random(size=k)
    rarray = np.floor(rarray*n)
    rarray.astype(int)
    end = True
    cls = np.zeros([1,n],np.int)    		
    center = np.take(data,rarray)
    pcenter = np.zeros([k,m])
    while end:
		for i in xrange(n):
			tmp = data[i] - center
            tmp = np.square(tmp)
            tmp = np.sum(tmp,axis=1)
            cls[i] = np.argmin(tmp)
        center = np.zeros([k,m])
        count = np.zeros([1,k],np.int)
        for i in xrange(n):
			center[cls[i]]=center[cls[i]]+data[i]
            count[cls[i]]= count[cls[i]]+1
        if center/count == pcenter:
			end = False
        pcenter = center/count

2.2 修改版

說是修改版其實有點勉強,不過確實是一個很有用的修改。編程中在做數值相等判斷的時候,直接使用==判斷並不可靠。實際上經過運算后的兩個值(浮點型)並不可能完全一致,可能會因為小數點后的些許差異導致判斷為false。
比如:

print 1e-5 == 1e-6 //這肯定是false,但是實際這兩個值可以看作近似相等。

在kmeans中判斷是否結束循環,就是判斷重新計算的聚類中心點是否和原聚類中心點一致,實際上新舊聚類中心點之間會有一個可允許的誤差。修改代碼如下:

import numpy as np
def kmeans(data, n, m, k):
	rarray = np.random.random(size=k)
    rarray = np.floor(rarray*n)
    rarray.astype(int)
    cls = np.zeros([1,n],np.int)    		
    center = np.take(data,rarray)
    pcenter = np.zeros([k,m])
    end = True
    while end:
		for i in xrange(n):
			tmp = data[i] - center
            tmp = np.square(tmp)
            tmp = np.sum(tmp,axis=1)
            cls[i] = np.argmin(tmp)
        center = np.zeros([k,m])
        count = np.zeros([1,k],np.int)
        for i in xrange(n):
			center[cls[i]]=center[cls[i]]+data[i]
            count[cls[i]]= count[cls[i]]+1
        if np.sum(center/count - pcenter) <= 1e-4:
			end = False
        pcenter = center/count

3. 待解決的問題

由於聚類之后,開始新的迭代過程中,可能有某一類\(k'\)會產生特殊情況:訓練樣本中沒有任何一個被分到這個類。這個時候對應的count[k'] = 0,直接做除法顯然就會報錯,這個問題暫時還沒有解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM