統計ER

R, EZR, SPSS, KH Coder を使ったデータ分析方法を紹介するブログ。ニッチな内容が多め

ランダムフォレストの最適化

ランダムフォレストはチューニングして最適化する。

チューニングは決定木を最適化する方法。

ランダムフォレストの場合は、決定木の数と特徴量(説明変数)の数を最適化する。

 

↑1万人以上の医療従事者が購読中

 

 

ランダムフォレストのパッケージのインストールと準備

最初に一回だけパッケージのインストールをする。

install.packages("randomForest")

 

呼び出して使えるように準備する。

library(randomForest)

 

ランダムフォレストの最適化のために例題として使用するデータ

MASSパッケージのfglデータを使う。

fglはForensic Glass Fragmensのデータで、法医学におけるガラス片のデータ。

RIという屈折率Refractive Indexと7種類の金属の酸化物のデータで、ガラスのタイプを識別するという課題。

ガラスのタイプは10列目のデータ。

library(MASS)
head(fgl)
table(fgl$type)

 

先頭から5行を見てみるとこんな感じ。

 

> head(fgl)
     RI    Na   Mg   Al    Si    K   Ca Ba   Fe type
1  3.01 13.64 4.49 1.10 71.78 0.06 8.75  0 0.00 WinF
2 -0.39 13.89 3.60 1.36 72.73 0.48 7.83  0 0.00 WinF
3 -1.82 13.53 3.55 1.54 72.99 0.39 7.78  0 0.00 WinF
4 -0.34 13.21 3.69 1.29 72.61 0.57 8.22  0 0.00 WinF
5 -0.58 13.27 3.62 1.24 73.08 0.55 8.07  0 0.00 WinF
6 -2.04 12.79 3.61 1.62 72.97 0.64 8.07  0 0.26 WinF

ガラスのタイプは6種類。

> table(fgl$type) WinF WinNF Veh Con Tabl Head 70 76 17 13 9 29

 

通常のランダムフォレストを実行してみる。

set.seed(2)
fgl.rf <- randomForest(type ~ ., data=fgl)
fgl.rf
varImpPlot(fgl.rf)

 

結果は以下の通り、説明変数は3つで、エラー率は21.5%

randomForest()のデフォルトは全説明変数の数(9つ)の平方根なので、ピッタリ合っている。

> fgl.rf

Call:
 randomForest(formula = type ~ ., data = fgl) 
               Type of random forest: classification
                     Number of trees: 500
No. of variables tried at each split: 3

        OOB estimate of  error rate: 21.5%
Confusion matrix:
      WinF WinNF Veh Con Tabl Head class.error
WinF    62     6   2   0    0    0   0.1142857
WinNF   12    58   1   3    1    1   0.2368421
Veh      7     3   7   0    0    0   0.5882353
Con      0     3   0   9    0    1   0.3076923
Tabl     0     2   0   0    7    0   0.2222222
Head     1     3   0   0    0   25   0.1379310

 

ジニ不純度の減少量で見る重要な変数3つは、マグネシウムとアルミニウムと屈折率。

ジニ不純度が大きく下がる変数が、識別に役立つ重要な変数。

f:id:toukeier:20180911214421p:plain

 

↑1万人以上の医療従事者が購読中

 

ランダムフォレストを最適化(チューニング)する

tuneRF()を使う。

()内のdoBest=Tは最適な決定木をobjectとして返すオプション。

set.seed(2)
fgl.res <- tuneRF(fgl[,-10], fgl[,10], doBest=T)
fgl.res
varImpPlot(fgl.res)

 

結果はエラー率19.16%になった。

説明変数は2つに減った。

> fgl.res <- tuneRF(fgl[,-10], fgl[,10], doBest=T)
mtry = 3  OOB error = 22.43% 
Searching left ...
mtry = 2        OOB error = 21.5% 
0.04166667 0.05 
Searching right ...
mtry = 6        OOB error = 25.7% 
-0.1458333 0.05 
> fgl.res

Call:
 randomForest(x = x, y = y, mtry = res[which.min(res[, 2]), 1]) 
               Type of random forest: classification
                     Number of trees: 500
No. of variables tried at each split: 2

        OOB estimate of  error rate: 19.16%
Confusion matrix:
      WinF WinNF Veh Con Tabl Head class.error
WinF    62     6   2   0    0    0   0.1142857
WinNF    9    62   1   1    2    1   0.1842105
Veh      7     4   6   0    0    0   0.6470588
Con      0     2   0  10    0    1   0.2307692
Tabl     0     1   0   0    8    0   0.1111111
Head     1     3   0   0    0   25   0.1379310

 

tuneRF()では、説明変数がいくつの時にエラー率が一番小さくなるかが自動的に図示される。

f:id:toukeier:20180911214545p:plain

 

ジニ不純度の減少量で見る重要な変数上位 2 つは、マグネシウムとアルミニウム。

f:id:toukeier:20180911214509p:plain

ランダムフォレストの最適化のために決定木の数を変えてやってみる

最後にntreeをデフォルトの500から2000に増やしてエラー率の変化を見てみる。

set.seed(2)
fgl.rf2 <- randomForest(type ~ ., data=fgl, mtry=2, ntree=2000)
fgl.rf2
plot(fgl.rf2)

 

最終的なエラー率は19.63%と大きくは改善しなかった。

> fgl.rf2

Call:
 randomForest(formula = type ~ ., data = fgl, mtry = 2, ntree = 2000) 
               Type of random forest: classification
                     Number of trees: 2000
No. of variables tried at each split: 2

        OOB estimate of  error rate: 19.63%
Confusion matrix:
      WinF WinNF Veh Con Tabl Head class.error
WinF    62     6   2   0    0    0   0.1142857
WinNF   10    62   1   1    1    1   0.1842105
Veh      7     4   6   0    0    0   0.6470588
Con      0     3   0   9    0    1   0.3076923
Tabl     0     1   0   0    8    0   0.1111111
Head     1     3   0   0    0   25   0.1379310

 

黒の実線がエラー率。

それ以外はクラスエラー率。

デフォルトの500個でほぼ収束しているのが見て取れる。

f:id:toukeier:20180911220949p:plain

 

まとめ

ランダムフォレストをチューニング(最適化)してみた。

統計ソフトRのrandomForestパッケージにあるtuneRF()で実行できる。

よりエラー率が低い決定木を作成することに成功した。