27
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

x-meansの使い方

Last updated at Posted at 2020-03-27

x-meansとは,k-meansの繰り返しとBICによるクラスターの分割(or処理停止)基準によって,最適なクラスター数を決定するアルゴリズムです.

この記事ではpyclusteringというライブラリでx-meansを使う方法を紹介します.

k-means系まとめ

  • k-means:クラスターの重心からの二乗誤差を最小化.
  • k-medoids:クラスターのmedoid(クラスターに属する点で,非類似度の総和が最小となる点)からの非類似度の総和が最小となるようにEMの手続きを行う.
  • x-means:BICに基づいてクラスタの分割を制御.
  • g-menas:データが正規分布に基づくと仮定して,アンダーソン・ダリング検定によってクラスタの分割を制御.
  • gx-means:上二つの拡張.
  • etc(pyclusteringのreadme参照.色々ある)

クラスター数の判定

データを人間が目で見てすぐにクラスター数がわかるならいいのですが,そんなのは稀なので,定量的な判定方法が欲しいところ.

sklearnのチートシートによれば,

が推奨されている.

も有用ですが,綺麗にエルボー(グラフがガクッとなる点)が出ることが経験上少なく,クラスター数に迷うことが多かったです.

全自動でクラスター数とクラスタリングをしてくれる方法として,x-meansがあります.

以下,x-meansを含む様々なクラスタリング手法を収録しているライブラリ「pyclustering」の使い方.

pyclusteringの使い方

pyclusteringは,クラスタリングアルゴリズムを集めたライブラリで,pythonとC++の両方で実装されています.

インストール

依存するパッケージ:scipy, matplotlib, numpy, PIL

pip install pyclustering

x-means使用例

ソースコード

x-meansは,k-meansにおけるEMステップに加えて,新たなステップ:あるクラスターが正規分布2つで表されるのと1つで表されるのとどちらが適切か,を判定し,2つが適切な場合はクラスターを2つに分ける,という操作がなされます.

以下,jupyter notebook使用.

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
from sklearn import cluster, preprocessing
 
# Wineのデータセット
df_wine_all=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data', header=None)
#品種(0列、1~3)と色(10列)とプロリンの量(13列)を使用する
df_wine=df_wine_all[[0,10,13]]
df_wine.columns = [u'class', u'color', u'proline']
 
# データの整形
X=df_wine[["color","proline"]]
sc=preprocessing.StandardScaler()
sc.fit(X)
X_norm=sc.transform(X)
 
# プロット
%matplotlib inline
 
x=X_norm[:,0]
y=X_norm[:,1]
z=df_wine["class"]
plt.figure(figsize=(10,10))
plt.subplot(4, 1, 1)
plt.scatter(x,y, c=z)
plt.show

# x-means
from pyclustering.cluster.xmeans import xmeans
from pyclustering.cluster.center_initializer import kmeans_plusplus_initializer
xm_c = kmeans_plusplus_initializer(X_norm, 2).initialize()
xm_i = xmeans(data=X_norm, initial_centers=xm_c, kmax=20, ccore=True)
xm_i.process()

# 結果をプロット
z_xm = np.ones(X_norm.shape[0])
for k in range(len(xm_i._xmeans__clusters)):
    z_xm[xm_i._xmeans__clusters[k]] = k+1

plt.subplot(4, 1, 2)
plt.scatter(x,y, c=z_xm)
centers = np.array(xm_i._xmeans__centers)
plt.scatter(centers[:,0],centers[:,1],s=250, marker='*',c='red')
plt.show

ダウンロード.png

上が元々のデータのクラスごとに色付けした図,下がx-meansによるクラスタリング結果.
★印は各クラスの重心です.

コード内のxm_c = kmeans_plusplus_initializer(X_norm, 2).initialize()で,クラスター数の初期値を2に設定していますが,きちんと3つにクラスタリングしてくれています.

xm_i.process()でx-meansを実行しています.

x-meansインスタンス(上のコードではxm_i)について,学習前と学習後でインスタンス変数を色々見ると,学習結果がどんな感じかがわかると思います.例えば

xm_i.__dict__.keys()

または

vars(xm_i).keys()

で取得できる

dict_keys(['_xmeans__pointer_data', '_xmeans__clusters', '_xmeans__centers', '_xmeans__kmax', '_xmeans__tolerance', '_xmeans__criterion', '_xmeans__ccore'])

などを色々見るとよいかと思います.

_xmeans__pointer_data

クラスタリング対象となったデータのコピー.

_xmeans__clusters

各クラスターには,元データ(_xmeans__pointer_data)の何行目が属しているかを表したリスト.

リストの要素数はクラスター数と同じであり,各要素はまたリストになっており,クラスターに属する行の番号が格納されている.

_xmeans__centers

各クラスターのセントロイドの座標(リスト)からなるリスト

_xmeans__kmax

クラスター数の最大値(設定値)

_xmeans__tolerance

x-meansのiterationの停止条件を定める定数です.クラスターの重心の変化の最大値がこの定数を下回ったとき,アルゴリズムが終了します.

_xmeans__criterion

クラスターの分割の判定条件です.デフォルト:BIC

_xmeans__ccore

pythonコードの代わりにC++コードを使うかどうかの設定値です.

27
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?