ランダムフォレストのチューニングとは?

にほんブログ村 科学ブログ 数学へ

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

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

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

 

パッケージのインストールと準備

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

install.packages("randomForest")

 

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

library(randomForest)

 

例題として使用するデータ

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

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

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

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

 

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

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

> 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

> 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

 

ランダムフォレストをチューニングする

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()で実行できる。

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