Hatena::ブログ(Diary)

小人さんの妄想 このページをアンテナに追加 RSSフィード Twitter

2013-05-31

星空のクラスタリング

クラスタリングクラスター分析)とは、多数のデータの集まりを、似通ったもの同士集めてグループ分けする統計手法です。

例えて言うなれば、星をグループ分けして星座を作るようなものです。

・・・ならば、星のデータをクラスタリングすれば、コンピュータが自動的に星座を作ってくれるのか?

試してみまみした。


星のデータは、以下から入手しました。

* プラネタリウムを作ってみよう! : 星のデータの入手方法

>>http://www.megastar-net.com/school/dataofstar.html

どうもありがとうございます!

(トップページを見たら「このコンテンツは閉鎖しました。」となっていました。ちょっと残念です。)

このデータをプロットした全天図です。

f:id:rikunora:20130531183033p:image

ピンク色が夏の大三角形(織姫彦星)、黄緑色が冬の大三角形北極星は画面右上。

ベテルギウス」のところにオリオン座があって、「アンタレス」のところにさそり座があります。


このデータをクラスタリングにかける訳なのですが、幾つか困った問題があります。

問題1.明るい星と暗い星(1等星と5等星)の違いをどのように表すか?

問題2.全天は球面なので、図の右と左、上と下は本来つながっているのだが、データの上ではつながっていない。

問題3.全天は球面なので、この図はちょうど世界地図(メルカトル図法)のように、実際よりも上と下が大き目に表示されている。


問題1.

 1等星は5等星の5倍の重みを持つものと考えて、1等星のデータを5個コピーして増やしました。

 2等星は4個コピー、3等星は3個コピー・・・5等星は1個のまま。

 こんな方法が果たして妥当かどうか微妙ですが、とりあえず良しとします。

問題2.3.

 とりあえず無視!

 まあ、画面の縁のあたりの結果は見ないということで。


以上の問題アリという前提で、データをR言語のクラスター分析にかけてみました。

R言語上で、以下のスクリプトを実行します。

# Excel のデータをR に取り込むには?

excel.w <- function(nc){ matrix(scan("clipboard"), byrow=TRUE, ncol=nc) }

# 使い方

# (1): Excel の必要なデータ範囲をコピーする.

# (2): excel.w 関数を起動する. 引数は,列数を表す数値一つだけ, 例えば2列なら excel.w(2)

x1 <- excel.w( 2 )

# ウォード法でクラスタリング

hc <- hclust( dist(x1), "ward" )

# クラスタリングの過程(デンドログラム)を表示してみる

plot( hc )

# 星座の数は 88 個ということで、88クラスタに分類

result <- cutree( hc, k=88 )

# 結果をファイルに書き出し

write( result, "Clust88_ward.txt", ncolumns=1 )

その結果できあがった、さそり座オリオン座近辺の様子です。

同じ色が付いている星は、同じクラスタ(グループ)に属しています。

(色は8色しか使っていないので、つながっていない同色は別のクラスタです。)

* ウォード法 --(クラスタ内の分散が最小となるようにグループ分けする方法)

f:id:rikunora:20130531183143p:image

さそり座は上半身と下半身で2分されていますね。

オリオン座も2つに分かれていて、オリオンの足と大犬座の頭が合わさって1つになっています。

ところで、クラスタリングには様々な方法があります。

方法の違いによって結果がどう変わるのか、片っ端から試してみました。


* 最近隣法 -- (最も近い点同士をクラスタ間の距離と見なす方法)

f:id:rikunora:20130531183220p:image

2つの星座とも、同じ色で塗りつぶされています。

実はこれ、1つの巨大クラスタが全天のほとんどを占めている状態です。

この方法だと、しばし巨大クラスタが出現するようです。


* 最遠隣法 -- (最も遠い点同士をクラスタ間の距離と見なす方法)

f:id:rikunora:20130531185303p:image

上の方法の逆です。

2つの星座ともバラバラで、まとまりが無い感じです。


* 群平均法 -- (全ての点間の距離の平均をクラスタ間の距離と見なす方法)

f:id:rikunora:20130531183518p:image

さそり座は2つに分かれた。

オリオン座と、大犬座、小犬座は、わりといい線いっている。


* 重心法 -- (クラスタ重心間の距離を、クラスタ間の距離と見なす方法)

f:id:rikunora:20130531183603p:image

さそり座は尻尾がちぎれた、あと一歩。

オリオン座はちょっと大き過ぎ。


* メディアン法 -- (クラスタの中央値の間の距離を、クラスタ間の距離と見なす方法)

f:id:rikunora:20130531183641p:image

いまひとつ、グダグダな感じ。


以上、それぞれ結果は少しずつ異なっているのですが、星座にドンピシャリと一致する方法はありませんでした。

