2017-06-20 159 views
1

我想了解scipy.cluster.vq.kmeans使用scipy kmeans進行聚類分析

在2D空間中分佈有許多點,問題是將它們分組爲簇。這個問題引起了我的關注,讀取this question,我在想,scipy.cluster.vq.kmeans將要走。

這是數據:
enter image description here

使用下面的代碼,所述目的將是獲得每個25簇的中心點。

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.cluster.vq import vq, kmeans, whiten 

pos = np.arange(0,20,4) 
scale = 0.4 
size = 50 
x = np.array([np.random.normal(i,scale,size*len(pos)) for i in pos]).flatten() 
y = np.array([np.array([np.random.normal(i,scale,size) for i in pos]) for j in pos]).flatten() 


plt.scatter(x,y, s=16, alpha=0.4) 


#perform clustering with scipy.cluster.vq.kmeans 
features = np.c_[x,y] 

# take raw data to cluster 
clusters = kmeans(features,25) 
p = clusters[0] 
plt.scatter(p[:,0],p[:,1], s=81, c="crimson") 

# perform whitening (normalization to std) first 
whitened = whiten(features) 
clustersw = kmeans(whitened,25) 
q = clustersw[0]*features.std(axis=0) 
plt.scatter(q[:,0],q[:,1], s=25, c="gold") 

plt.show() 

結果看起來是這樣的:
enter image description here

紅點標記聚類中心的位置,而美白,黃色點正在使用那些具有美白。雖然它們不同,但主要問題在於它們顯然不是全部在正確的位置。因爲這些簇很好地分離,所以我很難理解爲什麼這個簡單的簇會失敗。

我看了this question哪個報告關於kmeans沒有給出準確的結果,但答案並不令人滿意。建議的使用kmeans2minit='points'的解決方案也不起作用;即kmeans2(features,25, minit='points')給出了與上述相似的結果。

所以問題是,有沒有辦法用scipy.cluster.vq.kmeans執行這個簡單的聚類問題?如果是這樣,我將如何確保獲得正確的結果。

+2

我只是在做同樣的事情(受同一問題的啓發)。通過對'kmeans'的'iter'參數使用較大的值,我得到了更可靠的結果,並且高達'iter = 800'。是的,這讓它變慢。 –

+0

真的嗎?使用'iter = 800'我大致相同; [image here](https://i.stack.imgur.com/SqKmp.png)。 – ImportanceOfBeingErnest

+1

我的羣集與您的羣集有很高的差異。當我收緊集羣時,我不得不更加激動。我剛剛跑了一個'iter = 2000'不夠的例子,但是iter = 10000'找到了預期的中心。 (我並不是說這是一個很好的解決方案,我只是在研究如何讓kmeans工作。) –

回答

0

就像這樣的數據,美白沒有什麼區別:你的x和y軸已經被類似地縮放。

K均值不能可靠地找到全局最優值。它傾向於陷入局部最優。這就是爲什麼通常使用多次運行並保持最佳配合,並嘗試複雜的初始化程序,如k-means ++。

+0

你能否詳細說一下你的意思是「複雜的初始化過程,如k-means ++」? – ImportanceOfBeingErnest

+0

Google for k-means ++ –

+0

好的,對不起,我的意思是從問題中給出問題,實現k-means ++的方法是什麼?有一個scipy功能嗎?我是否需要更改爲scikit-learn或其他圖書館?那麼對於這個問題的答案是,單靠scipy工具是不可能的? – ImportanceOfBeingErnest