glmnet part 05 - Sparse Matrices

Glmnet Vignette


Trevor Hastie and Junyang Qian
Stanford September 13, 2016

희귀 행렬 (Sparse Matrices)

우리의 패키지는 희귀 입력 행렬을 지원한다, 거대한 행렬에서 효율적인 저장 공간과 동작을 허용 그러나 단지 소수의 0이 아닌 요소. 그것은 cox 군을 제외한 모든 군에서 사용 가능하다. glmnet에서 희귀 행렬(패키지 Matrix에서 클래스 sparseMatrix으로 부터 상속)의 사용은 마치 정규 행렬을 제공하는 것 처럼 같다.
우리는 미리 생성된 표본 데이터의 집합을 적재한다.
data(SparseExample)
그것은 x를 적재한다, 100 × 20 희귀 입력 행렬 그리고 y, 응답 벡터.
class(x)

## [1] "dgCMatrix"
## attr(,"package")
## [1] "Matrix"
사용자는 0이 아닌 요소의 위치와 값을 제공하여 함수 sparseMatrix를 가지고 희귀 행렬을 생성할 수 있다. 대안으로, Matrix 함수는 sparse = TRUE 설정으로 희귀 행렬을 구축하기 위해 또한 사용할 수 있다, 그러나 이것은 무엇인가 목적에서 벗어난다.
우리는 이전과 같은 방법으로 모델을 적합할 수 있다.
fit = glmnet(x, y)
우리는 또한 교차 검증을 수행할 수 있고 그리고 결과 객체를 plot한다.
cvfit = cv.glmnet(x, y)
plot(cvfit)
다른 함수의 사용은 비슷하다 그리고 우리는 여기서 설명하지 않는다.
희귀 행렬은 또한 newx로 사용될 수 있음을 주목하라, predict 함수에 새 입력 행렬, 예를 들어,
i = sample(1:5, size = 25, replace = TRUE)
j = sample(1:20, size = 25, replace = TRUE)
x = rnorm(25)
nx = sparseMatrix(i = i, j = j, x = x, dims = c(5, 20))
predict(cvfit, newx = nx, s = "lambda.min")

##               1
## [1,]  0.3825586
## [2,] -0.2172428
## [3,] -1.6621635
## [4,] -0.4174700
## [5,] -1.3940989

부록 0: 수렴 기준 (Appendix 0: Convergence Criteria)

Glmnet은 계수의 변화가 아닌 오히려 적합 값에 변화의 충격에 초점을 맞춘 수렴 기준을 사용한다, 그러므로 목적의 손실 부분. 순 결과는 계수 변화 벡터의 가중치 노름(weighted norm)이다.
가우시안 모델에서 그것은 다음으로 사용한다. 관측 i가 가중치 ωi를 가진다고 가정해라. νj를 변수 xj의 (가중) 제곱-합으로 놓아라:
만약 모델에서 교차점(intercept)가 있으면, ωj는 가중 평균으로 중앙화 될 것이다, 그러므로 이것은 가중 분산이 될 것이다. ^βj0^βjn로 갱신된 후에, 우리는 Δj = ν( ^βj0^βjn)2를 계산한다. 좌표 강하의 순환 계산 후에, 우리는 Δmax = maxjΔj를 본다. 왜 이 측정인가? 우리는 작성할 수 있다:
이 조건에서 적합 값에 변화의 가중 제곱 합을 측정. 이것은 적합에서 이 계수의 변화의 충격을 측정한다. 만약 가장 큰 그런 변화가 무시해도 좋다면, 우리는 중단한다.
로지스틱 회귀, 그리고 다른 비-가우시안 모델에서 그것은 내부 루프(loop)와 비슷하다. 단지 지금은 각 관측에서 가중치는 더 복잡하다. 예로, 로지스틱 회귀에서 가중치는 현재 뉴튼 단계(current Newton step)에서 발생하는 그런 것이다, 즉 ωi* = ωi pi^(1 - pi^). 그러므로 pi^은 우리가 현재 내부 루프로 입력한 적합 확률이다. 직관적으로 같다 - 그것은 현재 가중 최소 제곱 손실, 또는 로그-우도 손실에서 이차 근사로 계수 변화의 충격을 측정한다.
외부-루프 수렴은 무엇인가? 우리는 같은 측정을 사용한다, 지금 ^β0은 우리가 이 내부 루프를 입력하기 전에 계수 벡터를 제외, 그리고 ^βn는 이 내부 루프에서 수렴 해법. 그러므로 만약 이 뉴튼 단계가 영향이 없다면, 우리는 외부-루프 수렴을 선언할 수 있다.

