統計ER

統計ソフトRの使い方を中心に、統計解析方法の解説をするブログ。ありそうでなかなか見つからないサンプルサイズ計算などニッチな方法について紹介しています。

サポートベクターマシンのコストパラメータCとは?

ブログランキングに参加しています。
まずはぽちぽちっとお願いします。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
にほんブログ村 科学ブログ 数学へ

学習セットでばっちり分類できても、新しいデータではうまく分類できないのは、機械学習の本来の目的から適切ではない。

目的は、新たなデータでも学習セットと同じように適切に分類できる分類器を作ること。

目的を達成するために調整できるパラメータがある。

サポートベクターマシンのコストパラメータとは?

コストパラメータCは誤分類を許容する指標。

Cが小さいと誤分類を許容する。大きいと誤分類を許容しない。

Cが大きい場合は、複雑に分類している。

複雑に分類すると、学習しているデータでは誤分類せずきれいに分類できる。

しかし、汎用性は下がる。テストデータでは分類性能が下がる。

Cを小さくして、誤りをある程度許容すると汎化性能が上がる。

出典:Tokyo.R 41 サポートベクターマシンで眼鏡っ娘分類システム構築

例題で確認してみる

データの準備

ISLRパッケージのOJデータを使う。OJデータはシトラスヒル(CH)とミニッツメイド(MM)どちらのオレンジジュースを買ったかのデータ。

どちらのオレンジジュース買うかを予測する分類器を作成するというお題。

最初一回だけインストールする。

install.packages("ISLR")

呼び出すのがlibrary()だ。

library(ISLR)

学習セットのために1070件のデータの3分の2をサンプリングする。

同じ結果が得られるためにseedを決めておく。

set.seed(20180916)
sub <- c(sample(1:1070, round(1070*2/3)))

コストパラメータを変えて結果を確認してみる

コストのデフォルトは1.指定しないと1がつかわれる。

model1 <- svm(Purchase ~ ., data = OJ[sub,], cross=10)
(svm.confusion.tr1 <- table(fitted(model1),OJ[sub,]$Purchase))
sum(diag(svm.confusion.tr1))/sum(svm.confusion.tr1)

pred1 <- predict(model1, newdata=OJ[-sub,])
(svm.confusion1 <- table(OJ[-sub,]$Purchase, pred1))
sum(diag(svm.confusion1))/sum(svm.confusion1)

学習セットの正答率は86.0%で、テストセットでは81.5%だ。

> (svm.confusion.tr1 <- table(fitted(model1),OJ[sub,]$Purchase))
    
      CH  MM
  CH 393  65
  MM  35 220
> sum(diag(svm.confusion.tr1))/sum(svm.confusion.tr1)
[1] 0.8597475

> (svm.confusion1 <- table(OJ[-sub,]$Purchase, pred1))
    pred1
      CH  MM
  CH 200  25
  MM  41  91
> sum(diag(svm.confusion1))/sum(svm.confusion1)
[1] 0.8151261

コストを10倍の10にしてみる。

model2 <- svm(Purchase ~ ., data = OJ[sub,], cross=10, cost=10)
(svm.confusion.tr2 <- table(fitted(model2),OJ[sub,]$Purchase))
sum(diag(svm.confusion.tr2))/sum(svm.confusion.tr2)

pred2 <- predict(model2, newdata=OJ[-sub,])
(svm.confusion2 <- table(OJ[-sub,]$Purchase, pred2))
sum(diag(svm.confusion2))/sum(svm.confusion2)

学習セットの正答率は87.0%まで上がるが、テストセットでは78.4%に下がった。

コストを高くすると汎化性能は下がることがわかる。

> (svm.confusion.tr2 <- table(fitted(model2),OJ[sub,]$Purchase))
    
      CH  MM
  CH 394  59
  MM  34 226
> sum(diag(svm.confusion.tr2))/sum(svm.confusion.tr2)
[1] 0.8695652

> (svm.confusion2 <- table(OJ[-sub,]$Purchase, pred2))
    pred2
      CH  MM
  CH 193  32
  MM  45  87
> sum(diag(svm.confusion2))/sum(svm.confusion2)
[1] 0.7843137

コストを0.1にしてみるとどうか?

model3 <- svm(Purchase ~ ., data = OJ[sub,], cross=10, cost=0.1)
(svm.confusion.tr3 <- table(fitted(model3),OJ[sub,]$Purchase))
sum(diag(svm.confusion.tr3))/sum(svm.confusion.tr3)

pred3 <- predict(model3, newdata=OJ[-sub,])
(svm.confusion3 <- table(OJ[-sub,]$Purchase, pred3))
sum(diag(svm.confusion3))/sum(svm.confusion3)

コスト1に比べると、学習セットでもテストセットでも正答率は下がる。

コストを下げ過ぎると性能が悪くなることがわかる。

> (svm.confusion.tr3 <- table(fitted(model3),OJ[sub,]$Purchase))
    
      CH  MM
  CH 383  80
  MM  45 205
> sum(diag(svm.confusion.tr3))/sum(svm.confusion.tr3)
[1] 0.8246844

> (svm.confusion3 <- table(OJ[-sub,]$Purchase, pred3))
    pred3
      CH  MM
  CH 201  24
  MM  46  86
> sum(diag(svm.confusion3))/sum(svm.confusion3)
[1] 0.8039216

まとめ

以上、サポートベクターマシンのコストパラメータCを変えてみて、分類器の性能を確認してみた。

コストパラメータは上げ過ぎても下げ過ぎてもよくないことがわかった。