RでSOM(自己組織化マップ)
(工事中)
自己組織化マップはニューラルネットの一種で、多次元データを圧縮して低次元のマップを描くものである。
非線形の主成分分析+クラスター分析とも言える。
詳細については Kohonen の著作である Self-Organizing Maps を参照のこと。和訳もされており、自己組織化マップとして Springer から発売されている。
アマゾン でも売っているので詳細を知りたい方はこちらを参照のほど。
Rでは以下のパッケージでコホネンの自己組織化マップをサポートしている。
Kohonen(教師付き・教師なし自己組織化マップ)パッケージ中のオブジェクト一覧
library(class)
コホネンのSOM_PAKのサンプル・データ ex.dat を使う
この ex.dat は、som_pak パッケージに含まれている。
ex.dat の構成は以下ようになっている。
5 13.575570 12.656892 -1.424328 -2.302774 404.921600 13.844373 12.610620 -1.435429 -1.964423 404.978180 13.996934 12.669785 -1.384147 -1.830788 405.187378 14.060876 12.755087 -1.378407 -2.020230 404.892548 (以下中略) 24.066832 22.776152 -0.371480 1.382585 409.522491 23.332212 22.386673 -0.440821 0.525516 406.918518
最初の行にある 5 は column number を示し、Rでは利用しないので、 入力では scan("ex.dat",skip=1) とすることで最初の行をスキップする。
ex <- matrix(scan("ex.dat",skip=1),ncol=5,byrow=T) #
12x8 のマップ、近傍関係は hexagonal(六角形) と rectanglar(四角形) の二つが選べるが ここでは hexagonalを選択する。
gr<-somgrid(xdim=12,ydim=8,topo = "hexagonal") #randinit
上記で設定した マップ上に多次元データ exを投影する。
以下のパラメータはそれぞれ、rlen:学習回数, alpha:学習係数α = 0.02, radii:半径 = 10
test<-SOM(ex,gr,rlen=1000,alpha=0.02,radii=10) #vsom
SOMの教科書やアプリケーションでは正六角形を用いている。正六角形表示は難しくはないようだ。
plot(test)
なお、どの値がどこに割り当てられるのかを知りたくなるかもしれない。 この場合は以下を用いると良いだろう。
plot(test) # 六角形配置にしたがって円を配置する (下記の 12*8は xdim, ydimに対応) symbols(test$grid$pts[,1],test$grid$pts[,2],circles=rep(0.5,8*12),inches=F,add=T) # knn1を使って ex 中のデータが SOMで割り当てた test$code (8*12ある)のどれに近いのかを調査 bins <- as.numeric(knn1(test$code,ex, 0:95)); # exから抜粋した値がどこに割り当てられるのかを示す。 # 全てをプロットすると収集がつかなくなるので seq(101, 1000, by=25)だけをプロットしてみる text(test$grid$pts[bins[seq(101,1000,by=25)],] + rnorm(36,0,0.2),col="blue",as.character(seq(101,1000,by=25) ))
なお、図によれば751と701は同じ領域に(5値ともまんべんなく中庸)、 601と576も同じ領域(最後の変数(5時半の方向)だけが比較的高い) にある。
以下の値で確認したところうまく分類できているようである。
> ex[701,] [1] 24.788752 29.759186 -0.546825 0.164685 402.904144 > ex[751,] [1] 24.40198 32.89207 -0.20661 -2.27529 404.54211 > ex[576,] [1] -0.190742 5.562227 -15.627743 -15.601818 407.453247 > ex[601,] [1] -2.853164 4.018708 -16.220818 -16.177996 405.366364
maptree パッケージ利用
library(som);
上記と同じex.datを使用する。ただし留意すべきは こちらのパッケージでは標準化しないと 描画の際に都合が悪い。
以下のようにして標準化しておく
ex.sc <- scale(ex);
なお、som packageにも normalize(標準化するためのもの?)とfiltering(サチらせるもの?)がついてくるので こちらを使ってみるのも一つの手である。
10x10のマップ、近傍関係はhexa(六角形)とrect(四角形)の二つが選べるが 今回は rectを選択する。
foo <- som(ex.sc, xdim=10,ydim=10,topol="rect");
plot(foo);
値がどこに割り当てられるのかを知りたい場合は
# 対象の設定 obj <- seq(101, 1001,by=25); n <- length(obj); # 以下 rep(0.5, n*2) + rnorm(n*2, 0, 0.15)はラベルを微妙にずらすためのギミック text(foo$visual[obj,c(1,2)] + rep(0.5, n*2)+ rnorm(n*2, 0, 0.15), as.character(obj), col="blue" )
library(kohonen)