부록 1: 내부 변수 (Appendix 1: Internal Parameters)

우리의 패키지는 경로 계산의 어떤 측면을 통제하는 내부 변수의 집합을 가진다. factory default 설정은 가장 일반적인 경우에 제공하는 것으로 예상되었다, 그리고 사용자는 특별한 요구가 없다면 변경할 필요가 앖다.
사용자가 변경할 수 있는 몇 개의 변수가 있다:
fdev - 경로를 중지하기 위한 편차에서 최소 부분 변화; factory default = 1.0e-5
devmax - 경로를 중지하기 위한 설명 편차의 최대 변화; factory default = 0.999
  • eps - lambda.min.ratio의 최소 값(glmnet을 보라); factory default= 1.0e-6
  • big - 큰 부동 소수점 수(large floating point number); factory default = 9.9e35. upper.limit의 정의에서 Inf는 크게 설정되었다
  • mnlam - 허용된 경로 포인트(람다 값)의 최소 수; factory default = 5
  • pmin - 어떤 분류에서 최소 null 확률; factory default = 1.0e-5
  • exmx - 최대 허용 지수; factory default = 250.0
  • prec - 다중-응답 경계 조정 해법의 수렴 임계점; factory default = 1.0e-10
  • mxit - 다중-응답 경계 조정 해법의 최대 반복; factory default = 100
  • factory - 만약 TRUE 이면, 모든 변수를 팩토리 기본값으로 재설정; 기본값은 FALSE
우리는 예로 사용법을 설명하다. 어떤 변화는 R 세션 동안에 잡아 두게 된다는 점에 유의해라, 혹은 그들이 glmnet.control에 연속 호출을 가지는 사용자로 인해 변경되지 않는다면.
data(QuickStartExample)
fit = glmnet(x, y)
print(fit)

##
## Call: glmnet(x = x, y = y)
##
##       Df    %Dev   Lambda
##  [1,]  0 0.00000 1.631000
##  [2,]  2 0.05528 1.486000
##  [3,]  2 0.14590 1.354000
##  [4,]  2 0.22110 1.234000
##  [5,]  2 0.28360 1.124000
##  [6,]  2 0.33540 1.024000
##  [7,]  4 0.39040 0.933200
##  [8,]  5 0.45600 0.850300
##  [9,]  5 0.51540 0.774700
## [10,]  6 0.57350 0.705900
## [11,]  6 0.62550 0.643200
## [12,]  6 0.66870 0.586100
## [13,]  6 0.70460 0.534000
## [14,]  6 0.73440 0.486600
## [15,]  7 0.76210 0.443300
## [16,]  7 0.78570 0.404000
## [17,]  7 0.80530 0.368100
## [18,]  7 0.82150 0.335400
## [19,]  7 0.83500 0.305600
## [20,]  7 0.84620 0.278400
## [21,]  7 0.85550 0.253700
## [22,]  7 0.86330 0.231200
## [23,]  8 0.87060 0.210600
## [24,]  8 0.87690 0.191900
## [25,]  8 0.88210 0.174900
## [26,]  8 0.88650 0.159300
## [27,]  8 0.89010 0.145200
## [28,]  8 0.89310 0.132300
## [29,]  8 0.89560 0.120500
## [30,]  8 0.89760 0.109800
## [31,]  9 0.89940 0.100100
## [32,]  9 0.90100 0.091170
## [33,]  9 0.90230 0.083070
## [34,]  9 0.90340 0.075690
## [35,] 10 0.90430 0.068970
## [36,] 11 0.90530 0.062840
## [37,] 11 0.90620 0.057260
## [38,] 12 0.90700 0.052170
## [39,] 15 0.90780 0.047540
## [40,] 16 0.90860 0.043310
## [41,] 16 0.90930 0.039470
## [42,] 16 0.90980 0.035960
## [43,] 17 0.91030 0.032770
## [44,] 17 0.91070 0.029850
## [45,] 18 0.91110 0.027200
## [46,] 18 0.91140 0.024790
## [47,] 19 0.91170 0.022580
## [48,] 19 0.91200 0.020580
## [49,] 19 0.91220 0.018750
## [50,] 19 0.91240 0.017080
## [51,] 19 0.91250 0.015570
## [52,] 19 0.91260 0.014180
## [53,] 19 0.91270 0.012920
## [54,] 19 0.91280 0.011780
## [55,] 19 0.91290 0.010730
## [56,] 19 0.91290 0.009776
## [57,] 19 0.91300 0.008908
## [58,] 19 0.91300 0.008116
## [59,] 19 0.91310 0.007395
## [60,] 19 0.91310 0.006738
## [61,] 19 0.91310 0.006140
## [62,] 20 0.91310 0.005594
## [63,] 20 0.91310 0.005097
## [64,] 20 0.91310 0.004644
## [65,] 20 0.91320 0.004232
## [66,] 20 0.91320 0.003856
## [67,] 20 0.91320 0.003513
우리는 경로 중지를 위한 편차에서 최소 부분 변화(minimum fractional change)를 변경할 수 있다 그리고 결과 비교한다.
glmnet.control(fdev = 0)
fit = glmnet(x, y)
print(fit)

