glmnetで多クラスのロジスティック回帰
誰かやってるようでなかったのでメモ。
glmnetはElastic Net(L1で罰則つけるlasso回帰、L2で罰則つけるリッジ回帰のまぜあわせ)ができるパッケージで、こいつを使うと多クラスのロジスティック(多項ロジスティック)回帰もできる。
まずパッケージを突っ込む。
install.packages("glmnet") library("glmnet")
ここでは定番のirisデータで、3値クラス分類をやってみる。xはdata.frameではなく行列しか受け付けない、めんどいが型変換が必要。
x <- as.matrix(iris[,-5]) y <- iris[,5]
実行結果は載せないが、デフォルトだと罰則の強さλを適当に複数の値(グリッド)で割り振って回帰した結果が返ってくる。またデフォルトではラッソ・リッジの混ぜ込み具合であるパラメータαが1になっており、ラッソ回帰になる。結果出てくるモデルの係数を取るにはcoef関数を指定する。type.multinomialは、各クラス(Species, setosaとか)ごとに推計されるパラメータにおいて、ない場所(0となる箇所)を同じに揃えてくれるというオプション。更に、family引数を調整すれば多クラスのロジスティック以外、例えば通常のロジスティック回帰(binomialにする)も実行できる。
coef(glmnet(x, y, family="multinomial")) coef(glmnet(x, y, family="multinomial", type.multinomial="grouped"))
罰則の強さλは考えてもしょうがないんでクロスバリデーション(CV)で決めちゃおうってのが、cv.glmnet関数。そして、最適(デフォルトがlambda.1seになってるが意味がわからん)なλで予測するのがpredict関数だ。ここでは分類結果(class)を返させているが、type引数をいじると各クラスに所属する確率(response)やらも返してくれる。
cvfit <- cv.glmnet(x, y, family="multinomial", type.multinomial="grouped") pred <- predict(cvfit, newx=x, type="class")
もとのデータをどのくらい正しく分類できているのかを見て見ると、結構いい感じだ。
> table(pred, iris[,5]) pred setosa versicolor virginica setosa 50 0 0 versicolor 0 47 1 virginica 0 3 49