glmnetãããå°ãçè§£ãããâ¡
ååã®è¨äºã§ã¯ glmnet ã®ä¸èº«ã確èªãã弿°ã® family ã«ãã£ã¦å¼ã³åºã颿°ãå¤ãã¦ãããã¨ããããã¾ããã
ä»åã¯ãã®ãªãã§ã gaussian ãæå®ãããå ´åã®é¢æ°ã§ãã elnet ãè¦ã¦ããã¾ãããã
ãªãååã®è¨äºã¯ãã¡ãã§ãã
elnet ã®å®è£
ããã§ã¯æ©é elnet ã¨ãã颿°ãè¦ã¦ããã¾ãããã
ã¡ãªã¿ã«ããã§ã® elnet ã¯ã³ã³ã½ã¼ã«ã§ elnet ã¨æã£ã¦ã表示ããã¾ããããC ã Fortran ã§æ¸ããããã®ã§ã¯ãªãã¦åã« glmnet ããã¨ã¯ã¹ãã¼ãããã¦ããªã颿°ãªã®ã§ glmnet:::elnet ã§ä¸èº«ãè¦ããã¨ãã§ãã¾ãã
ãã®é¢æ°ã¯ããã»ã©é·ããªãã®ã§ãããªãå
容ã®ç¢ºèªã«å
¥ãã¾ãããä»ã®å¤ãã®é¢æ°åæ§ã« elnet ã§ãæåã¯ãã©ã¡ã¼ã¿ã®åãåãã»ç¢ºèªãè¡ãã¾ãã
ä¸ã®ãããã¯ã§ã¯åå¾©åæ°ï¼ maxit ï¼ã観測å¤ã®éã¿ï¼ weights ï¼ãåãåã£ãå¾ã type.gaussian ã®æå®å
容ã«ãã£ã¦ ka ã¨ãããã©ã¡ã¼ã¿ã«æ ¼ç´ããå¤ãå¤ãã¦ãã¾ãã
function (x, is.sparse, ix, jx, y, weights, offset, type.gaussian = c("covariance", "naive"), alpha, nobs, nvars, jd, vp, cl, ne, nx, nlam, flmin, ulam, thresh, isd, intr, vnames, maxit) { # 1. ãã©ã¡ã¼ã¿ã®åãåã ### maxit maxit = as.integer(maxit) ### weights weights = as.double(weights) ### type.gaussian type.gaussian = match.arg(type.gaussian) ka = as.integer(switch(type.gaussian, covariance = 1, naive = 2, ))
ka ã¯ããã«å
ã®å¦çã§ elnetu 㨠elnetn ã¨ããï¼ã¤ã®ãµãã«ã¼ãã³ã®ã©ã¡ããå¼ã¶ããæ±ºãã¦ãã¾ãã®ã§ã type.gaussian ã®æå®ã«åããã¦ãµãã«ã¼ãã³ã夿´ãã¦ããã¨ãããã¨ã§ããã
以ä¸ã§ã¯ y ããã³ offset ï¼åå¨ããå ´åï¼ã double ã«å¤æãã¦ãã¾ãã
ã¾ã y ã®éã¿ä»ãå¹³åã使ã£ã¦ Null Deviance ï¼æ®å·®é¸è±åº¦ï¼ãè¨ç®ãã¦ãã¾ãã
### y ã® storage.mode storage.mode(y) = "double" ### offset if (is.null(offset)) { is.offset = FALSE } else { storage.mode(offset) = "double" is.offset = TRUE y = y - offset } ### éã¿ä»ãå¹³å ybar = weighted.mean(y, weights) ### Null Devianceï¼å¸°ç¡ã¢ãã«ã®æ®å·®é¸è±åº¦ï¼ nulldev = sum(weights * (y - ybar)^2) if (nulldev == 0) stop("y is constant; gaussian glmnet fails at standardization step")
次ã®ãããã¯ã§æ©éãã£ããã£ã³ã°ã«å
¥ãã¾ãã
is.sparse ãæå®ããã¦ãããå¦ãã§ spelnet 㨠elnet ã®ã©ã¡ããå¼ã°ããããæ±ºã¾ãã¾ããã弿°ã®éãã¨ãã¦ã¯ spelnet ã«ãã㦠x ã as.double ã¨ããã¦ããã ix 㨠jx ï¼ããããçè¡åã«ããã¦éã¼ãã®è¦ç´ ã®åº§æ¨ãç¹å®ããããã®æ°å¤ï¼ã追å ããã¦ãã¾ãã
# 2. ãã£ããã£ã³ã° ## çè¡åã§ãããã§é¢æ°ãå¤ãã fit = if (is.sparse) .Fortran("spelnet", ka, parm = alpha, nobs, nvars, x, # çè¡åã§ããå ´åã以ä¸ã® ix, jx ã弿°ã¨ãã¦è¿½å ããã # ix, jx ã¯çè¡åã«ãããéã¼ãã®è¦ç´ ã®ç´¯ç©åæ°ã¨è¡çªå· ix, jx, y, weights, jd, vp, cl, ne, nx, nlam, flmin, ulam, thresh, isd, intr, maxit, lmu = integer(1), a0 = double(nlam), ca = double(nx * nlam), ia = integer(nx), nin = integer(nlam), rsq = double(nlam), alm = double(nlam), nlp = integer(1), jerr = integer(1), PACKAGE = "glmnet") else .Fortran("elnet", ka, parm = alpha, nobs, nvars, as.double(x), y, weights, jd, vp, cl, ne, nx, nlam, flmin, ulam, thresh, isd, intr, maxit, lmu = integer(1), a0 = double(nlam), ca = double(nx * nlam), ia = integer(nx), nin = integer(nlam), rsq = double(nlam), alm = double(nlam), nlp = integer(1), jerr = integer(1), PACKAGE = "glmnet") # nx 㯠éã¼ãã®å¤æ°ã®åæ° # nlam ã¯æ¤è¨¼ãã lambda ã®åæ° # ãªã®ã§ ca ã¯å¤æ°ã®æ° * lambda ã®æ°
å¦çãæãããã¨ã¯ãã¨ã©ã¼ããã§ãã¯ããä¸ã§å¿ è¦ãªãã©ã¡ã¼ã¿ãåå¾ãã¾ãã
# 3. å¾å¦ç ## ã¨ã©ã¼ãã§ã㯠if (fit$jerr != 0) { errmsg = jerr(fit$jerr, maxit, pmax = nx, family = "gaussian") if (errmsg$fatal) stop(errmsg$msg, call. = FALSE) else warning(errmsg$msg, call. = FALSE) } ## ãã©ã¡ã¼ã¿ï¼åçãåå¸°ä¿æ°ãèªç±åº¦ã次å ãlambdaï¼ãåã£ã¦ãã outlist = getcoef(fit, nvars, nx, vnames) ## ãã©ã¡ã¼ã¿ï¼xxxxxxxxxxï¼ãåã£ã¦ã㦠outlist ã«çµåãã dev = fit$rsq[seq(fit$lmu)] outlist = c(outlist, list(dev.ratio = dev, nulldev = nulldev, npasses = fit$nlp, jerr = fit$jerr, offset = is.offset)) ## elnet ã¯ã©ã¹ãä»ä¸ãã class(outlist) = "elnet" outlist }
ããã§ã¯æ¬¡ã« elnet ã®æ¬ä½ã§ãã elnetï¼ãããããã§ããï¼ ã®ä¸èº«ãè¦ã¦ããã¾ãããã
elnetï¼äºåº¦ç®ï¼ã®å®è£
ä¸è¨ã®ãã£ããã£ã³ã°ã®ã»ã¯ã·ã§ã³ã§ elnet 㯠.Fortran("elnet") ã¨ãã¦å¼ã°ãã¦ãã¾ãããããã¾ã§ glm ã GAM ã§è¦ã¦ããã¨ãã¨åãããã«ã glmnet ã§ããã¯ã fortran ã«è¡ãçãããã§ããã
ã¨è¨ã£ã¦ãããã§ã¯ã¾ã 颿°èªä½ã¯å¤§ãããªããä¸ã®ããã«ï¼ã³ã¡ã³ãæãã§ï¼30è¡ç¨åº¦ã§æ¸ããã¦ãã¾ãã
subroutine elnet(ka,parm,no,ni,x,y,w,jd,vp,cl,ne,nx,nlam, flmin,u *lam,thr,isd,intr,maxit, lmu,a0,ca,ia,nin,rsq,alm,nlp,jerr) implicit double precision(a-h,o-z) double precision x(no,ni),y(no),w(no),vp(ni),ca(nx,nlam),cl(2,ni) double precision ulam(nlam),a0(nlam),rsq(nlam),alm(nlam) integer jd(*),ia(nx),nin(nlam) double precision, dimension (:), allocatable :: vq; ! vp ã 0.0 ã ã£ãå ´åã«ã¯ jerr = 100000 ã¨ã㦠return ãã¦ãã¾ã if(maxval(vp) .gt. 0.0)goto 10021 jerr=10000 return 10021 continue allocate(vq(1:ni),stat=jerr) ! ããã§ã jerr ã« 0 以å¤ã®æ°å¤ãå ¥ã£ã¦ããã return ãã¦ãã¾ã if(jerr.ne.0) return ! vp ã®å¤ã«ãã£ã¦ vq ãçæ ! ããã©ã«ã㯠1 ! ni 㯠nvars ã§å¤æ°ã®æ°ãªã®ã§ã vq ã«ã¯ããã©ã«ãã§ã¯å¤æ°ã®æ°ãå ¥ã ! ã§ããªãã§ sum(vq) ãªãã ã vq=max(0d0,vp) vq=vq*ni/sum(vq) ! elnetu ã elnetn ã®ã©ã¡ããå¼ã¶ã㯠ka .ne. 1 ã§ãããã§å¤æãã¦ãã ! 1 ã§ãªããã° elnetn ã 1 ãªã elnetu if(ka .ne. 1)goto 10041 call elnetu (parm,no,ni,x,y,w,jd,vq,cl,ne,nx,nlam,flmin,ulam,thr, *isd,intr,maxit, lmu,a0,ca,ia,nin,rsq,alm,nlp,jerr) goto 10051 10041 continue call elnetn (parm,no,ni,x,y,w,jd,vq,cl,ne,nx,nlam,flmin,ulam,thr,i *sd,intr,maxit, lmu,a0,ca,ia,nin,rsq,alm,nlp,jerr) 10051 continue continue deallocate(vq) return end
goto ãå¤ç¨ãã¦ãã¾ããããã
夿°å®£è¨ä»¥ä¸ã§æ°ã«ãªãã¨ããã¨ãã¦ã¯ã vp ã 0 ã ã£ãã¨ãã®æåã¨ã elnetu ãå¼ã¶ã¨ããã§ããããã
vp ã¯ååã®è¨äºã§ç¢ºèªããéãã glmnet ã®ãªãã§ vp = as.double(penalty.factor) ã¨ãã¦å®ç¾©ããã¦ãã¾ãã
ãã® penalty.factor ã¯ããã©ã«ãã§ã¯ 1 ãå
¥ãã¾ãã®ã§åºæ¬çã«ã¯ goto 10021 ã§é£ã°ããã¦ãã¾ãã¾ãã
ãã®ã»ã¯ã·ã§ã³ã§å¼ã£ãããã®ã¯æç¤ºçã« penalty.factor ã« 0 ãæå®ããå ´åã§ããã
! vp ã¯å夿°ã«å¯¾ããç½°åã®éã¿ï¼ããã©ã«ã㯠1ï¼ ãå ¥ã£ããã¯ãã« ! vp = as.double(penalty.factor) ! jerr ã®æ°å¤ã§å¾ç¶ã®å¦çã§åºåããã¨ã©ã¼ã¡ãã»ã¼ã¸ã決ã¾ã if(maxval(vp) .gt. 0.0)goto 10021 jerr=10000 return 10021 continue allocate(vq(1:ni),stat=jerr)
ã§ã¯ penalty.factor ã« 0 ãæå®ããå ´åã¯ã©ããªããã¨è¨ãã¨ã jerr ã« 10000 ãå
¥åãã㦠return ããã¾ãã
ãã® jerr ã¯å
ã»ã©ç¢ºèªããå¾å¦çã«ãã㦠errmsg = jerr(fit$jerr, maxit, pmax = nx, family = "gaussian") ã¨ãã¦ã¨ã©ã¼ã¡ãã»ã¼ã¸ã«å¤æãããã®ã§ããã
ã¾ããã® jerr ã¨ãã颿°ã¯ glmnet ã§å®ç¾©ããã¦ãã¾ãã®ã§ã
> glmnet:::jerr function (n, maxit, pmax, family) { if (n == 0) list(n = 0, fatal = FALSE, msg = "") else { errlist = switch(family, gaussian = jerr.elnet(n, maxit, pmax), binomial = jerr.lognet(n, maxit, pmax), multinomial = jerr.lognet(n, maxit, pmax), poisson = jerr.fishnet(n, maxit, pmax), cox = jerr.coxnet(n, maxit, pmax), mrelnet = jerr.mrelnet(n, maxit, pmax)) names(errlist) = c("n", "fatal", "msg") errlist$msg = paste("from glmnet Fortran code (error code ", n, "); ", errlist$msg, sep = "") errlist } }
ã¨ãã¦åãåºãã¾ãã
颿°ãã¿ã¦ã¿ãã¨ã errlist 㯠switch(family, ~) ã§æ´ã«ç°ãªã颿°ãå¼ã³åºãããã®çµæãæ ¼ç´ãã¦ããããã§ãã
ãã®ããæ´ã« jerr.elnet ã確èªããã¨
> glmnet:::jerr.elnet function (n, maxit, pmax) { if (n > 0) { if (n < 7777) msg = "Memory allocation error; contact package maintainer" else if (n == 7777) msg = "All used predictors have zero variance" else if (n == 10000) msg = "All penalty factors are <= 0" else msg = "Unknown error" list(n = n, fatal = TRUE, msg = msg) } else if (n < 0) { if (n > -10000) msg = paste("Convergence for ", -n, "th lambda value not reached after maxit=", maxit, " iterations; solutions for larger lambdas returned", sep = "") if (n < -10000) msg = paste("Number of nonzero coefficients along the path exceeds pmax=", pmax, " at ", -n - 10000, "th lambda value; solutions for larger lambdas returned", sep = "") list(n = n, fatal = FALSE, msg = msg) } }
else if (n == 10000) msg = "All penalty factors are <= 0" ã¨ãç½°åé
ã 0 ã§ãããã¨ãæãã¦ããã¦ãã¾ããã
ãã¦ç¶ã㦠elnetu ã®å¼ã³ã ãã確èªããã¨ãelnetu 㨠elnetn ã®ããããå¼ã¶ã㯠ka ã§æ±ºã¾ã£ã¦ãã¾ãã
å
ã»ã©å°ã触ããéãã ka 㯠ka = as.integer(switch(type.gaussian, covariance = 1, naive = 2, )) ã§å®ç¾©ããã¦ãã¾ãã
ã¾ã type.gaussian 㯠glmnet ã®å¼æ°ã§ãããtype.gaussian = ifelse(nvars < 500, "covariance", "naive") ã¨å®ç¾©ããã¦ãã¾ãã
夿°ã®æ°ã 500 æªæºã§ããã° covarinace ã¨ãªãã ka ã«ã¯ 1 ãå¼ã渡ãããã®ã§ if(ka .ne. 1) ã«ã¯è©²å½ããããããã£ã¦ elnetu ãå¼ã°ãããã¨ã«ãªãããã§ããã
! elnetu ã elnetn ã®ã©ã¡ããå¼ã¶ã㯠ka .ne. 1 ã§ãããã§å¤æãã¦ãã ! 1 ã§ãªããã° elnetn ã 1 ãªã elnetu ! ka 㯠elnet ã®ç¬¬ä¸å¼æ° ! ka = as.integer(switch(type.gaussian, covariance = 1, naive = 2, )) ! ãã® covariance / naive ã¯å¤æ°ã®æ°ã§æ±ºã¾ã ! type.gaussian = ifelse(nvars < 500, "covariance", "naive") if(ka .ne. 1)goto 10041 call elnetu (parm,no,ni,x,y,w,jd,vq,cl,ne,nx,nlam,flmin,ulam,thr, *isd,intr,maxit, lmu,a0,ca,ia,nin,rsq,alm,nlp,jerr) goto 10051 10041 continue call elnetn (parm,no,ni,x,y,w,jd,vq,cl,ne,nx,nlam,flmin,ulam,thr,i *sd,intr,maxit, lmu,a0,ca,ia,nin,rsq,alm,nlp,jerr)
次åã¯ãã® elnetu ãè¦ã¦ã¿ã¾ãããã