ラッ疎回帰のCVがガチャなので禁を犯してcv.foldsを書き換える記事
最近ビッグデータ占い師の研究をしており、関数型言語Rと格闘しています。
LASSO回帰という便利な回帰があります。
Ridge回帰との主な違いとして、Ridgeは名詞、LASSOは略語*1です。
高次元空間ではL1-normが1となる点の集合が成す多面体の角っこがトゲトゲするので、二乗和誤差の等高線が軸上でぶつかりやすくなるため、パラメータの多くが0になります。
glmnetとlarsという2種類のパッケージがあるが、前者はなんかR3.0.3では使えなかった。
後者は正則化項の係数を交差検定で決定できるcv.larsなる関数がある。これで自動的に決定したい。
N <- 10 # N-fold cross validation cv.result <- cv.lars( ....., N )
で色々計算し、
lambda <- cv.result$index[which.min(cv.result$cv)]
で最適な生息加工の係数lambdaを得る。
cv.larsは、入力された事例を乱数に基づいてN個のグループに分割し、N分割交差確認でパラメータを決定する。
入力事例が少ないと、ランダムゆえ推定値が安定しない。交差検定ガチャ。なんとかしたい。
普通に考えて事例数Dのデータに対して、D分割をすれば、分割にランダム要素がなくなるため、結果も安定する。
でも以下のようにしてcv.larsが内部で呼ぶcv.foldsを書き換えても良さそう。
tmp <- function(n, folds) { comb <- combn(1:n, 1) rv <- list() for (i in 1:ncol(comb)) { rv[[sprintf("%d", i)]] <- as.numeric(comb[,i]) } return(rv) } unlockBinding("cv.folds", environment(fun=lars)) assignInNamespace("cv.folds", tmp, ns="lars", envir=environment(fun=lars)) assign("cv.folds", tmp, envir=environment(lars)) lockBinding("cv.folds", environment(lars)) cv.folds <- tmp # 今のnamespaceにも残滓が残るので。
ちなみに後半部では、名前空間を†解錠†してcv.foldsを†リライト†しています。
combnの第二引数を1から整数Kへ書き換えると、データ集合からKこの元を取り出す全ての組み合わせをfold-out集合とするようになる。
もはや分割ではない(これも交差確認と呼べるのか?)。第二引数を1から2へ変えて試しても、結果が一致しない。何がどう違うんだろう。
アイスコーヒーおいしい〜
*1:LASSO: least absolute shrinkage and selection operator