読者です 読者をやめる 読者になる 読者になる

アクチュアリーはデータサイエンスの夢を見るか

Rで保険数理と機械学習をやっています

2次判別分析について(スイス銀行紙幣②)

前回に引き続いて機械学習のトピックを取り上げます。今回は2次判別分析です。

線形判別分析では、「群団間で分散が等しい」という前提を用いる弱点があることは前回お話ししました。一方で、群団間で分散が異なる場合に対応した手法が2次判別分析になります。

前回のスイス銀行紙幣のデータを2変数に絞って実行した例が次の通りです。

f:id:r_std:20160504095008p:plain

赤色で示した真札群よりも、緑色で示した偽札群の方が分散が大きいことを反映して凸型の判別関数を描くことができました。

 

全ての変数を用いて実行した結果は次の通りです。

> table(test_qda$class,test_y)
test_y
 0 1
0 49 0
1 1 50

線形判別と変わらない結果となりました。誤判別されたデータを調べてみます。

f:id:r_std:20160504100515p:plain

ピンク色で示された点が誤判別されたデータになります。真札の外れ値に対応できなかったようです。

線形判別、2次判別に共通する弱点として、境界から離れたデータに左右されやすいという点が挙げられます。スイス銀行紙幣のデータでは各群団がまとまって分布していましたが、分布が一様になっているケースなどでは、群団間の境界から離れたデータによって平均、分散が左右され狙い通りの境界を引けない危険性があります。

契約者から取得したデータを保険料率に織り込むことを考える場合、判別分析は汎化能力に優れ、かつ契約者の理解を得られやすいと考えられるものの、コストやプライバシーの観点からどの変数を取得・利用するかが論点になると予想されます。

今回のソースコードは次の通りです。

>||
#MASS読み込み
library(MASS)

sb=read.csv("sbnote.csv")

#学習用データの区分
sb_train=rbind(sb[1:50,],sb[101:150,])
sb_test=rbind(sb[51:100,],sb[151:200,])
test_x=sb_test[,-7]
test_y=sb_test$class

#二次判別用
sb_qda=qda(class~.,sb_train)
table(predict(sb_qda)$class,sb_train$class)

test_qda=predict(sb_qda,test_x)
table(test_qda$class,test_y)

#等分散の仮定を置かずに2変数に絞って判別分析を行う
gd=100
xp=seq(7,13,length=gd)
yp=seq(137,143,length=gd)

x2=cbind(sb[,4],sb[,6])
names(x2)=c("bottom","diagonal")
y=sb$class

sb.qda=qda(x2,y,prior=c(0.5,0.5))
pred=predict(sb.qda)

con=expand.grid(bottom=xp,diagonal=yp)

qpred=predict(sb.qda,con)
qp=qpred$posterior[,1]-qpred$posterior[,2]

plot(x2,pch=21,col=y+2,xlim=c(7,13),ylim=c(137,143),xlab="bottom",ylab="diagonal",main="2次判別の例")
contour(xp,yp,matrix(qp,gd),add=T,levels=0,col=4)

#誤判別したデータを図示
pairs(test_x,main="銀行紙幣の散布図",pch = 21, bg=4+as.numeric(test_qda$class)-test_y)