« Rでテキストマイニング | Home | オシロスコープ 再検討 (3) »

線形SVMの識別関数を求める (ksvmパッケージ)

By kmgs | 2 月 7, 2009

サポートベクターマシン(SVM)は、変数に重みを付けるのではなく、サンプルに重みを付けることで識別超平面を求めます。RBFカーネル等を用いた非線形モデルでは識別関数が複雑な形(RBFならいくつかのガウス関数の和)となるのですが、内積を用いた線形カーネルであれば線形の式として求めることができます。
まずは下準備。今回はirisデータの一部を用い、setosaとversicolorを判別してみます。

install.packages("kernlab") # インストールしていなければ
library(kernlab)
iris2 <- iris[iris$Species != "setosa",]
iris3 <- scale(iris2[,-5])
model <- ksvm(Species ~., data=iris2, kernel="vanilladot")

次に、ksvm()によるモデルから、サポートベクターとなったサンプル(model@alphaindex)とその重み(model@coef)を用いて、各変数の重み(すなわち識別超平面の傾き、以下の例では変数coeff)を求めます。
ちなみに、alphaindex[[1]]などとリスト形式になっているのは、3群以上の判別を行ったときに複数個のSVMを用いた多数決を行うためです。

coeff <- t(iris3[model@alphaindex[[1]],]) %*% model@coef[[1]]
coeff # こいつが変数の重み
                   [,1]
Sepal.Length -0.3744591
Sepal.Width  -0.5222862
Petal.Length  1.6011505
Petal.Width   1.6255681
b(model) # 切片
[1] -0.2882371

Petal.LengthとPetal.Widthの重みが大きいことが分かります。次は検算です。

pred1 <- predict(model, iris2)
pred2 <- predict(model, iris2, type="decision")
pred3 <- iris3 %*% coeff - b(model) # 検算の式
data.frame(pred1, pred2, pred3) # pred2とpred3が一致
plot(pred2, pred3)
sum(abs(pred2 - pred3)) # 微妙にずれるが、手順の違いに計算誤差程度?

ちなみに、わざわざscale()でZ変換してiris3のデータを作っているのは、ksvmがデフォルトで内部的にZ変換を行うためです(こうしないと結果が一致しない)。もしくは、ksvm(..., scaled=F)でZ変換を抑制することもできます。

なお、私は機械学習の専門ではないので、もし間違いがありましたらご指摘いただければ幸いです。

Topics: R |

Comments

*
画像に書かれた文字を入力してください

スパム対策用画像
ログインすると画像認証なしで投稿できます

ホットワード 関数 padding margin 統計 処理
割引クーポンまとめ情報 - クー割