• 追加された行はこの色です。
  • 削除された行はこの色です。
#freeze
*はじめに [#g88a8135]

ロジスティック回帰は、教師信号 [math]y[/math] が 1 または 0 の2値分類問題(カテゴリーが「はい」と「いいえ」のカテゴリー分析)において、[math]y = 1[/math] となる確率を表す関数を回帰分析によって求める手法です。



『Rによるバイオインフォマティクスデータ解析』には載っていません。

#html{{
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=tf_til&t=tohgorohmatsu-22&m=amazon&o=9&p=8&l=as1&IS2=1&detail=1&asins=4320057082&linkId=f6db5311dcfd9a82f5dee20859d39574&bc1=ffffff&lt1=_blank&fc1=444b4c&lc1=444b4c&bg1=ffffff&f=ifr"></iframe>
}}


*準備 [#e5c35924]

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

ここでは、標準で使用できる''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)),]
}}
#geshi(rsplus){{
    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
}}

2値分類にするため、Speciesがsetosaなら 1、そうでないなら 0 という新しい列 Setosa を作ります。
これを、versicolor, virginica についても行います。
#geshi(rsplus){{
iris$Setosa <- ifelse(iris$Species=="setosa", 1, 0)
iris$Versicolor <- ifelse(iris$Species=="versicolor", 1, 0)
iris$Virginica <- ifelse(iris$Species=="virginica", 1, 0)
}}

もう一度、ランダムに10個のデータを選択して、追加した列を確認します。
#geshi(rsplus){{
    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species Setosa Versicolor Virginica
21           5.4         3.4          1.7         0.2     setosa      1          0         0
43           4.4         3.2          1.3         0.2     setosa      1          0         0
50           5.0         3.3          1.4         0.2     setosa      1          0         0
54           5.5         2.3          4.0         1.3 versicolor      0          1         0
73           6.3         2.5          4.9         1.5 versicolor      0          1         0
76           6.6         3.0          4.4         1.4 versicolor      0          1         0
84           6.0         2.7          5.1         1.6 versicolor      0          1         0
114          5.7         2.5          5.0         2.0  virginica      0          0         1
139          6.0         3.0          4.8         1.8  virginica      0          0         1
150          5.9         3.0          5.1         1.8  virginica      0          0         1
}}

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


*ロジスティック回帰 [#u50975a4]

SVM(サポート・ベクター・マシン)は二値分類を行う教師付き学習の手法で,高い汎化能力を持っています.
説明のため、まずは説明変数をPetal.Length、目的変数をVirginicaとします。
#geshi(rsplus){{
x.train <- iris.train$Petal.Length
y.train <- iris.train$Virginica
plot(x.train, y.train)
}}
#ref(iris_petal_length_virginica.png,nolink)

SVMが高い汎化能力を持つ理由の一つが,''カーネル・トリック''というテクニックが使えることです.
これは,元の空間で線形分離が不可能なときでも,カーネルと呼ばれる写像関数を用いて,線形分離可能な空間にマッピングすることで,線形分離を可能にするというものです.
このデータに対して線形回帰でモデルを作成すると、うまくフィットしません。
#geshi(rsplus){{
model <- lm(y.train ~ x.train)
abline(model)
}}
#ref(iris_petal_length_virginica_lm.png,nolink)

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

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

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

分離超平面から最も近い事例を''サポート・ベクター''といい,分離超平面からサポート・ベクターまでの間の部分を''マージン''と呼びます.
#ref(hard_margin_svm_1.png,nolink,50%);
そこで、目的変数の値が 1 になる確率を [math]p[/math] とし、この確率を
$$ p = \frac{1}{1+\exp(-(\beta_0+\beta_1 x))} $$
という関数で近似することを考えます。

SVMは,このマージンが最も大きい分離超平面を求めます.
これを''マージン最大化''といいます.
#ref(hard_margin_svm_2.png,nolink,50%);
この関数は、次のような 0 から 1 までの値をとり、S字の形をしています。
#ref(sigmoid.png,nolink)

分離超平面で正事例と負事例を完全に分けられるならこれで良いのですが,どうしても分けられない場合もあります.
分けられると仮定するSVMを''ハード・マージンSVM''といい,分けられないときのためのSVMを''ソフト・マージンSVM''といいます.
この式を変形すると、次のようになります。
$$ \log\left(\frac{p}{1-p}\right) = \beta_0 + \beta_1 x$$
左辺の [math]\frac{p}{1-p}[/math] を''オッズ'' (odds) といい、[math]\log\left(\frac{p}{1-p}\right)[/math] を''ロジット関数''といいます。

