Il n'est en effet pas difficile de généraliser cette recette aux GLM, car les GLM sont généralement adaptés à l'aide des moindres carrés itérativement repondérés . Par conséquent, à l'intérieur de chaque itération, on peut substituer l'étape des moindres carrés pondérés régulière avec une étape des moindres carrés pondérés pénalisée par une crête pour obtenir un GLM pénalisé par une crête. En fait, en combinaison avec des pénalités de crête adaptatives, cette recette est utilisée pour ajuster les GLM pénalisés L0 (c'est-à-dire le meilleur sous-ensemble, c'est-à-dire les GLM où le nombre total de coefficients non nuls est pénalisé). Ceci a été implémenté par exemple dans le paquet l0ara , voir cet article et celui-ci pour plus de détails.
Il convient également de noter que le moyen le plus rapide de résoudre une régression de crête régulière utilise
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]
}
dans le cas où n>=p
, ou en utilisant
lmridge_solve_largep = function (X, Y, lambda) (t(X) %*% solve(tcrossprod(X)+lambda*diag(nrow(X)), Y))[,1]
quand p>n
et pour un modèle sans interception.
C'est plus rapide que d'utiliser la recette d'augmentation de ligne , c'est-à-dire de faire
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))))
}
S'il vous arrivait d'avoir besoin de contraintes de non négativité sur vos coefficients ajustés, alors vous pouvez simplement faire
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
}
ce qui donne ensuite un résultat légèrement plus précis que
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
}
(et à proprement parler seule la solution nnls(A=crossprod(X)+diag(lambdas), b=crossprod(X,Y))$x
est alors la bonne).
Je n'ai pas encore compris comment le cas contraint à la non-négativité pourrait être encore optimisé pour le p > n
cas - faites-moi savoir si quelqu'un pourrait savoir comment faire cela ... [ lmridge_nnls_largep = function (X, Y, lambda) t(X) %*% nnls(A=tcrossprod(X)+lambda*diag(nrow(X)), b=Y)$x
ne fonctionne pas]