R: заставить коэффициенты регрессии сложить до 1 - PullRequest
4 голосов
/ 18 октября 2019

Я пытаюсь запустить простую регрессию OLS с ограничением, что сумма коэффициентов двух переменных составляет до 1.

Я хочу:

Y = α + β1 * x1 + β2 * x2 + β3 * x3,
where β1 + β2 = 1

У меня естьнашел, как сделать соотношение между коэффициентами, как:

β1 = 2* β2

Но я не нашел, как сделать ограничения, как:

β1 = 1 - β2

Как бы я сделал это в этом простом примере?

data <- data.frame(
  A = c(1,2,3,4),
  B = c(3,2,2,3),
  C = c(3,3,2,3),
  D = c(5,3,3,4)
)

lm(formula = 'D ~ A + B + C', data = data)

Спасибо!

Ответы [ 2 ]

5 голосов
/ 18 октября 2019

β1 + β2 = 1

Чтобы иметь β1 + β2 = 1 модель, которую вы должны установить, является

fit <- lm(Y ~  offset(x1) + I(x2 - x1) + x3, data = df)

То есть

Y = α + x1 + β2 * (x2 - x1) + β3 * x3

после замены β1 = 1 - β2 ;x_new = x2 - x1 и коэффициент для x1 равен 1.


β1 + β2 + β3 = 1

fit <- lm(Y ~  offset(x1) + I(x2 - x1) + I(x3 - x1), data = df)

Y = α+ x1 + β2 * (x2 - x1) + β3 * (x3 - x1)

после замены β1 = 1 - β2 - β3


β1 + β2 + β3 +... = 1

Я думаю, что картина ясна ... вам нужно только вычесть одну переменную x1 из остальных переменных (x2, x3, ...) и иметь коэффициент этой переменной, x1, равный 1.


Пример β1 + β2 = 1

# Data
df <- iris[, 1:4]
colnames(df) <- c("Y", paste0("x", 1:3, collaapse=""))

# β1 + β2 = 1
fit <- lm(Y ~  offset(x1) + I(x2 - x1) + x3, data = df)
coef_2 <- coef(fit)
beta_1 <- 1 - coef_2[2]
beta_2 <- coef_2[2]
1 голос
/ 18 октября 2019

1) CVXR Мы можем вычислить коэффициенты, используя CVXR напрямую, указав цель и ограничение. Мы предполагаем, что D является ответом, коэффициенты A и B должны быть равны 1, b [1] - это точка пересечения, а b [2], b [3] и b [4] - коэффициенты A, B и C.

library(CVXR)

b <- Variable(4)
X <- cbind(1, as.matrix(data[-4]))
obj <- Minimize(sum((data$D - X %*% b)^2))
constraints <- list(b[2] + b[3] == 1)
problem <- Problem(obj, constraints)
soln <- solve(problem)

bval <- soln$getValue(b)
bval
##            [,1]
## [1,]  1.6428605
## [2,] -0.3571428
## [3,]  1.3571428
## [4,] -0.1428588

Цель - это остаточная сумма квадратов, которая равна:

soln$value
## [1] 0.07142857

2) pracma Мы также можем использовать пакет pracma для вычислениякоэффициенты. Мы указываем X-матрицу, вектор ответа, матрицу ограничений (в этом случае вектор, заданный в качестве третьего аргумента, рассматривается как матрица из одной строки) и правую часть ограничения.

library(pracma)

lsqlincon(X, data$D, Aeq = c(0, 1, 1, 0), beq = 1) # X is from above
## [1]  1.6428571 -0.3571429  1.3571429 -0.1428571

3) limSolve Этот пакет также может решать для коэффициентов регрессионных задач с ограничениями. Аргументы такие же, как и в (2).

library(limSolve)
lsei(X, data$D, c(0, 1, 1, 0), 1)

, что дает:

$X
                    A          B          C 
 1.6428571 -0.3571429  1.3571429 -0.1428571 

$residualNorm
[1] 0

$solutionNorm
[1] 0.07142857

$IsError
[1] FALSE

$type
[1] "lsei"

Проверка

Мы можем проверить выше, используя lmподход в другом ответе:

lm(D ~ I(A-B) + C + offset(B), data)

, дающий:

Call:
lm(formula = D ~ I(A - B) + C + offset(B), data = data)

Coefficients:
(Intercept)     I(A - B)            C  
     1.6429      -0.3571      -0.1429  

Коэффициент I(A-B) равен коэффициенту A в исходной формулировке, и один минус - это коэффициентC. Мы видим, что все подходы приводят к одинаковым коэффициентам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...