Обобщение этого рецепта для GLM действительно не сложно, поскольку GLM обычно подходят с использованием итеративно переоцененных наименьших квадратов . Следовательно, в каждой итерации можно заменить обычный шаг взвешенных наименьших квадратов на шаг взвешенных наименьших квадратов, наложенный на ребро, чтобы получить GLM, наложенный на ребро. Фактически, в сочетании с адаптивными штрафами гребня этот рецепт используется, чтобы соответствовать штрафованным L0 GLM (или лучшему подмножеству, то есть GLM, где штрафуется общее количество ненулевых коэффициентов). Это было реализовано, например, в пакете l0ara , см. Этот документ и этот для деталей.
Стоит также отметить, что самый быстрый способ решения правильной регрессии гребня в замкнутой форме использует
lmridge_solve = function (X, y, lambda, intercept = TRUE) {
if (intercept) {
lambdas = c(0, rep(lambda, ncol(X)))
X = cbind(1, X)
} else { lambdas = rep(lambda, ncol(X)) }
solve(crossprod(X) + diag(lambdas), crossprod(X, y))[, 1]
}
для случая, где n>=p
или используя
lmridge_solve_largep = function (X, Y, lambda) (t(X) %*% solve(tcrossprod(X)+lambda*diag(nrow(X)), Y))[,1]
когда p>n
и для модели без перехвата.
Это быстрее, чем использование рецепта увеличения строки , т.е.
lmridge_rbind = function (X, y, lambda, intercept = TRUE) {
if (intercept) {
lambdas = c(0, rep(lambda, ncol(X)))
X = cbind(1, X)
} else { lambdas = rep(lambda, ncol(X)) }
qr.solve(rbind(X, diag(sqrt(lambdas))), c(y, rep(0, ncol(X))))
}
Если вам понадобятся ограничения неотрицательности для ваших установленных коэффициентов, тогда вы можете просто сделать
library(nnls)
nnlmridge_solve = function (X, y, lambda, intercept = TRUE) {
if (intercept) {
lambdas = c(0, rep(lambda, ncol(X)))
X = cbind(1, X)
} else { lambdas = rep(lambda, ncol(X)) }
nnls(A=crossprod(X)+diag(lambdas), b=crossprod(X,Y))$x
}
что затем дает чуть более точный результат, чем
nnlmridge_rbind = function (X, y, lambda, intercept = TRUE) {
if (intercept) {
lambdas = c(0, rep(lambda, ncol(X)))
X = cbind(1, X)
} else { lambdas = rep(lambda, ncol(X)) }
nnls(A=rbind(X,diag(sqrt(lambdas))), b=c(Y,rep(0,ncol(X))))$x
}
(и, строго говоря, только решение nnls(A=crossprod(X)+diag(lambdas), b=crossprod(X,Y))$x
является правильным).
Я еще не выяснил, как можно оптимизировать кейс с ограничением неотрицательности p > n
- дайте мне знать, если кто-нибудь узнает, как это сделать ... [ lmridge_nnls_largep = function (X, Y, lambda) t(X) %*% nnls(A=tcrossprod(X)+lambda*diag(nrow(X)), b=Y)$x
не работает]