ここまでの方法は「階層クラスター分析」と言って、

・まずデータの点同士をつなぎ合わせて小さいクラスターを作り、

・小さいクラスター同士をつなぎ合わせて、徐々に大きなクラスタを作り上げる、

といったボトムアップ方式でした。

これとは別の考え方で、全体を一気に見渡してクラスタリングを進める「非階層クラスター分析」という手法もあります。

ついでに、そっちも試してみます。

非階層クラスター分析として、R言語には k-means という手法が用意されています。

# k-meansで 88個のクラスタを生成

km <- kmeans( x1, 88 )

# 結果をファイルに書き出し

write(km$cluster, "Clust88_kmeans.txt", ncolumns=1)

* k-means (R言語:ユークリッド距離)

f:id:rikunora:20130531183726p:image

これはこれで、独特のクラスタができました。

さそり座が大きく3分割されたのは、これが初めて。


クラスタリングとは、距離の近いもの同士の「お団子」を作る作業なので、「丸い塊」ができやすいように思います。

一方、人間が星座を形作るときには「星の並び」、つまり1方向に連なっていることが大きな要因なのではないでしょうか。

つまり、さそり座のような細長い列に対してクラスタリングは不向きなのかも。

そう考えて、さらに別の方法を探求しました。

最近流行りのビッグデータを処理するライブラリに「Apache Mahout」があります。

調べてみると、この Mahoutに搭載されているクラスタリング機能には、

データ間の距離を角度で評価する「コサイン距離(CosineDistanceMesure)」が用意されています。

さらに、長さと角度の両方を評価する「谷本距離(TanimotoDistanceMesure)」というものもありました。

これ、いけそうなので、試してみました。


まずはR言語と同様の、k-means(ユークリッド距離)を Mahoutでも試してみます。

* k-means (Mahout:ユークリッド距離)

f:id:rikunora:20130531183804p:image

同じアルゴリズムであるにも関わらず、結果は微妙に変わっています。

k-means の初期値を乱数で選んでいるので、その影響かと思われます。


次に、コサイン距離でやってみます。

* k-means (Mahout:コサイン距離)

f:id:rikunora:20130531183843p:image

結果、巨大なクラスタができました。

上に挙げた最近隣法と似たような状況です。

その一方で、巨大クラスタからあぶれた大犬座付近はカラフルになっています。


最後に、谷本距離。

* k-means (Mahout:谷本距離)

f:id:rikunora:20130531183922p:image

オリオン座は、これまでの中で最も良い出来です。

さそり座も、まあまあ良し。

その一方で、大犬座と小犬座は一体化している。


ということで、とりあえず試せるクラスタリングを片っ端から試してみたのですが、

残念ながら「これが星座だっ!」と言えるような結果は得られませんでした。

きっと星座とは単純機械的な方法で形作られたのではなく、もっと人間的な要因が作用した結果なのではないかと察せられます。


Mahoutのプログラムについては、以下の本を丸写ししました。

hirotahirota 2013/06/01 11:49 星座がクラスタリングとは面白い事考えましたねー。
たぶん、ランダムの中に見慣れたパターンを見つけるというのは
偶然の模様に人の顔を見つける心霊写真と同様の話でしょうから
データ優先のクラスタリングとは違うんでしょうね。

rikunorarikunora 2013/06/04 09:17 何の予備知識も無い人に星空を見せたら、たぶん全く違う星座を作り出すと思うのです。
それはそうと、心霊写真のパターンを発見するプログラム、というのはおもしろいかも。

hirotahirota 2013/06/04 11:41 携帯のアプリにして流行らせますか?
発見される場所には迷惑なような…村起こしなような…

@masa_36@masa_36 2013/06/22 01:42 おもしろいですね。
・等級は一般的には対数スケール(1等級差=4dB)なので、
http://ja.wikipedia.org/wiki/等級_(天文)
重み付けを変える(よりくっきり等級の差がでて?)
・マハラノビス距離を使ってみる(コサイン距離に近いのかも?)
http://mjin.doshisha.ac.jp/R/17.html
「Rにはマハラノビス距離を求める関数mahalanobisがある」
とかでも違うおもしろい結果がでるかも。(やってくださいという意味ではないですが^^;)

rikunorarikunora 2013/07/01 18:49 逆に、人間の癖に近い分け方を探し当てられれば、人間の感覚解明につながるかもですね。
等級は対数スケール -> 逆に、感覚量は刺激強度の対数に比例 -> 「フェヒナーの法則」
と対応していると思うのです。
マハラノビス距離とは、良いところを突いているかもしれません。
どうもクラスタリングというものは、やってみないと分からないものだと実感しています。。。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/rikunora/20130531/p1