Erreur lors de l'exécution de glmnet en multinomial [fermé]

9

Le problème mentionné dans cette question est résolu dans la version 1.7.3 du package R glmnet.

J'ai des problèmes avec glmnet avec family = multinomial et je me demandais si j'ai rencontré quelque chose de similaire ou si je pourrais être en mesure de me dire ce que je fais mal.

Lorsque je mets mes propres données fictives, l'erreur "Erreur d'application (nz, 1, médiane): dim (X) doit avoir une longueur positive" est signalée lorsque je cours cv.glmnet, ce qui en plus de dire "cela n'a pas fonctionné" n'était pas extrêmement informatif pour moi.

y=rep(1:3,20) #=> 60 element vector
set.seed(1011)
x=matrix(y+rnorm(20*3*10,sd=0.4),nrow=60) # 60*10 element matrix
glm = glmnet(x,y,family="multinomial")   #=> returns without error
crossval = cv.glmnet(x,y,family="multinomial")   #=> Error in apply(nz, 1, median) : dim(X) must have a positive length
crossval = cv.glmnet(x,y,family="multinomial",type.measure="class")   #=> Error in apply(nz, 1, median) : dim(X) must have a positive length
crossval = cv.glmnet(x,y,family="multinomial",type.measure="mae")   #=> Error in apply(nz, 1, median) : dim(X) must have a positive length
cvglm = cv.glmnet(x,y,family="multinomial",lambda=2)   #=> Error in apply(nz, 1, median) : dim(X) must have a positive length

Voici une description visuelle du problème que j'essayais d'obtenir de résoudre glmnet, si cela aide:

my_colours = c('red','green','blue')
plot(x[,1],x[,2],col=my_colours[y])

Je suis en mesure d'exécuter l'exemple de code à partir des documents du package, ce qui me fait penser que je ne comprends pas bien quelque chose ou qu'il y a un bogue dans glmnet.

library(glmnet)
set.seed(10101)
n=1000;p=30
x=matrix(rnorm(n*p),n,p) #=> 1000*30 element matrix
beta3=matrix(rnorm(30),10,3)
beta3=rbind(beta3,matrix(0,p-10,3))
f3=x%*% beta3
p3=exp(f3)
p3=p3/apply(p3,1,sum)
g3=rmult(p3) #=> 1000 element vector
set.seed(10101)
cvfit=cv.glmnet(x,g3,family="multinomial")

Ceci utilise R version 2.13.1 (2011-07-08) et glmnet 1.7.1, bien que je puisse générer le même problème sur R 2.14.1. Des idées des gens?

BenJWoodcroft
la source

Réponses:

11

Il y a un bug subtil.

Ce qui se passe est le suivant: dans votre ensemble de données artificielles, les moyennes à trois groupes sont sur une ligne, et avec l'écart-type relativement petit utilisé, les trois groupes deviennent linéairement séparables dans votre espace à 10 dimensions. Par conséquent, tous les paramètres liés au deuxième groupe sont estimés à 0 pour tousλ . Vérifier

coef(glm)

En interne, cv.glmnetil y a un appel à predictdéterminer pour chaque le nombre de coefficients non nuls. Essayerλ

predict(glm, type = "nonzero")

La structure est, à la lecture du cv.glmnetcode, supposée être une liste de listes, mais la deuxième entrée de la liste est NULL, et non une liste! Cela provoque l'erreur. Cela se produit dans ce bloc de code decv.glmnet

if (inherits(glmnet.object, "multnet")) {
    nz = predict(glmnet.object, type = "nonzero")
    nz = sapply(nz, function(x) sapply(x, length))
    nz = ceiling(apply(nz, 1, median))
}

Le résultat renvoyé par les deux sapplyappels imbriqués n'est pas une matrice comme prévu dans le dernier appel de apply. Cela génère l'erreur.

Il pourrait être très improbable de rencontrer l'erreur dans la pratique, mais le code devrait bien sûr être robuste aux cas extrêmes. Vous devez signaler le problème au responsable, Trevor Hastie (son e-mail est répertorié sur le lien).

NRH
la source
Merci pour la réponse réfléchie et rapide. La plupart des choses que vous dites semblent correctes, mais je ne suis pas sûr que la raison en soit nécessairement qu'elles soient linéairement séparables. Si vous augmentez le sd de la rnorm dans les entrées, l'erreur disparaît:
BenJWoodcroft
1
NRH: Une pensée sans rapport - je soupçonne que le professeur Hastie n'appréciera peut-être pas que vous mettiez son e-mail en texte clair comme ça, car cela peut inviter le spam (bien qu'il soit impossible de le dire avec certitude, bien sûr). Je ne veux pas paraître trop dur car votre réponse a été très utile ..
BenJWoodcroft
2
@BenJWoodcroft, ce n'est pas la séparabilité linéaire en tant que telle qui déclenche l'erreur mais l'organisation géométrique des trois groupes le long d'une ligne. La séparabilité linéaire rend cette organisation plus évidente dans les données échantillonnées, et si vous augmentez suffisamment l'écart-type, glmnet ne "découvre" pas l'organisation. Comme le montre votre deuxième exemple, vous n'avez pas réellement besoin de la séparabilité linéaire. Vous avez raison sur l'adresse e-mail, merci.
NRH
3
Je reçois également cette erreur avec glmnet 1.9.8 et avec R 3.1.1 avec le code ci-dessus ainsi que le code fourni sur la vignette avec les exemples de données.
user2030668
1
Je vois cette erreur avec des données réelles utilisant R 3.2.1 sur Windows et glmnet 2.0-2. Les données d'entraînement ont 449 observations de 229 prédicteurs. La variable de réponse a 9 niveaux. Toute suggestion sur la façon de procéder serait la bienvenue.
Kent Johnson
-1

Convertissez d'abord votre matrice par exemple

x sans réponse en numérique. Après cela, le (s) coefficient (s) significatif (s) contribuant au modèle trouvent par recherche des noms de famille ou des noms de domaine comme dans la structure des données, les variables sont.

Muhammad Naeem
la source