バイオ・データ・マイニング/RでSVMを使う のバックアップソース(No.5)

このページはまだ書きかけです.

*はじめに [#g88a8135]

『Rによるバイオインフォマティクスデータ解析』の7.15「SVM」を参考にして,RでSVMを使って学習します.

#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>
}}


*準備 [#e5c35924]

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

Naïve Bayesは,''e1071パッケージ''に含まれています.
そこで,e1071パッケージをインストールします.
install.packagesコマンドを実行すると,パッケージをダウンロードするサーバーを聞かれますので,リストからJapanのどれかを選択します.
#geshi(rsplus){{
> install.packages("e1071")
> library("e1071")
}}

ここでは,標準で使用できる''irisデータセット''を使います.
#geshi(rsplus){{
> data(iris)
}}

このデータセットは,アヤメの種類(Species)を花びらの長さ(Sepal.Length),幅(Lepal.Width),がくの長さ(Petal.Length),幅(Petal.Width)によって分類する問題です.
長さと幅は連続値,種類はsetosa, versicolor, virginicaのいずれかをとる離散値です.

このデータセットには,setosa, versicolor, virginicaという3種類のアヤメについて,それぞれ50個ずつ,合計150個のデータが含まれています.
ランダムに10個のデータを選択して,見てみましょう.
#geshi(rsplus){{
> iris[sort(sample(1:150,10)),]
    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
4            4.6         3.1          1.5         0.2     setosa
22           5.1         3.7          1.5         0.4     setosa
65           5.6         2.9          3.6         1.3 versicolor
97           5.7         2.9          4.2         1.3 versicolor
100          5.7         2.8          4.1         1.3 versicolor
108          7.3         2.9          6.3         1.8  virginica
116          6.4         3.2          5.3         2.3  virginica
122          5.6         2.8          4.9         2.0  virginica
136          7.7         3.0          6.1         2.3  virginica
146          6.7         3.0          5.2         2.3  virginica
}}

これをランダム・サンプリングして80%を訓練データとし,のこりの20%をテスト・データとします.
#geshi(rsplus){{
> idx <- sample(nrow(iris), as.integer(nrow(iris)*0.8))
> iris.train <- iris[idx,]
> iris.test <- iris[-idx,]
}}


*SVM [#u50975a4]

SVM(サポート・ベクター・マシン)は二値分類を行う教師付き学習の手法で,高い汎化能力を持っています.

SVMが高い汎化能力を持つ理由の一つが,''カーネル・トリック''というテクニックが使えることです.
これは,元の空間で線形分離が不可能なときでも,カーネルと呼ばれる写像関数を用いて,線形分離可能な空間にマッピングすることで,線形分離を可能にするというものです.

SVMは,最初,二値分類用に開発されましたが,その語,同じ技術を使って回帰を行う手法が開発されました.
そこで,最近では,分類用のSVMを''SVC''(サポート・ベクター分類),回帰用のSVMを''SVR''(サポート・ベクター回帰)と呼んで区別します.

ここでは,分類用のSVM,つまりSVCのことを単にSVMと呼びます.

SVMは,高次元空間の中で,正事例と負事例を分離する超平面(線形判別関数)を求めます.
したがって,説明変数はすべて実数値でなければなりません.

分離超平面から最も近い事例を''サポート・ベクター''といい,分離超平面からサポート・ベクターまでの間の部分を''マージン''と呼びます.
#ref(hard_margin_svm_1.png,nolink,50%);

SVMは,このマージンが最も大きい分離超平面を求めます.
これを''マージン最大化''といいます.
#ref(hard_margin_svm_2.png,nolink,50%);

分離超平面で正事例と負事例を完全に分けられるならこれで良いのですが,どうしても分けられない場合もあります.
分けられると仮定するSVMを''ハード・マージンSVM''といい,分けられないときのためのSVMを''ソフト・マージンSVM''といいます.

ソフト・マージンSVMでは,マージンの内側からはみ出している事例に対してペナルティを与え,このペナルティを''スラック変数'' [math]\xi[/math] で表します.
マージンの内側からはみ出していない事例のスラック変数の値はゼロ,つまり,ペナルティなしです.
#ref(soft_margin_svm.png,nolink,50%)


ここからはソフト・マージンSVMのことを単にSVMと呼びます.

SVMの判別関数は次の式で表されます.
\[ f(\mathbf{x}) = \mathbf{x}^\mathrm{T} \mathbf{w} + b \]
ここで,[math]\mathbf{x}[/math] は説明変数ベクトル,[math]\mathbf{w}[/math] は係数ベクトル,[math]b[/math] は切片を表します.
つまり,判別関数を説明変数 [math]x_1[/math], [math]x_2[/math], ..., [math]x_p[/math] の線形和とし,各説明変数の係数 [math]w_1[/math], [math]w_2[/math], ..., [math]w_p[/math] と切片 [math]b[/math] を学習します.

SVMは次のような [math]\mathbf{w}[/math] と [math]b[/math] を求めます.
\[ \mathrm{argmin}_{\mathbf{w}, b} C \sum_1^n \xi_i + \frac{1}{2} ||\mathbf{w}||^2 \]

[math]\sum_1^n \xi_i[/math] はスラック変数の総和,つまり,ペナルティの総和です.
これを最小化するということは,ペナルティの総和が小さいほどいいという意味になります.

[math]||\mathbf{w}||^2[/math] は正則化項です.
これを最小化するということは,係数の絶対値が小さいほどいいという意味になります.

[math]C[/math] はペナルティの総和と正則化項のどちらをどのくらい重視するかを表すパラメーターです.
[math]C[/math] が大きいとペナルティの総和を小さくしようとし,[math]C[/math]が小さいと正則化項を小さくしようとします.


*SVMの実行 [#t5be7a25]

e1071パッケージのSVMを使うには,''svm関数''を用います.
svm関数の引数には,モデル式と訓練データを与えます.
#geshi(rsplus){{
> iris.svm <- svm(Species~., data=iris.train)
}}

