음이 아닌 능선 회귀를 수행하는 방법?


10

음이 아닌 능선 회귀를 수행하는 방법? 음수가 아닌 올가미는에서 사용할 수 scikit-learn있지만, 능선의 경우 베타의 음수가 아닌 것을 시행 할 수 없으며 실제로 음의 계수를 얻습니다. 이것이 왜 그런지 아는 사람이 있습니까?

또한 규칙적인 최소 제곱으로 릿지를 구현할 수 있습니까? 이것을 다른 질문으로 옮겼습니다. OLS 회귀 측면에서 능선 회귀를 구현할 수 있습니까?


1
여기에는 매우 직교하는 두 가지 질문이 있습니다. "최소 제곱의 관점에서 능선을 구현할 수 있습니까?"를 별도의 질문으로 분류하는 것이 좋습니다.
Matthew Drury

답변:


8

" 이것이 왜 그런지 아는가? "에 대한 다소 반 기후적인 대답 은, 음이 아닌 능선 회귀 루틴을 구현할만큼 아무도 신경 쓰지 않는다는 것입니다. 주된 이유 중 하나는 사람들이 이미 음이 아닌 탄성 그물 루틴을 구현하기 시작했기 때문입니다 (예 : herehere ). 탄성 그물은 릿지 회귀를 특수한 경우로 포함합니다 (하나는 LASSO 부품의 가중치가 0으로 설정 됨). 이 작품들은 비교적 새롭기 때문에 아직 scikit-learn 또는 유사한 일반적인 사용 패키지에 포함되지 않았습니다. 이 논문의 저자에게 코드를 문의 할 수 있습니다.

편집하다:

@amoeba와 의견에 대해 토론했듯이 실제 구현은 상대적으로 간단합니다. 다음과 같은 회귀 문제가 있다고 가정하십시오.

y=2x1x2+ϵ,ϵN(0,0.22)

어디 x1x2 다음과 같은 표준 법선입니다. xpN(0,1). 표준화 된 예측 변수를 사용하므로 나중에 정규화 할 필요가 없습니다. 단순화를 위해 인터셉트도 포함하지 않았습니다. 표준 선형 회귀를 사용하여이 회귀 문제를 즉시 해결할 수 있습니다. 따라서 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 가이 게시물 을 읽습니다. 우리는 이 절차를 정확히 구현할 입니다. 요컨대, 우리는 원래의 디자인 매트릭스를 보강 할 것입니다XλIp 대각 행렬과 응답 벡터 yp제로. 이런 식으로 우리는 원래 능선 회귀 문제를 다시 표현할 수있을 것입니다(XTX+λI)1XTy 같이 (X¯TX¯)1X¯Ty¯ 어디 ¯증강 버전을 상징합니다. 이 노트 에서 슬라이드 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

작동합니다. 좋습니다, 그래서 우리는 능선 회귀 부분을 얻었습니다. 우리는 다른 방법으로 해결할 수 있습니다. 잔차 제곱합이 비용 함수 인 최적화 문제로 공식화 한 다음에 최적화 할 수 있습니다.minβ||y¯X¯β||22. 물론 우리는 그렇게 할 수 있습니다.

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

예상대로 다시 작동합니다. 이제 우리는 원합니다 : 여기서 입니다. 이는 단순히 동일한 최적화 문제이지만 솔루션이 음이 아니도록 제한됩니다.minβ||y¯X¯β||22β0

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

이는 원래의 음이 아닌 능선 회귀 작업을 간단한 제약 최적화 문제로 재구성하여 해결할 수 있음을 보여줍니다. 몇 가지주의 사항 :

  1. 정규화 된 예측 변수를 (실제로) 사용했습니다. 정규화를 직접 설명해야합니다.
  2. 절편 의 비정규 화에 대해서도 마찬가지입니다 .
  3. 내가 사용 optimL-BFGS-B의 인수를. 바운드를 허용하는 가장 바닐라 R 솔버입니다. 수십 가지의 더 나은 솔버를 찾을 것이라고 확신합니다.
  4. 일반적으로 선형 최소 제곱 문제는 2 차 최적화 작업 으로 간주됩니다 . 이것은이 게시물에 대한 과잉이지만 필요한 경우 더 나은 속도를 얻을 수 있습니다.
  5. 주석에서 언급했듯이 능선 회귀를 보강 선형 회귀 부분으로 건너 뛰고 능선 비용 함수를 최적화 문제로 직접 인코딩 할 수 있습니다. 이것은 훨씬 간단하고이 게시물은 상당히 작습니다. 논쟁을 위해서 나는이 두 번째 해결책도 덧붙인다.
  6. 나는 파이썬에서 완전히 대화가 아니지만 본질적으로 NumPy의 linalg.solve 및 SciPy의 최적화 함수 를 사용 하여이 작업을 복제 할 수 있습니다 .
  7. 하이퍼 파라미터 등 을 선택하려면 어떤 경우에도 일반적인 CV 단계를 수행하면됩니다. 아무것도 변하지 않습니다.λ

포인트 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

1
이것은 다소 오해의 소지가 있습니다. 음수가 아닌 능선 회귀는 구현하기가 쉽지 않습니다. 확장 된 데이터에 대한 일반적인 회귀로 능선 회귀를 다시 작성한 다음 ( stats.stackexchange.com/questions/203687에 대한 주석 참조 ) 음이 아닌 회귀 루틴을 사용할 수 있습니다.
amoeba

나는 그것을 구현하는 것이 간단하다는 데 동의합니다 (+1). (저는 다른 스레드에 대한 귀하와 Glen의 의견을 앞섰습니다). 문제는 어려운 것이 아니라 구현되지 않은 이유입니다. 그 문제에 대해, 나는이 NNRR 작업을 직접 공식화하는 것이 먼저 확장 데이터 회귀로 공식화 한 다음 쿼드를 사용하는 최적화 문제가 훨씬 간단하다고 생각합니다. 음식물. 이 회귀를 해결하기위한 최적화. 나는 구현 부분에서 모험을 할 것이기 때문에 대답하지 않았다.
usεr11852

아니면 그냥 스탠로 작성하십시오.
Sycorax는

아 좋아 나는 Q가 음이 아닌 능선을 수행하는 방법을 묻는 것 (그리고 그것이 통과되지 않은 이유에 대해서만 묻는 것)을 이해했다. 나는 이것을 제목에 넣도록 편집했다. 어쨌든, 그것을하는 방법 은 더 흥미로운 질문 인 것 같습니다. 음이 아닌 능선을 구현하는 방법에 대한 설명으로 답변을 업데이트 할 수 있다면 향후 독자에게 매우 유용 할 것입니다 (그리고 기꺼이 찬성 :).
amoeba

1
쿨, 나중에 할게요 (새 타이틀은 눈치 채지 못했습니다. 죄송합니다). 아마도 OLS / 의사 관찰 측면에서 구현을 제공 할 것이므로 다른 질문에도 대답 할 것입니다.
usεr11852

4

탄성 그물을 구현하는 R 패키지 glmnet이므로 올가미와 릿지가 가능합니다. 매개 변수 lower.limits및을 사용하면 upper.limits각 가중치에 대해 최소 또는 최대 값을 개별적으로 설정할 수 있으므로 하한을 0으로 설정하면 음이 아닌 탄성 망 (lasso / ridge)을 수행합니다.

파이썬 래퍼도 있습니다 https://pypi.python.org/pypi/glmnet/2.0.0


2

우리가 해결하려고 노력하고 있음을 상기하십시오.

minimizexAxy22+λx22s.t. x>0

다음과 같습니다.

minimizexAxy22+λxIxs.t. x>0

더 많은 대수와 함께 :

minimizexxT(ATA+λI)x+(2ATy)Txs.t. x>0

의사 파이썬의 해결책은 간단하게 수행하는 것입니다.

Q = A'A + lambda*I
c = - A'y
x,_ = scipy.optimize.nnls(Q,c)

참조 : 형식의 정규화 사용하여 음이 아닌 최소 제곱을 어떻게 스파 스 합니까?KxRkx

좀 더 일반적인 답변입니다.


c =-A'y 라인을 읽지 않아야합니까 c = A'y? 솔루션이 scipy.optimize.nnls (newMatX, newVecY)와 약간 다르다는 점에 유의해야하지만, newMatX는 대각선을 따라 sqrt (lambda)로 대각선 행렬로 보강 된 X 행이고 NewVecY는 Y입니다. nvar 0으로 확장되었습니다. 나는 당신이 언급 한 해결책이 올바른 것이라고 생각합니다.
Tom Wenseleers
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.