##
## Call: glmnet(x = x, y = y)
##
##        Df    %Dev    Lambda
##   [1,]  0 0.00000 1.6310000
##   [2,]  2 0.05528 1.4860000
##   [3,]  2 0.14590 1.3540000
##   [4,]  2 0.22110 1.2340000
##   [5,]  2 0.28360 1.1240000
##   [6,]  2 0.33540 1.0240000
##   [7,]  4 0.39040 0.9332000
##   [8,]  5 0.45600 0.8503000
##   [9,]  5 0.51540 0.7747000
##  [10,]  6 0.57350 0.7059000
##  [11,]  6 0.62550 0.6432000
##  [12,]  6 0.66870 0.5861000
##  [13,]  6 0.70460 0.5340000
##  [14,]  6 0.73440 0.4866000
##  [15,]  7 0.76210 0.4433000
##  [16,]  7 0.78570 0.4040000
##  [17,]  7 0.80530 0.3681000
##  [18,]  7 0.82150 0.3354000
##  [19,]  7 0.83500 0.3056000
##  [20,]  7 0.84620 0.2784000
##  [21,]  7 0.85550 0.2537000
##  [22,]  7 0.86330 0.2312000
##  [23,]  8 0.87060 0.2106000
##  [24,]  8 0.87690 0.1919000
##  [25,]  8 0.88210 0.1749000
##  [26,]  8 0.88650 0.1593000
##  [27,]  8 0.89010 0.1452000
##  [28,]  8 0.89310 0.1323000
##  [29,]  8 0.89560 0.1205000
##  [30,]  8 0.89760 0.1098000
##  [31,]  9 0.89940 0.1001000
##  [32,]  9 0.90100 0.0911700
##  [33,]  9 0.90230 0.0830700
##  [34,]  9 0.90340 0.0756900
##  [35,] 10 0.90430 0.0689700
##  [36,] 11 0.90530 0.0628400
##  [37,] 11 0.90620 0.0572600
##  [38,] 12 0.90700 0.0521700
##  [39,] 15 0.90780 0.0475400
##  [40,] 16 0.90860 0.0433100
##  [41,] 16 0.90930 0.0394700
##  [42,] 16 0.90980 0.0359600
##  [43,] 17 0.91030 0.0327700
##  [44,] 17 0.91070 0.0298500
##  [45,] 18 0.91110 0.0272000
##  [46,] 18 0.91140 0.0247900
##  [47,] 19 0.91170 0.0225800
##  [48,] 19 0.91200 0.0205800
##  [49,] 19 0.91220 0.0187500
##  [50,] 19 0.91240 0.0170800
##  [51,] 19 0.91250 0.0155700
##  [52,] 19 0.91260 0.0141800
##  [53,] 19 0.91270 0.0129200
##  [54,] 19 0.91280 0.0117800
##  [55,] 19 0.91290 0.0107300
##  [56,] 19 0.91290 0.0097760
##  [57,] 19 0.91300 0.0089080
##  [58,] 19 0.91300 0.0081160
##  [59,] 19 0.91310 0.0073950
##  [60,] 19 0.91310 0.0067380
##  [61,] 19 0.91310 0.0061400
##  [62,] 20 0.91310 0.0055940
##  [63,] 20 0.91310 0.0050970
##  [64,] 20 0.91310 0.0046440
##  [65,] 20 0.91320 0.0042320
##  [66,] 20 0.91320 0.0038560
##  [67,] 20 0.91320 0.0035130
##  [68,] 20 0.91320 0.0032010
##  [69,] 20 0.91320 0.0029170
##  [70,] 20 0.91320 0.0026580
##  [71,] 20 0.91320 0.0024220
##  [72,] 20 0.91320 0.0022060
##  [73,] 20 0.91320 0.0020100
##  [74,] 20 0.91320 0.0018320
##  [75,] 20 0.91320 0.0016690
##  [76,] 20 0.91320 0.0015210
##  [77,] 20 0.91320 0.0013860
##  [78,] 20 0.91320 0.0012630
##  [79,] 20 0.91320 0.0011500
##  [80,] 20 0.91320 0.0010480
##  [81,] 20 0.91320 0.0009551
##  [82,] 20 0.91320 0.0008703
##  [83,] 20 0.91320 0.0007930
##  [84,] 20 0.91320 0.0007225
##  [85,] 20 0.91320 0.0006583
##  [86,] 20 0.91320 0.0005999
##  [87,] 20 0.91320 0.0005466
##  [88,] 20 0.91320 0.0004980
##  [89,] 20 0.91320 0.0004538
##  [90,] 20 0.91320 0.0004135
##  [91,] 20 0.91320 0.0003767
##  [92,] 20 0.91320 0.0003433
##  [93,] 20 0.91320 0.0003128
##  [94,] 20 0.91320 0.0002850
##  [95,] 20 0.91320 0.0002597
##  [96,] 20 0.91320 0.0002366
##  [97,] 20 0.91320 0.0002156
##  [98,] 20 0.91320 0.0001964
##  [99,] 20 0.91320 0.0001790
## [100,] 20 0.91320 0.0001631
우리는 경로를 따라 모두 연속하도록 fdev = 0 로 설정한다, 많은 변경이 없을 때 조차. 연속 길이는 100이 된다, nlambda의 기본값.
사용자는 또한 기본 설정을 재설정할 수 있다.
glmnet.control(factory = TRUE)
현재 설정은 다음으로 얻어진다.
glmnet.control()

