Линейная регрессия с ограничениями на коэффициенты

Я пытаюсь выполнить линейную регрессию для такой модели:

Y = aX1 + bX2 + c

и Y ~ X1 + X2

Предположим, у меня есть следующий вектор ответа:

set.seed(1)
Y <- runif(100, -1.0, 1.0)

и следующая матрица предикторов:

X1 <- runif(100, 0.4, 1.0)
X2 <- sample(rep(0:1,each=50))
X <- cbind(X1, X2)

Я хочу использовать следующие ограничения на коэффициенты:

a + c >= 0  
c >= 0

поэтому нет ограничений на b.

Я знаю, что пакет glmc можно использовать для применения ограничений, но я не смог определить как применить его для моих ограничений. Я также знаю, что контр.sum можно использовать так, чтобы все коэффициенты суммировались до 0, например, но это не то, что я хочу сделать. решать.QP () кажется другой возможностью, где установка meq=0 можно использовать так, чтобы все коэффициенты >=0 (опять же, не моя цель).

Примечание: решение должно иметь возможность обрабатывать значения NA в векторе ответа Y, например:

Y <- runif(100, -1.0, 1.0)
Y[c(2,5,17,56,37,56,34,78)] <- NA

1 ответов


solve.QP могут быть переданы произвольные линейные ограничения, поэтому его, безусловно, можно использовать для моделирования ваших ограничений a+c >= 0 и c >= 0.

во-первых, мы можем добавить столбец 1 к X чтобы захватить термин перехвата, а затем мы можем воспроизвести стандартную линейную регрессию с solve.QP:

X2 <- cbind(X, 1)
library(quadprog)
solve.QP(t(X2) %*% X2, t(Y) %*% X2, matrix(0, 3, 0), c())$solution
# [1]  0.08614041  0.21433372 -0.13267403

С данными выборки из вопроса ни одно ограничение не выполняется с использованием стандартной линейной регрессии.

путем изменения как Amat и bvec параметры, мы можем добавить наши два ограничения:

solve.QP(t(X2) %*% X2, t(Y) %*% X2, cbind(c(1, 0, 1), c(0, 0, 1)), c(0, 0))$solution
# [1] 0.0000000 0.1422207 0.0000000

С учетом этих ограничений квадраты остатков минимизируются путем установки коэффициентов a и c равными 0.

вы можете обрабатывать отсутствующие значения в Y или X2 как lm функция делает, удаляя оскорбительные наблюдения. Вы можете сделать что-то вроде следующего шага предварительной обработки:

has.missing <- rowSums(is.na(cbind(Y, X2))) > 0
Y <- Y[!has.missing]
X2 <- X2[!has.missing,]