ソフト・マージン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 \]
*ロジスティック回帰を実行する [#z45c2dde]

[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関数の引数には,モデル式と訓練データを与えます.
ロジスティック回帰を行うには、''glm''関数を使います。
glm関数には、第1引数にモデル式、第2引数にデータフレーム、第3引数に ''family=binomial(link="logit")'' を指定します。
#geshi(rsplus){{
iris.svm <- svm(Species~., data=iris.train)
model <- glm(Virginica ~ Petal.Length, data=iris.train, family=binomial(link="logit"))
}}

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

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

学習したモデルを表示すると次のようになります.
学習したモデルのサマリーを出力してみます。
#geshi(rsplus){{
iris.svm
summary(model)
}}
#geshi(rsplus){{

Call:
svm(formula = Species ~ ., data = iris.train)
glm(formula = Virginica ~ Petal.Length, family = binomial(link = "logit"), 
    data = iris.train)

Deviance Residuals: 
     Min        1Q    Median        3Q       Max  
-2.02963  -0.03626   0.00000   0.02848   2.51612  

Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  radial 
       cost:  1 
      gamma:  0.25 
Coefficients:
             Estimate Std. Error z value Pr(>|z|)    
(Intercept)   -40.965     11.058  -3.705 0.000212 ***
Petal.Length    8.409      2.267   3.709 0.000208 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Number of Support Vectors:  49
(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 154.11  on 119  degrees of freedom
Residual deviance:  31.59  on 118  degrees of freedom
AIC: 35.59

Number of Fisher Scoring iterations: 9
}}
CoefficientsのEstimateがロジスティック回帰で求められたロジット関数の係数を表しており、Interceptが定数項 [math]\beta_0[/math] です。
したがって、目的変数の値が 1 になる確率は次のように表されます。
$$ p = \frac{1}{1 + \exp(-(-40.965 + 8.409 x))} $$

SVM-TypeはSVMの種類を表し,C-classificationというのは,上で説明したパラメーター [math]C[/math] を調整するタイプのSVCです.
''C-SVC''ともいいます.
これをプロットしてみます。
#geshi(rsplus){{
plot(x.train, y.train)
curve(1/(1+exp(-(-40.965+8.409*x))), add=TRUE)
}}
#ref(iris_petal_length_virginica_logistic.png,nolink)

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

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

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


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

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

予測するには,''predict関数''を使います.
predicrt関数には,学習したモデルとテスト・データを引数として与えます.
訓練データに対する確率は、''fitted''関数で出力できます。
#geshi(rsplus){{
iris.svm.pred <- predict(iris.svm, iris.test)
fitted(model)
}}
#geshi(rsplus){{
          26           85           58          100           86          105           48           66          135          129           90 
1.129131e-12 4.219567e-02 1.825599e-06 1.522187e-03 4.219567e-02 9.995945e-01 2.100456e-13 1.864666e-02 9.978238e-01 9.978238e-01 6.570957e-04 
         118           11           67           19          127            2           84          102          130           68           41 
9.999998e-01 4.870000e-13 4.219567e-02 2.617940e-12 3.544564e-01 2.100456e-13 8.725072e-01 8.725072e-01 9.995945e-01 1.522187e-03 2.220446e-16...
}}
インデックスをランダムに選んだままでソートしていないので、順番はバラバラになっています。

予測結果と正解ラベルを突き合わせて表を作ります.
テストデータに対して予測をするときは、''predict.glm''関数を用います。
predict.glm関数の第1引数には学習したモデル、第2引数にはテストデータのデータフレーム、第3引数には''type="response"''を指定します。
#geshi(rsplus){{
table(iris.svm.pred, iris.test[,5])
predict.glm(model, iris.test, type="response")
}}
#geshi(rsplus){{             
iris.svm.pred setosa versicolor virginica
   setosa         10          0         0
   versicolor      0          7         1
   virginica       0          0        12
#geshi(rsplus){{
           5            7           18           22           24           30           33           36           38           39           43 
2.100456e-13 2.100456e-13 2.100456e-13 4.870000e-13 2.617940e-12 1.129131e-12 4.870000e-13 2.220446e-16 2.100456e-13 2.220446e-16 2.220446e-16 
          47           55           59           62           70           72           76           91           93           94          103 
