Pythonでx-means法を実装した

はじめに

最近、このままだと修士論文がすごくシンプルな内容になりそうなことに気づいたので、ページ数を稼ぐためによりよい示唆を得るために、何か分析を足す必要が出てきました。
色々考えた結果、x-means法によるクラスタリングを行うことにしたのですが、同手法のPythonによる実装が見つからなかったので、勉強も兼ねて自分で書くことにしました。

x-means法とは

x-means法はk-means法を拡張したものであり、後者が実行時にあらかじめクラスタ数を指定しなければいけないのに対し、最適なクラスタ数を自動で推定できる点が優れています。
その基本となるアイデアPelleg and Moore(2000)で初めて提案されました。
今回は、これに改良を加えた石岡(2000)の手法を実装しました。

実装

肝心のコードですが、ここに掲載するには少し長いので、Gistに上げておきました。

Implementation of X-means clustering in Python

実行に必要なライブラリ、および動作を確認した環境は以下の通りです。

  • Python 3.4.1
  • numpy 1.8.1
  • scipy 0.14.0
  • scikit-learn 0.15-git

実行例

ちゃんと実装できているかの確認として、4点(1,1),(1,2),(2,1),(2,2)を中心に正規分布に従う乱数を20個ずつ発生させ、これを4つのクラスタに分けられるかどうかを試しました。

具体的なコードとその実行結果は以下の通りです。

import numpy as np
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()

# クラスタリングの実行
x_means = XMeans(random_state = 1).fit(np.c_[x,y]) 

# 結果をプロット
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.show()

f:id:Yasaichi:20140719194849p:plain

クラスタk=4を与えていないのにも関わらず、上手くクラスタリングできているのがわかると思います。

参考