Rのmodel.matrixの説明

glmnetrandomForestといったパッケージで教師有り学習(回帰)を行う際に、Rのformulaを直接与えると、 data.frameでは変数の数が多い場合にオーバーヘッドがでかくなる場合がある。

あらかじめ前処理としてmodel.matrix(どの列が説明変数で、どの列が応答変数なのかの情報をmatrixに含ませたもの)に変換しておくと、各列の変数の型がそろうのでメモリ使用量が大幅に減る場合がある。

data.matrixというものもあるが、こういった場合には使用するべきでない。なぜならfactorが整数値になってしまい、互いに独立であるはずのfactor間に大小関係が生まれてしまうため。例えば


df = data.frame(x=c('a', 'b', 'c'), y=c(1, 2, 3))
print(data.matrix(df))
##      x y
## [1,] 1 1
## [2,] 2 2
## [3,] 3 3

xa + b = cという望ましくない関係が生まれてしまう。

対してmodel.matrixを使用するとfactorを自動でダミー変数化(別々の列に分解)してくれる。


print(model.matrix(as.formula(~0+x+y), # x, y共に説明変数のデザイン行列を作る
                   data=df)
     )

これは以下のような出力を出す。


##   xa xb xc y
## 1  1  0  0 1
## 2  0  1  0 2
## 3  0  0  1 3
## attr(,"assign")
## [1] 1 1 1 2
## attr(,"contrasts")
## attr(,"contrasts")$x
## [1] "contr.treatment"

xxa, xb, xcの3列に分解されていることがわかる。

なんのためにformula0+を加えているかというと、これを加えない場合Rxa, xb, xcのうち一つを省略するため。 (xb, xcがともに0ならばxaは必ず1になるため2列あれば3列目の内容は必ずしも必要ない)

だが、話をややこしくしないためにとりあえず0+を加えておいた方がよいと思う。

応答変数は何なんだと思うかもしれないが、例えばglmnet::glmnetの場合は引数として別に与えるので、model.matrixに含ませる必要はない。

多くのRの回帰関数(e.g. lm)は、このようなダミー変数化とデザイン行列への変換を自動で行ってくれるため、変数がnumericでなくても何も考えずに使うことができる。

参考

Tweet This Page
BTC address: 16BQGsTmsKtbMMT2Zwj4qNZnnAncnVCtWo
NEM address: NBZ5WW-S53QRZ-DO73Z7-B6CA6I-R2PNS4-PLR24N-NKZJ 投げ銭をいただけると泣いて喜びます