モデル式は,「目的変数 ~ 説明変数」という形をしていて,複数の説明変数を指定するときは記号 ''+''(プラス)で連結します.
また,この例のように,目的変数以外全部を説明変数とするときは,記号 ''.''(ドット)で表すことができます.

irisデータのSpeciesにはsetosa, versicolor, virginicaという3つの値があるので,2値分類であるSVMはそのまま適用することはできませんが,setosaとその他,versicolorとその他,virginicaとその他というように,2値分類を3回行ってその結果を総合して多値分類を行っています.

学習したモデルを表示すると次のようになります.
#geshi(rsplus){{
> iris.svm

Call:
svm(formula = Species ~ ., data = iris.train)


Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  radial 
       cost:  1 
      gamma:  0.25 

Number of Support Vectors:  49

}}

SVM-TypeはSVMの種類を表し,C-classificationというのは,上で説明したパラメーター [math]C[/math] を調整するタイプのSVCです.
''C-SVC''ともいいます.

SVM-Kernelはカーネル・トリックに用いられたカーネル(マッピング)の種類を表し,radialは動径基底関数(RBF, radial basis function)を用いたカーネルです.
''RBFカーネル'', ''ガウシアン・カーネル''ともいいます.

costはC-SVCのパラメーター [math]C[/math],gammaはRBFカーネルのパラメーターです.

そして一番下にはサポート・ベクターの数が出ています.


*テスト・データの予測 [#x2920564]

SVMで学習したモデルを用いてテスト・データに対してカテゴリーを予測してみましょう.

予測するには,''predict関数''を使います.
predicrt関数には,学習したモデルとテスト・データを引数として与えます.
#geshi(rsplus){{
> iris.svm.pred <- predict(iris.svm, iris.test)
}}

予測結果と正解ラベルを突き合わせて表を作ります.
#geshi(rsplus){{
> table(iris.svm.pred, iris.test[,5])
             
iris.svm.pred setosa versicolor virginica
   setosa         10          0         0
   versicolor      0          7         1
   virginica       0          0        12
}}

正解がsetosaの事例は10個すべてsetosaと予測でき,正解がversicolorの事例は7個すべてversicolorと予測できましたが,正解がvirginicaの事例は13個中12個を正しくvirginicaと予測したものの,1個をversicolorと誤って予測したことがわかります.


*チューニング [#r504e596]

そのまま実行して精度がそれほど良くなかったとしても,そこであきらめてはいけません.
パラメーターを調整したり,カーネルを変更することで,もっと良いモデルを学習できることがあります.

まずは [math]C[/math] をいろいろと変えてみましょう.
[math]C[/math] を指定するには,svm関数の引数にcostを指定します.

#geshi(rsplus){{
> iris.svm <- svm(Species~., data=iris.train, cost=0.5)
}}


*まとめ [#z31308ae]



このページはまだ書きかけです.
トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS