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

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

統計検定準1級に合格しました

先日、統計検定準1級の合格発表がありました。大変うれしいことに評価Sをいただいて合格することができました。引き続き1級の受験も目指して勉強していきたいです。

www.toukei-kentei.jp

試験の難易度としては、アクチュアリー基礎科目の数学をやや難しくしたものに、多変量解析などの専門的なトピックや論述問題が加わったイメージです。合格率自体は22%と高めなので、気軽にチャレンジできる試験です。

対策としては、公式問題集公式サイトの例題集を一周しました。アクチュアリー試験とあまり被りのない機械学習分野については、はじめてのパターン認識を読んで知識を補完しました。2016年度の試験では、当ブログでとりあげている線形判別分析や、台風の上陸数のモデリングなどが論述問題で出題されたことから、自分にとってはラッキーな出題でした。

試験の開催は年1回6月のようですので、アクチュアリー試験で中だるみを感じている方にはもってこいの試験だと思われます。今年も12月の試験まで150日を切ったようなので、これを皮切りにスパートをかけていきたいと思います。

アクチュアリー試験 損保数理の問題をRで解く①

今回は、アクチュアリー試験の問題をRで解きます。

取り上げるのはH25年度の損保数理の第二問Ⅲ 非斉次ポアソン過程の問題です。

 

逆関数法を用いて非斉次ポアソン過程Ntをシミュレーションした一例は次の通りです。

題意のパラメータλは3で仮置きしています。

逆関数法については、こちらなどをご参照ください。)

f:id:r_std:20160626021947p:plain

>||
nhp=function(Tmax,lambda){
u=rep(0,10000)
tau=rep(0,10000)
T=rep(0,10000)

u[1]=runif(1)
tau[1]=-log(u[1])
T[1]=(tau[1]/lambda)^3

u[2]=runif(1)
tau[2]=-log(u[2])+tau[1]
T[2]=(tau[2]/lambda)^3

u[3:10000]=runif(9998)

for(i in 3:100){
tau[i]=-log(u[i])+tau[i-1]
T[i]=(tau[i]/lambda)^3
if(T[i]>Tmax){
T[i]=0
break
}
}
Ti=T[T>0]
N=c(0:length(Ti))
Ti=c(0,Ti)
plot(Ti, N,type = "s",xlab="time",ylab="Nt")
}

nhp(100,3)
||<

 

数値解を求めてみます。

>||
##n件目の事故がある時刻の平均

ETN=function(m,n,lambda){
result=rep(0,m)
for(j in 1:m){
u=rep(0,n)
tau=rep(0,n)
T=rep(0,n)

u[1]=runif(1)
tau[1]=-log(u[1])
T[1]=(tau[1]/lambda)^3

u[2]=runif(1)
tau[2]=-log(u[2])+tau[1]
T[2]=(tau[2]/lambda)^3

u[3:n]=runif(n-2)

for(i in 3:n){
tau[i]=-log(u[i])+tau[i-1]
T[i]=(tau[i]/lambda)^3
}

result[j]=T[n]
}
kekka=mean(result)
return(kekka)
}

ETN(100,5,3)
||<

実行結果は次の通りです。

> ETN(50000,6,3)
[1] 12.42624

 

(I)が正答だとわかります。

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)

線形判別分析について(スイス銀行紙幣①)

はじめまして。

当ブログでは小生の独学した内容(主に機械学習)などについて備忘録をかねてまとめていきたいと考えています。多分に誤りが含まれることが予想されますので、お含みおきください。また、先人の皆様にとっては稚拙な内容にはなりますが、至らぬ点についてはご指導頂ければ幸いです。

 

今回は線形判別分析をとりあげます。データは次の論文のものを以下のサイトから孫引きします。

Flury, B. and Riedwyl, H. (1988). Multivariate Statistics, A Practical Approach, Cambridge University Press

http://mo161.soci.ous.ac.jp/@d/DoDStat/MethodsList/MultivariateAnalysis_allj.html

スイス銀行紙幣について、紙幣の横の長さ、紙幣の縦の長さ(左側)、縦の長さ(右側)、下部マージン、上部マージン、対角線の長さ、真札か偽札かの7つが変数となっているデータです。

 

データの散布図は次の通りです。

f:id:r_std:20160503082222p:plain

赤色が真札、緑色が偽札を示しています。さて、このデータを基にスイス銀行紙幣の真偽を定量的に判別するにはどうしたらよいでしょうか?

今回取り上げる線形判別分析は、各群団からの中心の距離(マハラノビス距離)によって判別を行う手法です。今回はスイス銀行紙幣のデータを真札群と偽札群の2群で判別するので、真札の平均からの距離と偽札の平均からの距離を比較して、距離が小さい方に判別を行います。

次の図は下部マージンと対角線の長さの2変数に絞った場合の線形判別を図示した例になります。

f:id:r_std:20160503154158p:plain

線形判別は各群団間の分散が等しいという前提に基づいた手法であることに注意が必要になります。中心からの距離だけに注目しているため、群団ごとの分布の裾の厚薄には対応できていないことが弱点です。一般的には偽札の方が製造精度が低いことが考えられるため、線形判別はフィットしづらいのではないかという予想のもと実行してみます。

200件のデータを100件ずつ学習用、テスト用に分けて実行したところ、テスト結果は次の通りとなりました。

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

等分散の前提に基づく線形判別分析でも、判別率99%という予想に反して良い結果が出ました。 

 

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

```R
#データの読み込み
sb=read.csv("sbnote.csv")

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

#散布図を描く
y=sb$class
x=sb[,-7]

pairs(x,main="銀行紙幣の散布図",pch = 21, bg=y+2)

#線形判別分析
train_x=sb_train[,-7]
train_y=sb_train$class
sb_lda=lda(train_x,train_y,prior=c(0.5,0.5))
sb_pred=predict(sb_lda)

#学習用データの結果
table(sb_pred$class,train_y)

#テスト用データの結果
test_x=sb_test[,-7]
test_y=sb_test$class
test_lda=predict(sb_lda,test_x)
table(test_lda$class,test_y) ```