1.129131e-12 9.267631e-02 9.267631e-02 3.522188e-03 2.835147e-04 6.570957e-04 1.864666e-02 1.864666e-02 6.570957e-04 1.825599e-06 9.998250e-01 
         108          115          124          126          131          141          145          149 
9.999939e-01 8.725072e-01 5.600666e-01 9.999245e-01 9.999675e-01 9.978238e-01 9.990602e-01 9.884120e-01 
}}

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

*モデルの評価 [#c6e49a5d]

*チューニング [#r504e596]
ロジスティック回帰で求めたモデルを評価するには、''ROC曲線''の下側の面積 (''AUC'': Area Under the Curve) を使います。

そのまま実行して精度がそれほど良くなかったとしても,そこであきらめてはいけません.
パラメーターを調整したり,カーネルを変更することで,もっと良いモデルを学習できることがあります.
ROC曲線とAUCを求めるには''pROC''パッケージを使います。
#geshi(rsplus){{
install.packages("pROC")
library(pROC)
}}

ただし,一つの訓練データだけでチューニングを行うと,そのデータだけはうまく分類できるがその他のデータはうまく分類できない''過学習''(''オーバー・フィッティング'')と呼ばれる現象が生じます.
気をつけましょう.
テストデータの目的変数とテストデータに対する予測値を変数に代入しておき、''roc''関数でROC曲線とAUCを求めます。
#geshi(rsplus){{
y.test <- iris.test$Virginica
p.test <- predict.glm(model, iris.test, type="response")

roc(y.test, p.test)
}}
#geshi(rsplus){{
Call:
roc.default(response = y.test, predictor = p.test)

Data: p.test in 19 controls (y.test 0) < 11 cases (y.test 1).
Area under the curve: 0.9928
}}

*まとめ [#z31308ae]
ROC曲線をプロットするには、roc関数で生成されるオブジェクトをplot関数に渡します。
#geshi(rsplus){{
roc <- roc(y.test, p.test)
plot(roc)
}}
#ref(roc.png,nolink)

SVM (SVC)は高い汎化能力を持つ2値分類のための機械学習手法です.

SVMに与えるデータの説明変数は全て数値でなければなりません.
*まとめ [#z31308ae]

e1071パッケージのsvm関数は,目標変数のカテゴリーが3種類以上でも実行できます.
ロジスティック回帰は、目的変数が 1 になる確率のロジット関数を線形回帰によって求める手法で、2値分類(カテゴリーが「はい」または「いいえ」のカテゴリー分析)に用いる手法です。

SVMはカーネル・トリックを用いることで高い汎化能力を得ています.
カーネルの種類やそのパラメーターを変えることで,より高い予測精度が得られる可能性があります.

SVMと同じ技術を用いて回帰もできます.
分類のためのSVMをSVC,回帰のためのSVMをSVRといいます.



*参考文献 [#g8f00b3a]
#html{{
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=tf_til&t=tohgorohmatsu-22&m=amazon&o=9&p=8&l=as1&IS2=1&detail=1&asins=4320057082&linkId=f6db5311dcfd9a82f5dee20859d39574&bc1=ffffff&lt1=_blank&fc1=444b4c&lc1=444b4c&bg1=ffffff&f=ifr"></iframe>
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=qf_sp_asin_til&t=tohgorohmatsu-22&m=amazon&o=9&p=8&l=as1&IS2=1&detail=1&asins=4621061224&linkId=632f1721f5fa1b024003cfb1b98ce366&bc1=ffffff&lt1=_blank&fc1=444b4c&lc1=444b4c&bg1=ffffff&f=ifr"></iframe>
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=qf_sp_asin_til&t=tohgorohmatsu-22&m=amazon&o=9&p=8&l=as1&IS2=1&detail=1&asins=4621061240&linkId=24ebe891b6a9641e04a983f2259eb3ab&bc1=ffffff&lt1=_blank&fc1=444b4c&lc1=444b4c&bg1=ffffff&f=ifr"></iframe>
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=qf_sp_asin_til&t=tohgorohmatsu-22&m=amazon&o=9&p=8&l=as1&IS2=1&detail=1&asins=4320121341&linkId=f7fea767d9538f35cc900e57d2e4a1b1&bc1=ffffff&lt1=_blank&fc1=444b4c&lc1=444b4c&bg1=ffffff&f=ifr"></iframe>
}}

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS