聚类 K-Means Using Python
最近在翻譯《Programming Computer Vision with Python》第六章Clustering Images圖像聚類,其中用到了k-means聚類算法,這里根據書中給出的實例對用python進行k-means聚類做一些解釋。關于k-means聚類算法的原理,這里不細述,具體原理可以查閱相關資料。
K-means是聚類算法中最簡單的一種聚類算法,它試著將輸入數據劃分成k簇,該算法最主要的缺點是需要事先選擇聚類數目,并且如果選擇不合理的話,聚類結果會很差。K-means以下面步驟迭代的提煉類中心:
1.初始化類中心,可以是隨機的,也可以是估計的。
2.將每個數據點分配給與它距離最近的類中心。
對同屬于一類的所有數據求平均,更新聚類中心
K-means試圖最小化所有的within-class的方差。該算法是一種啟發式提煉算法,在大多數情況下,它都很有效,但是并不能確保獲得的解答是最好的。為了避免在初始化時選擇不好而造成的影響,該算法通常會用不同的初始值運行幾遍,然后選擇方差最小的。雖然上面K-means的算法很容易實現,但由于有現成的實現vector quantization package,所以我們沒必要再做自己去實現,直接使用上面的模塊即可。
在給出完整代碼之前,我們先來理解兩個numpy、scipy兩個模塊中設計到的兩個函數,分別對應的是numpy.vstack()和scipy.cluster.vq()。我們直接看這兩個函數的例子:
Example for numpy.vstack():
>>> a = np.array([1, 2, 3]) >>> b = np.array([2, 3, 4]) >>> np.vstack((a,b))輸出結果為:
array([[1, 2, 3], [2, 3, 4]])從這個簡單的例子可以看出,np.vstack()這個函數實現connection的作用,即connection(a,b),為了看得更清楚,我們再來看一個這個函數的例子:
>>> a = np.array([[1], [2], [3]]) >>> b = np.array([[2], [3], [4]]) >>> np.vstack((a,b))輸出結果這里不給出了,具體可以再python shell上test。好了,現在我們了解了這個函數的作用,我們再來看scipy.cluster.vq()函數的作用,這里也直接給出實例,通過實例解釋該函數的作用:
Example for scipy.cluster.vq():
>>> from numpy import array >>> from scipy.cluster.vq import vq >>> code_book = array([[1.,1.,1.],[2.,2.,2.]]) >>> features = array([[ 1.9,2.3,1.7],[ 1.5,2.5,2.2],[ 0.8,0.6,1.7]]) >>> vq(features,code_book)輸出結果為:
(array([1, 1, 0]), array([ 0.43588989, 0.73484692, 0.83066239])),下圖解釋了該結果的意義,array([1, 1, 0])中的元素表示features中的數據點對應于code_book中離它最近距離的索引,如數據點[1.9, 2.3, 1.7]離code_book中的[2., 2., 2.]最近,該數據點對的對應于code_book中離它最近距離的索引為1,在python中索引值時從0開始的。 當然,對于上面的結果可以用linalg.norm()函數進行驗證,驗證過程為:
>>> from numpy import array >>> from scipy.cluster.vq import vq >>> code_book = array([[1.,1.,1.],[2.,2.,2.]]) >>> features = array([[ 1.9,2.3,1.7],[ 1.5,2.5,2.2],[ 0.8,0.6,1.7]]) >>> vq(features,code_book) >>> from numpy import * >>> dist = linalg.norm(code_book[1,:] - features[0,:])輸出的dist的結果為:dist: 0.43588989435406728
好了,了解完這兩個函數,我們可以上完整了演示k-means完整的代碼了。
""" Function: Illustrate the k-means Date: 2013-10-27 """" from pylab import * from scipy.cluster.vq import * # 生成模擬數據 class1 = 1.5 * randn(100, 2) class2 = randn(100,2) + array([5, 5]) features = vstack((class1,class2)) # K-Means聚類 centroids, variance = kmeans(features, 2) code, distance = vq(features, centroids) figure() ndx = where(code==0)[0] plot(features[ndx,0], features[ndx,1],'*') ndx = where(code==1)[0] plot(features[ndx, 0],features[ndx,1], 'r.') plot(centroids[:, 0],centroids[:, 1], 'go') axis('off') show()上述代碼中先隨機生成兩類數據,每一類數據是一個100*2的矩陣,centroids是聚類中心。返回來的variance我們并不需要它,因為SciPy實現中,會默認運行20次,并為我們選擇方差最小的那一次。這里聚類中心k=2,并將其作為code_book代用vq(),代碼運行結果如下:上圖顯示了原數據聚完類后的結果,綠色圓點表示聚類中心。
該工具確實非常的有用,但是需要注意的是python實現的K-means沒有c++實現的快,所以如果你在很大的數據集上用python進行聚類,會花費上一些時間。不過,在大多數情況下,足夠我們使用了。
參考資料: 1.Clustering using SciPy's k-means
from:?http://yongyuan.name/blog/kmeans-using-python.html
總結
以上是生活随笔為你收集整理的聚类 K-Means Using Python的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聚类图像像素 Clustering Pi
- 下一篇: Bag of Words模型