## $fdev
## [1] 1e-05
##
## $eps
## [1] 1e-06
##
## $big
## [1] 9.9e+35
##
## $mnlam
## [1] 5
##
## $devmax
## [1] 0.999
##
## $pmin
## [1] 1e-09
##
## $exmx
## [1] 250
##
## $prec
## [1] 1e-10
##
## $mxit
## [1] 100

부록 2: 다른 패키지와 비교 (Appendix 2: Comparison with Other Packages)

어떤 사람들은 단일 λ에서 Lasso 또는 elastic-net 문제를 풀기 위해 glmnet을 사용하기를 원한다. 우리는 다른 패키지(CVX 같은)와 glmnet으로 얻은 해결법을 여기서 비교한다, 그리고 또한 이런 상황에서 변수 설정에 대한 설명과 같이.
Warning: 그런 문제는 glmnet으로 해결할 수 있지만, 그것은 추천되지 않는다 그리고 패키지의 정신이 아니다. glmnet은 warm starts 같은 다양한 기술을 가지고 Lasso 또는 elastic-net 문제에서 완전한 해결 경로를 적합한다, warm starts는 로지스틱 회귀 같은 비선형 모델에서 필요하다. 그러한 이점은 사라지게 될 것이다 만약 λ 연속이 단지 하나의 값으로 제한된다면, 그리고 수렴이 보장되지 않는다.
그럼에도 불구하고, 우리는 비교의 목적에서 따라오는 선형 모델의 전형적인 예제를 가지고 설명한다. X, Y, 그리고 λ > 0 이 주어지고, 우리는 그러한 β를 찾기을 원한다.
경우, 말하면, λ0 = 8.
우리는 먼저 glmnet을 사용하여 해결한다. 목적 함수에 교차점(intercept) 조건이 없음에 주목하라, 그리고 X의 열은 표준화될 필요가 없다. 해당하는 변수는 그것을 옳바르게 작동하기 위한 집합이 되어야 한다. 게다가, 기본으로 2차 조건(quadratic term) 전에 1/(2n) 펙터이다, 우리는 옳바르게 λ를 조정할 필요가 있다. 비교 목적으로, thresh 옵션은 1e-20로 지정한다. 어쨌든, 이것은 많은 연습 응용에 필요하지 않다.
fit = glmnet(x, y, intercept = F, standardize = F, lambda = 8/(2*dim(x)[1]), 
             thresh = 1e-20)
