Линейная регрессия с ограничениями на коэффициенты
Я пытаюсь выполнить линейную регрессию для такой модели:
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,]