Błąd podczas uruchamiania glmnet w trybie wielomianowym [zamknięte]

9

Problem wspomniany w tym pytaniu został rozwiązany w wersji 1.7.3 pakietu R glmnet.

Mam problemy z uruchomieniem glmnet z rodziną = wielomian i zastanawiałem się, czy napotkałem coś podobnego lub mogę powiedzieć mi, co robię źle.

Po wprowadzeniu własnych danych fikcyjnych pojawia się błąd „Błąd w zastosowaniu (nz, 1, mediana): dim (X) musi mieć długość dodatnią”, gdy uruchamiam cv.glmnet, co oprócz powiedzenia „nie działało” nie było dla mnie bardzo pouczające.

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

Oto wizualny opis problemu, który próbowałem rozwiązać za pomocą glmnet, jeśli to pomaga:

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

Jestem w stanie uruchomić przykładowy kod z dokumentacji pakietu, co sprawia, że ​​jestem podejrzany, że coś źle zrozumiałem lub że występuje błąd w 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")

Korzysta z wersji R 2.13.1 (2011-07-08) i glmnet 1.7.1, chociaż mogę wygenerować ten sam problem na R 2.14.1. Jakieś pomysły ludzie?

BenJWoodcroft
źródło

Odpowiedzi:

11

Jest subtelny błąd.

To, co się dzieje, jest następujące: w twoim sztucznym zbiorze danych trzy średnie grupowe są na linii, a przy stosunkowo niewielkim odchyleniu standardowym trzy grupy stają się liniowo rozdzielalne w twojej 10-wymiarowej przestrzeni. W rezultacie wszystkie parametry związane z drugą grupą są szacowane na 0 dla wszystkichλ. Czek

coef(glm)

Wewnętrznie cv.glmnetjest wezwanie predictdo ustalenia dla każdegoλliczba niezerowych współczynników. Próbować

predict(glm, type = "nonzero")

Struktura po odczytaniu cv.glmnetkodu powinna być listą, ale drugim wpisem na liście jest NULL, a nie lista! To powoduje błąd. Dzieje się tak w tym bloku kodu zcv.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))
}

Wynik zwracany z dwóch zagnieżdżonych sapplywywołań nie jest macierzą, jak oczekiwano w ostatnim wywołaniu z apply. To generuje błąd.

W praktyce może być bardzo mało prawdopodobne, że wystąpi błąd, ale kod powinien oczywiście być odporny na ekstremalne przypadki. Powinieneś zgłosić problem opiekunowi Trevorowi Hastiemu (jego adres e-mail znajduje się pod linkiem).

NRH
źródło
Dzięki za miłą i szybką odpowiedź. Wydaje się, że większość rzeczy jest poprawna, ale nie jestem pewien, czy powodem jest to, że można je rozdzielić liniowo. Jeśli zwiększysz sd rnorma na wejściach, błąd zniknie:
BenJWoodcroft
1
NRH: Jedna myśl nie ma związku - podejrzewam, że prof. Hastie może nie docenić tego, że umieściłeś jego e-mail w zwykłym tekście, ponieważ może on zawierać spam (choć oczywiście nie można tego stwierdzić z całą pewnością). Nie chcę brzmieć zbyt ostro, ponieważ twoja odpowiedź była bardzo pomocna ..
BenJWoodcroft,
2
@BenJWoodcroft, to nie liniowa separacja jako taka powoduje błąd, ale geometryczna organizacja trzech grup wzdłuż linii. Liniowa separowalność czyni tę organizację bardziej oczywistą w próbkowanych danych, a jeśli wystarczająco zwiększysz odchylenie standardowe, glmnet nie „odkryje” organizacji. Jak pokazuje twój drugi przykład, tak naprawdę nie potrzebujesz liniowej separowalności. Masz rację co do adresu e-mail, dzięki.
NRH,
3
Ten błąd pojawia się również w glmnet 1.9.8 i R 3.1.1 z powyższym kodem, a także kodem podanym na winiecie z przykładowymi danymi.
user2030668,
1
Widzę ten błąd w przypadku danych rzeczywistych korzystających z wersji R 3.2.1 w systemie Windows i glmnet 2.0-2. Dane treningowe obejmują 449 obserwacji 229 predyktorów. Zmienna odpowiedzi ma 9 poziomów. Wszelkie sugestie dotyczące dalszego postępowania byłyby mile widziane.
Kent Johnson
-1

Najpierw przekonwertuj swoją matrycę na przykład

x bez odpowiedzi na liczbę. Następnie znaczący współczynnik (współczynniki), które przyczyniają się do modelu, znajdują się po wyszukiwaniu nazw lub nazw, podobnie jak w strukturze danych zmiennych.

Muhammad Naeem
źródło