우리는 그 다음 계수를 추출한다 (없는 교차점(intercept)을 가짐).
beta_glmnet = coef(fit)[-1,])
주의: 우리는 없는 교차점을 지정하지만, 하나가 놓여 있다, 그러나 그것은 0 이다.
여기서 처럼 선형 모델에서 이 접근은 작동된다 왜냐하면 우리는 제곱 에러 손실을 사용했다, 그리고 좌표 강하는 수렴을 보장한다. 그러나 많은 비선형 군에서, 그것은 아마 실패할 것이다. 이유는 우리가 단계 길이 최적화를 사용하지 않았다, 그래서 우리를 손실 함수 이차 영역에 놓기 위해 매우 좋은 warm starts에 의존한다.
대안으로, 이 작업을 수행하기 위해 더 안정적이고 그리고 강하게 추천하는 방법은 2 단계에 있다. 먼저 특별한 람다 없이 전체 lasso 또는 elastic-net 경로를 적합한다, 그것의 선택을 그 자신의 연속으로 놓아라. 그러면 coef 또는 predict를 호출하게 만든다 (exact = TRUE 옵션을 사용) 그리고 해당하는 계수를 추출하기 위해 요구되는 λ0를 제공하라. (만약 λ0가 glmnet에서 생성된 λ 연속에 없다면, 경로는 새로운 값(s)를 가지고 본래의 연속을 인수로 하는 새로운 λ 연속으로 재적합될 것이다).
fit = glmnet(x, y, intercept = F, standardize = F, thresh = 1e-20)
beta_glmnet = coef(fit, s = 8/(2*dim(x)[1]), exact = T)[-1,]
우리는 지금 CVX를 사용한다, a general convex optimization solver, 이 특별한 Lasso 문제를 해결하기 위함. 사용자는 CVXfromR 패키지를 사용하여 R에서 CVX를 또한 호출할 수 있다 그리고 다음의 문제를 해결한다.
library(CVXfromR)
setup.dir = "change/this/to/your/cvx/directory"
n = dim(x)[1]; p = dim(x)[2]
cvxcode = paste("variables beta(p)",
                "minimize(square_pos(norm(y - x * beta, 2)) + lambda * norm(beta, 1))",
                sep = ";")
Lasso = CallCVX(cvxcode, const.var = list(p = p, x = x, y = y, lambda = 8), 
                opt.var.names = "beta", setup.beta_CVX = Lasso$beta)
여기서 편리하게도, 결과는 CVXResult.RData에 저장되었다, 그리고 우리는 단순하게 결과를 적재할 수 있다.
data(CVXResults)
게다가, 우리는 같은 문제를 해결하기 위해 lars를 사용한다.
library(lars)

fit_lars = lars(x, y, type = "lasso", intercept = F, normalize = F)
beta_lars = predict(fit_lars, s = 8/2, type = "coefficients", 
                    mode = "lambda")$coefficients
결과는 6자리수까지 나오는 목록이다 (수렴 임계점 때문) .
cmp = round(cbind(beta_glmnet, beta_lars, beta_CVX), digits = 6)
colnames(cmp) = c("beta_glmnet", "beta_lars", "beta_CVX")
cmp

##     beta_glmnet beta_lars  beta_CVX
## V1     1.389118  1.389118  1.389118
## V2     0.007991  0.007991  0.007991
## V3     0.731234  0.731234  0.731234
## V4     0.031119  0.031119  0.031119
## V5    -0.866793 -0.866793 -0.866793
## V6     0.564867  0.564867  0.564867
## V7     0.069678  0.069678  0.069678
## V8     0.358346  0.358346  0.358346
## V9     0.000000  0.000000  0.000000
## V10    0.070565  0.070565  0.070565
## V11    0.173464  0.173464  0.173464
## V12   -0.027472 -0.027472 -0.027472
## V13   -0.017960 -0.017960 -0.017960
## V14   -1.138053 -1.138053 -1.138053
## V15   -0.070990 -0.070990 -0.070990
## V16    0.000000  0.000000  0.000000
## V17    0.000000  0.000000  0.000000
## V18    0.000000  0.000000  0.000000
## V19    0.000000  0.000000  0.000000
## V20   -1.097528 -1.097528 -1.097528
이전   다음

댓글 없음:

댓글 쓰기