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