モモノキ&ナノネと一緒にRで機械学習を試してみよう
Rで機械学習、決定木でIrisデータを分類
ナノネ、統計解析用フリーソフト『R』の使い方を練習するよ。今回は機械学習の決定木(decision tree)を試してみよう。
枝分かれして分類するやつね。
データは今回もIrisを使うよ。
3種類のアヤメは少し覚えたかも。Irisは前回のSVM練習でも使ったし。
これが『Setosa』で、
これは『Versicolor』、
こっちが『Virginica』だよね。
データもグラフで再確認。
plot(iris, col=c(2, 3, 4)[iris$Species])
今回は決定木分類に『rpart』を使うよ。rpartはRにデフォルトでインスールされてるみたいだから、library()で読み込んでみて。
# install.packages("rpart") # 必要に応じインスール
library(rpart)
rpart準備OK。
さっそく決定木で分類をやってみよう。rpart()で引数にモデル式とデータを指定すれば、とりあえず分類を実行できるよ。
モデル式は目的変数がSpecies(アヤメの種類)、~でつないで、残り4つを説明変数に設定(ピリオドで目的変数以外を全指定)。dataにはirisを指定すればOKだね。
モデルを作るコードはsvmのときと同じ感じだね。
iris.rpart <- rpart(Species ~ ., data = iris) # 決定木モデル作成
iris.rpart
分類できたみたいだけど...。Rでも分かりやすく図示できる?
図示できるよ。決定木の分類結果を図示する方法は複数あるから、いくつか実際に試してみよう。
# 決定木の図示 その1
plot(iris.rpart)
text(iris.rpart, use.n=TRUE, cex=0.5)
シンプルな図だけど、どう分類されたか分かるね。Petal.Length(がく片長さ)が2.45より小さいとsetosa。2.45以上のときはさらに分岐してPetal.Width(花弁幅)が1.75より小さいとversicolor、1.75以上だとvirginicaに分類されている。
次はもうちょっとグラフィカルに。partykitを使って図示してみよう。
# 決定木の図示 その2
# install.packages("partykit") # 初回利用時はインスール必要
library(partykit) # partykit読み込み
options(repr.plot.width=10, repr.plot.height=7) # グラフサイズ調整(jupyter notebook)
plot(as.party(iris.rpart)) # プロットの引数にas.party(データ)を指定
グラフも付いてちょっと見やすくなったかも。
最後はポップな感じに。rpart.plotを使って図示してみよう。
options(repr.plot.width=7, repr.plot.height=7) # グラフサイズデフォルト
# 決定木の図示 その3-1
# install.packages("rpart.plot") # 初回利用時はインスール必要
library(rpart.plot) # rpart.plot読み込み
rpart.plot(iris.rpart) # プロット
カラフルな図になった。見やすさは好みにもよるけど。
オプションでtypeとextraを変更すると表示方法を少し変更できるみたい。いろいろ試して見てね。
# 決定木の図示 その3-2
rpart.plot(iris.rpart, type=4, extra=1) # オプションのtypeとextraで表示方法変更
分類結果の図示方法はこれくらいにして、次は決定木モデルで予測をやってみよう。
まずは訓練用とテスト用データを準備。前回のSVM練習と一緒で、割合は適当に訓練用70%、テスト用30%としておこう。
# 訓練データとテストデータに分割
set.seed(100)
df.rows = nrow(iris) # 150
train.rate = 0.7 # 訓練データの比率
train.index <- sample(df.rows, df.rows * train.rate)
df.train = iris[train.index,] # 訓練データ
df.test = iris[-train.index,] # テストデータ
cat("train=", nrow(df.train), " test=", nrow(df.test))
データ準備完了。訓練用が105データ、テスト用は45データ。
次は訓練データを使って決定木のモデルをつくるよ。
model.rpart <- rpart(Species ~ ., data = df.train) # 決定木モデル、データは訓練用を指定
式の書き方は最初と一緒で、データに訓練用を指定すればOKかな。
続いて訓練データで学習したモデルを使って、テストデータの予測をやってみよう。予測はpredict()で、引数にモデルとデータを指定してね。あと分類の場合はオプション引数のtypeに"class"も指定しておいてね。
# テストデータの予測
prediction = predict(model.rpart, df.test, type="class" )
OK、さっき作ったモデルとテストデータを指定、typeは"class"とした。
うまく分類できたかな?tableを使って予測と正解を確認してみよう。
(result <- table(prediction, df.test$Species)) # ()で括って内容表示
# 精度の計算(行列の対角合計 / 行列の合計)
(accuracy_prediction = sum(diag(result)) / sum(result))
正解率は93.3%でまずまずの結果。グラフにプロットしてみる。
# モデル予測結果を図示(Petal.Length / Petal.Width)
par(mar = c(6, 7, 5, 2))
par(mgp = c(4, 1.2, 0.4))
par(lwd = 2)
plot(df.test$Petal.Length, df.test$Petal.Width,
main = "Iris (decision tree)",
xlab = "Petal length (cm)",
ylab = "Petal width (cm)",
#col = prediction,
pch=c(1,2,3)[prediction],
cex = 2,
cex.main = 2,
cex.lab = 2,
cex.axis = 1.5,
xlim = c(0, 7),
ylim = c(0, 3.5),
yaxp = c(0, 3, 3)
)
par(family = "serif")
par(font = 3)
legend("topleft",
legend = levels(prediction),
pch = c(1, 2, 3),
# col = c(1, 2, 3),
cex = 1.7,
pt.cex = 2,
bty = 'n',
inset = c(0.05, 0.03))
今回はPetal.LengthとPetal.Widthを軸にプロットしてみた。
Rのグラフの作成も少し慣れてきたね。
最後に木の複雑さを調整してみよう。木の枝を刈ったり、伸ばしたりする方法だよ。
木の複雑さの調整は、rpart()オプションのcontrolパラメータを変更すればOK。木を作る制約条件を変更できるよ。
controlパラメータとデフォルト値は下の通り。minsplit、cp、maxdepthあたりの値を変更するといい感じに調整できるよ。
rpart.control()
どんな数値を指定すればよいかは、printcp(モデル)やplotcp(モデル)を出力すると参考になるよ。
iris.rpart <- rpart(Species ~ ., data = iris) # 決定木モデル
printcp(iris.rpart)
plotcp(iris.rpart)
たとえば、枝を短くする場合。
options(repr.plot.width=12, repr.plot.height=7)
iris.rpart <- rpart(Species ~ .,
data=iris,
control = rpart.control(cp = 0.44)) # maxdepth = 1としても同じ結果
plot(as.party(iris.rpart))
こんどは枝を長くする場合の例だよ。
options(repr.plot.width=12, repr.plot.height=7)
iris.rpart <- rpart(Species ~ .,
data=iris,
control = rpart.control(
minsplit=0, # 分岐の最少データ数(小さいと細かく分岐)
cp=0, # モデルの複雑さ(小さいと細かく分岐)
maxdepth = 5)) # 木の最大深さ(大きいと細かく分岐)
plot(as.party(iris.rpart))
printcp(iris.rpart)
あとでパラメータの値を変えて、いろいろ試してみるよ。
今回の決定木を使った分類練習は以上で。
またね!
0 件のコメント :
コメントを投稿