음이 아닌 능선 회귀를 수행하는 방법? 음수가 아닌 올가미는에서 사용할 수 scikit-learn
있지만, 능선의 경우 베타의 음수가 아닌 것을 시행 할 수 없으며 실제로 음의 계수를 얻습니다. 이것이 왜 그런지 아는 사람이 있습니까?
또한 규칙적인 최소 제곱으로 릿지를 구현할 수 있습니까? 이것을 다른 질문으로 옮겼습니다. OLS 회귀 측면에서 능선 회귀를 구현할 수 있습니까?
음이 아닌 능선 회귀를 수행하는 방법? 음수가 아닌 올가미는에서 사용할 수 scikit-learn
있지만, 능선의 경우 베타의 음수가 아닌 것을 시행 할 수 없으며 실제로 음의 계수를 얻습니다. 이것이 왜 그런지 아는 사람이 있습니까?
또한 규칙적인 최소 제곱으로 릿지를 구현할 수 있습니까? 이것을 다른 질문으로 옮겼습니다. OLS 회귀 측면에서 능선 회귀를 구현할 수 있습니까?
답변:
" 이것이 왜 그런지 아는가? "에 대한 다소 반 기후적인 대답 은, 음이 아닌 능선 회귀 루틴을 구현할만큼 아무도 신경 쓰지 않는다는 것입니다. 주된 이유 중 하나는 사람들이 이미 음이 아닌 탄성 그물 루틴을 구현하기 시작했기 때문입니다 (예 : here 및 here ). 탄성 그물은 릿지 회귀를 특수한 경우로 포함합니다 (하나는 LASSO 부품의 가중치가 0으로 설정 됨). 이 작품들은 비교적 새롭기 때문에 아직 scikit-learn 또는 유사한 일반적인 사용 패키지에 포함되지 않았습니다. 이 논문의 저자에게 코드를 문의 할 수 있습니다.
편집하다:
@amoeba와 의견에 대해 토론했듯이 실제 구현은 상대적으로 간단합니다. 다음과 같은 회귀 문제가 있다고 가정하십시오.
어디 과 다음과 같은 표준 법선입니다. . 표준화 된 예측 변수를 사용하므로 나중에 정규화 할 필요가 없습니다. 단순화를 위해 인터셉트도 포함하지 않았습니다. 표준 선형 회귀를 사용하여이 회귀 문제를 즉시 해결할 수 있습니다. 따라서 R에서는 다음과 같아야합니다.
rm(list = ls());
library(MASS);
set.seed(123);
N = 1e6;
x1 = rnorm(N)
x2 = rnorm(N)
y = 2 * x1 - 1 * x2 + rnorm(N,sd = 0.2)
simpleLR = lm(y ~ -1 + x1 + x2 )
matrixX = model.matrix(simpleLR); # This is close to standardised
vectorY = y
all.equal(coef(simpleLR), qr.solve(matrixX, vectorY), tolerance = 1e-7) # TRUE
마지막 줄에 주목하십시오. 거의 모든 선형 회귀 루틴은 QR 분해를 사용하여 추정합니다.. 능선 회귀 문제에 대해서도 동일하게 사용하고 싶습니다. 이 시점 에서 @whuber 가이 게시물 을 읽습니다. 우리는 이 절차를 정확히 구현할 것 입니다. 요컨대, 우리는 원래의 디자인 매트릭스를 보강 할 것입니다 와 대각 행렬과 응답 벡터 와 제로. 이런 식으로 우리는 원래 능선 회귀 문제를 다시 표현할 수있을 것입니다 같이 어디 증강 버전을 상징합니다. 이 노트 에서 슬라이드 18-19 도 완전성을 확인하십시오 . 나는 매우 간단하다는 것을 알았습니다. R에서 우리는 다음과 같이 할 것입니다 :
myLambda = 100;
simpleRR = lm.ridge(y ~ -1 + x1 + x2, lambda = myLambda)
newVecY = c(vectorY, rep(0, 2))
newMatX = rbind(matrixX, sqrt(myLambda) * diag(2))
all.equal(coef(simpleRR), qr.solve(newMatX, newVecY), tolerance = 1e-7) # TRUE
작동합니다. 좋습니다, 그래서 우리는 능선 회귀 부분을 얻었습니다. 우리는 다른 방법으로 해결할 수 있습니다. 잔차 제곱합이 비용 함수 인 최적화 문제로 공식화 한 다음에 최적화 할 수 있습니다.. 물론 우리는 그렇게 할 수 있습니다.
myRSS <- function(X,y,b){ return( sum( (y - X%*%b)^2 ) ) }
bfgsOptim = optim(myRSS, par = c(1,1), X = newMatX, y= newVecY,
method = 'L-BFGS-B')
all.equal(coef(simpleRR), bfgsOptim$par, check.attributes = FALSE,
tolerance = 1e-7) # TRUE
예상대로 다시 작동합니다. 이제 우리는 원합니다 : 여기서 입니다. 이는 단순히 동일한 최적화 문제이지만 솔루션이 음이 아니도록 제한됩니다.
bfgsOptimConst = optim(myRSS, par = c(1,1), X=newMatX, y= newVecY,
method = 'L-BFGS-B', lower = c(0,0))
all(bfgsOptimConst$par >=0) # TRUE
(bfgsOptimConst$par) # 2.000504 0.000000
이는 원래의 음이 아닌 능선 회귀 작업을 간단한 제약 최적화 문제로 재구성하여 해결할 수 있음을 보여줍니다. 몇 가지주의 사항 :
optim
의 L-BFGS-B의 인수를. 바운드를 허용하는 가장 바닐라 R 솔버입니다. 수십 가지의 더 나은 솔버를 찾을 것이라고 확신합니다.포인트 5 코드 :
myRidgeRSS <- function(X,y,b, lambda){
return( sum( (y - X%*%b)^2 ) + lambda * sum(b^2) )
}
bfgsOptimConst2 = optim(myRidgeRSS, par = c(1,1), X = matrixX, y = vectorY,
method = 'L-BFGS-B', lower = c(0,0), lambda = myLambda)
all(bfgsOptimConst2$par >0) # TRUE
(bfgsOptimConst2$par) # 2.000504 0.000000
탄성 그물을 구현하는 R 패키지 glmnet이므로 올가미와 릿지가 가능합니다. 매개 변수 lower.limits
및을 사용하면 upper.limits
각 가중치에 대해 최소 또는 최대 값을 개별적으로 설정할 수 있으므로 하한을 0으로 설정하면 음이 아닌 탄성 망 (lasso / ridge)을 수행합니다.
파이썬 래퍼도 있습니다 https://pypi.python.org/pypi/glmnet/2.0.0
우리가 해결하려고 노력하고 있음을 상기하십시오.
다음과 같습니다.
더 많은 대수와 함께 :
의사 파이썬의 해결책은 간단하게 수행하는 것입니다.
Q = A'A + lambda*I
c = - A'y
x,_ = scipy.optimize.nnls(Q,c)
참조 : 형식의 정규화 사용하여 음이 아닌 최소 제곱을 어떻게 스파 스 합니까?
좀 더 일반적인 답변입니다.