![]() |
pythonでクラスタリングと表示http://pepper.is.sci.toho-u.ac.jp/pepper/index.php?python%A4%C7%A5%AF%A5%E9%A5%B9%A5%BF%A5%EA%A5%F3%A5%B0%A4%C8%C9%BD%BC%A8 |
![]() |
訪問者数 9793 最終更新 2015-07-22 (水) 12:48:41
クラスタリングのk-means法は広く使われ、パッケージも各言語環境で作られている。Pythonの 場合、scipyにあるkmeansと、多分その導出系のscikit-learnにあるKMeansが利用可能になっている。
k-means法はあらかじめクラスタ数を決めて分類するので、クラスタ数が不明なときにそのままは対応できない。 それに対して、BIC(ベイズ情報量規準)やAIC(赤池情報量規準)などを使って、最適なモデルを 選択しようという考え方があり、その選択のロジックを含めたのがxmeansパッケージらしい。
xmeanについてはhttp://web-salad.hateblo.jp/entry/2014/07/19/200347
Scikit-learnのkmeansパッケージの使い方は、numpyのarrayを、次元別に用意したものを 組合せるのが良いらしい。
x_means = xmeans.XMeans(random_state = 1).fit(np.c_[x,y,z])
但し、x, y, zはnumpyのarrayデータ。np.c_は
c=array([1,2,3]), d=array([4,5,6])のとき、np.c_[c,d]=array([[1,4],[2,5],[3,6]])
のような動作をする。
2次元の場合
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' xmeansを、(1)外部からライブラリとして使う。(2)3次元でのクラスタリング。 xmeanについてはhttp://web-salad.hateblo.jp/entry/2014/07/19/200347 ''' import sys, string, codecs import numpy as np from mpl_toolkits.mplot3d import Axes3D import xmeans import matplotlib.pyplot as plt # データの準備 x = np.array([np.random.normal(loc, 0.1, 20) for loc in np.repeat([1,2], 2)]).flatten() y = np.array([np.random.normal(loc, 0.1, 20) for loc in np.tile([1,2], 2)]).flatten() # 実際の効果は xdom = np.array([1,1,2,2]) # ydom = np.array([1,2,1,2]) # クラスタリングの実行 x_means = xmeans.XMeans(random_state = 1).fit(np.c_[x,y]) #それぞれの要素のペアを作る # c=array([1,2,3]), d=array([4,5,6])のとき、np.c_[c,d]=array([[1,4],[2,5],[3,6]]) print(x_means.labels_) print(x_means.cluster_centers_) print(x_means.cluster_log_likelihoods_) print(x_means.cluster_sizes_) # 結果をプロット #plt.rcParams["font.family"] = "Hiragino Kaku Gothic Pro" plt.rcParams["font.family"] = "VL Gothic" plt.scatter(x, y, c = x_means.labels_, s = 30) plt.scatter(x_means.cluster_centers_[:,0], x_means.cluster_centers_[:,1], c = "r", marker = "+", s = 100) plt.xlim(0, 3) plt.ylim(0, 3) plt.title(u"改良x-means法の実行結果 参考: 石岡(2000)") plt.show() # plt.savefig("clustering.png", dpi = 200)
3次元の場合
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' xmeansを、(1)外部からライブラリとして使う。(2)3次元でのクラスタリング。 xmeanについてはhttp://web-salad.hateblo.jp/entry/2014/07/19/200347 3次元にしたので、mplot3dについてはhttp://qiita.com/mojaie/items/c993fbb3aa63d0001c1c ''' import sys, string, codecs import numpy as np from mpl_toolkits.mplot3d import Axes3D import xmeans import matplotlib.pyplot as plt # データの準備 xdom = np.array([1,1,1,1,2,2,2,2]) ydom = np.array([1,1,2,2,1,1,2,2]) zdom = np.array([1,2,1,2,1,2,1,2]) x = np.array([np.random.normal(loc, 0.1, 200) for loc in xdom]).flatten() y = np.array([np.random.normal(loc, 0.1, 200) for loc in ydom]).flatten() z = np.array([np.random.normal(loc, 0.1, 200) for loc in zdom]).flatten() # クラスタリングの実行 x_means = xmeans.XMeans(random_state = 1).fit(np.c_[x,y,z]) # c=array([1,2,3]), d=array([4,5,6])のとき、np.c_[c,d]=array([[1,4],[2,5],[3,6]]) print(x_means.labels_) print(x_means.cluster_centers_) print(x_means.cluster_log_likelihoods_) print(x_means.cluster_sizes_) # 結果をプロット fig = plt.figure() ax = Axes3D(fig) # 軸ラベルの設定 ax.set_xlabel("X-axis") ax.set_ylabel("Y-axis") ax.set_zlabel("Z-axis") # 表示範囲の設定 ax.set_xlim(0, 3) ax.set_ylim(0, 3) ax.set_zlim(0, 3) # グラフ描画色分け編 ''' labelsはクラスタ番号。それによって配列x, y, zから値を抜きたい x = np.arange(9); s = np.array([0,1,0,1,0,1,0,1,0]) np.select([s==0],[x]) とすると、抜ける。結果はarray([0, 0, 2, 0, 4, 0, 6, 0, 8]) ''' labels = x_means.labels_ number_of_clusters = len(x_means.cluster_sizes_) colors = ["#ff0000", "#00ff00", "#0000ff", "#cccc00", "#00cccc", "#cc00cc", "#ccccc0", "#c0cccc", "#ccc0cc", "#0c0c0c"] if number_of_clusters > len(colors): print "number of clusters %d exceeds number of colors" % number_of_clusters quit() for i in range(number_of_clusters): # クラスタごとに色を変えてプロットする ux = np.select([labels==i], [x]) # ラベルの値がiの要素だけを[x]から選ぶ uy = np.select([labels==i], [y]) uz = np.select([labels==i], [z]) ax.plot(ux, uy, uz, "o", color=colors[i], ms=4, mew=0.5) plt.show()
得られた絵は、