*はじめに [#ye1804ba]
『Rによるバイオインフォマティクスデータ解析』の7.9.1節「k-menas」を参考にして,k平均法を行います.
#html{{
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=tohgoroh-22&o=9&p=8&l=as1&asins=4320057082&ref=tf_til&fc1=444B4C&IS2=1&lt1=_blank&m=amazon&lc1=444B4C&bc1=FFFFFF&bg1=FFFFFF&f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
}}


*準備 [#zf92ac9d]
Rのインストールについては,次のページを見てください.
-[[MacでRを使う>機械学習/MacでRを使う]]
-[[WindowsでRを使う>機械学習/WindowsでRを使う]]

まず,[math](1, 1)[/math] を中心として,[math]x[/math]座標と[math]y[/math]座標をそれぞれ分散0.3として正規分布で100個の点を生成し,これをc1とします.
次に,[math](-1 -1)[/math] を中心として,同じように分散0.3の正規分布で100個の点を生成し,これをc2とします.
c1とc2をまとめて,dataとし,これをプロットします.
#geshi(rsplus){{
> set.seed(123)
> x1 = rnorm(100, mean=1, sd=0.3)
> y1 = rnorm(100, mean=1, sd=0.3)
> c1 <- cbind(x1, y1)
> x2 = rnorm(100, mean=-1, sd=0.3)
> y2 = rnorm(100, mean=-1, sd=0.3)
> c2 <- cbind(x2, y2)
> data <- rbind(c1, c2)
> colnames(data) <- c("x", "y")
> plot(data)
}}
#ref(kmeans_data1.png,nolink,50%)


*クラスタリング [#j0ec994d]
クラスタリングは,分類対象のデータ集合をいくつかのグループに分割するものです.
分割された部分データ集合を''クラスター''といいます.

クラスタリングの手法には,主に''階層的アプローチ''と''分割最適化アプローチ''があります.
ここでは,後者の分割最適化アプローチの一つである''[math]k[/math]平均法''を行います.


*k平均法 [#fbb389e4]
[math]k[/math]平均法([math]k[/math]-means)は,データの集合を [math]k[/math] 個のクラスターに分割します.
クラスター数 [math]k[/math] を最初に決めておかなければなりません.

[math]k[/math]平均法は,次の手順で行います.
+各データ [math]\bf{x}_1, \dots, \bf{x}_n[/math] に対して,ランダムにクラスター [math]c_1, \dots, c_k[/math] を割り当てる.
+クラスター [math]c_1, \dots, c_k[/math] ごとに,クラスター [math]c_i[/math] に割り当てられたデータの平均を求め,それを [math]c_i[/math] の中心とする.
+各データ [math]\bf{x}_1, \dots, \bf{x}_n[/math] に対して,データ [math]\bf{x}_i[/math] と各クラスター [math]c_1, \dots, c_k[/math] の中心との距離を求め,[math]\bf{x}_i[/math] を最も中心が近いクラスターに割り当て直す.
+全てのデータについてクラスターの割り当てが変更されなかったら終了する.そうでない場合は,ステップ2へ戻る.

Rで[math]k[/math]平均法を用いるには,''kmeans''関数を用います.
kmeans関数の引数には,分割するデータとクラスター数 [math]k[/math] を与えます.
#geshi(rsplus){{
> Cluster <- kmeans(data, 2)
}}

作成されたオブジェクトの''cluster''変数には割り当てられたクラスター番号が,''center''変数には各クラスターの中心座標が格納されます.
#geshi(rsplus){{
> Cluster$cluster
  [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 [40] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 [79] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[118] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[157] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[196] 1 1 1 1 1
> Cluster$center
           x         y
1 -0.9638605 -1.010867
2  1.0271218  0.967736
}}

結果をプロットすると次のようになります.
#geshi(rsplus){{
> plot(data, col=Cluster$cluster, pch=Cluster$cluster)
> points(Cluster$centers, col=1:2, pch=8, cex=2)
}}
#ref(kmeans1.png,nolink,50%)

[math]k[/math]平均法の結果は,最初に行われるランダムな割り当てに依存します.
nstartオプションの値(デフォルトは1)を2以上にすると,nstart回実行して最もよい結果を返します.
#geshi(rsplus){{
> Cluster <- kmeans(data, 2, nstart=10)
}}

また,[math]k[/math]平均法を実行するたびに結果が変わるので,同じ結果を得るには,''set.seed''を用いて乱数のシードをセットしてから実行します.
#geshi(rsplus){{
> set.seed(0)
> Cluster <- kmeans(data, 2)
}}


*k平均法が苦手な問題 [#a4275b11]
今度は,もう少し分散を大きくし,かつ,データの個数を同じにしないでやってみます.
#geshi(rsplus){{
> set.seed(123)
> x1 = rnorm(100, mean=1, sd=1)
> y1 = rnorm(100, mean=1, sd=1)
> c1 <- cbind(x1, y1)
> x2 = rnorm(10, mean=-1, sd=1)
> y2 = rnorm(10, mean=-1, sd=1)
> c2 <- cbind(x2, y2)
> data <- rbind(c1, c2)
> plot(data)
}}
#ref(kmeans_data2.png,nolink,50%)
#geshi(rsplus){{
> Cluster <- kmeans(data, 2)
> plot(data, col=Cluster$cluster, pch=Cluster$cluster)
> points(Cluster$centers, col=1:2, pch=8, cex=2)
}}
#ref(kmeans2.png,nolink,50%)
すると,データを生成するときに使用した中心 [math](1, 1), (-1, -1)[/math] よりもずれてしまいました.
[math]k[/math]平均法はこういう問題はうまくクラスタリングできません.



*まとめ [#k4ec4f3a]

[math]k[/math]平均法は,[math]k[/math] 個のクラスターへの割り当てとクラスターの中心の計算を繰り返す,分割最適化アプローチのクラスタリング手法です.

[math]k[/math]平均法では,クラスターの数 [math]k[/math] をユーザーが事前に与えなければなりません.
したがって,いくつかの [math]k[/math] を試して最もうまくいったものを採用するという方法をとることがあります.

[math]k[/math]平均法の結果は,最初に行われるランダムな割り当てに依存します.
nstartオプションで複数回実行して最も良い結果を採用するか,乱数のシードを変えて実行すると,よりよい結果が得られる可能性があります.

また,[math]k[/math]平均法ではうまくいかない問題があることがよく知られています.
そのようなときは,スペクトラル・クラスタリングを用いるとうまくいくかもしれません.


*参考文献 [#q4967b57]

#html{{
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=tohgoroh-22&o=9&p=8&l=as1&asins=4320057082&ref=tf_til&fc1=444B4C&IS2=1&lt1=_blank&m=amazon&lc1=444B4C&bc1=FFFFFF&bg1=FFFFFF&f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=tohgoroh-22&o=9&p=8&l=as1&asins=4274067033&ref=qf_sp_asin_til&fc1=444B4C&IS2=1&lt1=_blank&m=amazon&lc1=444B4C&bc1=FFFFFF&bg1=FFFFFF&f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
}}

-[[クラスタリングとは(クラスター分析とは):http://www.kamishima.net/jp/clustering/]] - 神嶌敏弘さん
-[[Rでスペクトラル・クラスタリングを使う>バイオ・データ・マイニング/Rでスペクトラル・クラスタリングを使う]] - とうごろうぃき
トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS