음이 아닌 능선 회귀를 수행하는 방법? 실제로 음의 계수를 얻습니다. 이것이 왜

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

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



답변

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

편집하다:

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

y=2x1−x2+ϵ,ϵ∼N(0,0.22)

어디

x1

x2

다음과 같은 표준 법선입니다.

xp∼N(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

대각 행렬과 응답 벡터

y

p

제로. 이런 식으로 우리는 원래 능선 회귀 문제를 다시 표현할 수있을 것입니다

(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

답변

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

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


답변

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

minimizex‖Ax−y‖22+λ‖x‖22s.t. x>0

다음과 같습니다.

minimizex‖Ax−y‖22+λx⊤Ixs.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)

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

K

x⊤Rkx

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