2016-06-08 3 views
0

J'ai formé un modèle binomial en utilisant glm(Xtrain, ytrain, formula='cbind(Response, n - Response) ~ features', family='binomial'), où ytrain est une matrice de réponse avec des colonnes de comptes (oui), compte (non).Calculer la courbe AUC pour les réponses sous la forme cbind (Count_1, Count_0)

Les réponses de test que j'ai montrées sont dans la même forme de matrice de réponse. Cependant, la fonction predict() renvoie des probabilités - une pour chaque ligne des données d'apprentissage. Je veux maintenant utiliser le paquet ROCR ou AUC pour générer des courbes AUC, mais mes prédictions et observations sont dans différents formats. Est-ce que quelqu'un sait comment faire ça?


OK. Ajouter un exemple Pardonnez-moi que ce soit dénué de sens/rang déficient/petit, je veux seulement illustrer mon cas.

plants <- c('Cactus', 'Tree', 'Cactus', 'Tree', 'Flower', 'Tree', 'Tree') 
sun <- c('Full', 'Half', 'Half', 'Full', 'Full', 'Half', 'Full') 
water <- c('N', 'Y', 'Y', 'N', 'Y', 'N', 'N') 
died <- c(10, 10, 8, 2, 15, 20, 12) 
didntdie <- c(2, 10, 8, 20, 10, 10, 10) 
df <- data.frame(died, didntdie, plants, sun, water) 
dftrain <- head(df, 5) 
dftest <- tail(df, 2) 
model <- glm("cbind(died, didntdie) ~ plants + sun + water", data=dftrain, family="binomial") 

À ce stade, predict(model, dftest) retourne les log-odds (donnant une probabilité de décès) pour les deux derniers ensembles de caractéristiques dans mon dataframe. Maintenant, je souhaite calculer une courbe AUC. Mes observations sont au dftest[c('died','didntdie')]. Mes prédictions sont essentiellement des probabilités. AUC, ROCR, etc. s'attendent à ce que les prédictions et les observations soient une liste de réponses bernoulli. Je ne trouve pas de documentation sur la façon d'utiliser cette matrice de réponse à la place. Toute aide appréciée.

+2

Vous devriez fournir un [exemple reproductible] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) pour vous faciliter la tâche. Qu'est-ce que «Xtrain»? La fonction 'glm()' par défaut n'a pas de paramètre 'eqtn ='. À quoi comparez-vous les probabilités? Comment voulez-vous calculer le ROC avec ces données? – MrFlick

Répondre

2

Pour commencer, vous pouvez développer la trame de données pour synthétiser des résultats binaires avec des comptes qui exploitent l'argument weight= à glm().

obs <- died + didntdie 
df <- df[rep(1:length(obs), each= 2),] # one row for died and one for didn't 
df$survived <- rep(c(0L,1L), times=length(obs)) # create binary outcome for survival 
df$weight <- c(rbind(died, didntdie)) # assign weights 
df 

#  died didntdie plants sun water survived weight 
# 1  10  2 Cactus Full  N  0  10 
# 1.1 10  2 Cactus Full  N  1  2 
# 2  10  10 Tree Half  Y  0  10 
# 2.1 10  10 Tree Half  Y  1  10 
# 3  8  8 Cactus Half  Y  0  8 
# 3.1 8  8 Cactus Half  Y  1  8 
# 4  2  20 Tree Full  N  0  2 
# 4.1 2  20 Tree Full  N  1  20 
# 5  15  10 Flower Full  Y  0  15 
# 5.1 15  10 Flower Full  Y  1  10 
# 6  20  10 Tree Half  N  0  20 
# 6.1 20  10 Tree Half  N  1  10 
# 7  12  10 Tree Full  N  0  12 
# 7.1 12  10 Tree Full  N  1  10 

model <- glm(survived ~ plants + sun + water, data=df, family="binomial", weights = weight) 

Si vous voulez faire la scission train/test, vous aurez besoin de faire une autre extension, cette fois-ci sur la duplication des lignes weight. Dans le cas contraire, votre test n'est pas un holdout aléatoire, au moins un randomisé au niveau de chaque plante, ce qui peut invalider vos résultats (en fonction de ce que vous essayez de conclure).

Ainsi, vous feriez quelque chose comme

df <- df[rep(1:nrow(df), times = df$weight),] 
model <- glm(survived ~ plants + sun + water, data=df, family="binomial") 
# note the model does not change 

library(pROC) 
auc(model$fitted.values, df$survived) 
# Area under the curve: 0.5833 

RemarqueCet est la CUA dans l'échantillon. Vous devez utiliser une rétention aléatoire (ou mieux encore, une validation croisée) pour estimer l'AUC hors échantillon. L'utilisation des N premières lignes du data.frame pour la division est et non une bonne idée sauf si l'ordre des lignes a déjà été randomisé.

+0

Ah! Merci pour l'exemple de la façon d'étendre la df. Ça va le faire, je pense. (Cependant, trop mauvais ROCR n'a pas de paramètre vous permettant d'entrer d'autres formes de données.) – Erin

+0

@Erin dans cet exemple, je vous ai montré comment le calculer en utilisant 'pROC :: auc'. 'ROCR :: prediction' est trop lent si tout ce que vous voulez est AUC. ROCR fait d'autres trucs sympas sous le capot. Vous pouvez aussi écrire votre propre fonction AUC, ce que j'utilise lorsque je travaille dans 'data.table' (non applicable ici). – C8H10N4O2

+0

cool, merci pour l'info supplémentaire sur pROC. Ne vous inquiétez pas de conseiller mes choix de retenue - je sais comment je fais cette partie. – Erin