Dans R, comment calculer la valeur de p pour l'aire sous ROC

12

J'ai du mal à trouver un moyen de calculer la valeur de p pour la zone sous une caractéristique d'opérateur de récepteur (ROC). J'ai une variable continue et un résultat de test de diagnostic. Je veux voir si AUROC est statistiquement significatif.

J'ai trouvé de nombreux packages traitant des courbes ROC: pROC, ROCR, caTools, vérification, Epi. Mais même après plusieurs heures passées à lire la documentation et à tester, je n'ai pas trouvé comment. Je pense que je l'ai raté.

user32530
la source
1
Qu'est-ce que cela pourrait signifier pour que la zone sous la courbe soit «significative»?
gung - Rétablir Monica
Je voulais dire tester si la valeur AUC est statistiquement différente de 0,5
user32530
D'où vient votre courbe ROC? Vraisemblablement, vous voulez un test de cela (par exemple, il existe une valeur de p pour un modèle de régression logistique pris dans son ensemble).
gung - Rétablir Monica
Eh bien, mes données sont les suivantes, j'ai un test standard qui fait le regroupement avec / sans maladie, et je veux trouver une valeur seuil pour une détermination biologique à partir d'un échantillon de sang. A côté de cela, j'ai besoin de la zone sous la courbe. Donc non, je n'ai pas de modèle de régression
user32530
Vous avez donc un test qui est effectué sur un échantillon de sang prélevé sur un patient, qui vous donne un numéro; & vous voudrez utiliser ce numéro pour classer si le patient a la maladie. À l'heure actuelle, vous disposez d'un ensemble de chiffres de ce test pour un ensemble de patients où vous connaissez leur véritable état pathologique. Est-ce que tout cela est correct?
gung - Rétablir Monica

Réponses:

12

Dans votre situation, il serait bien de tracer une courbe ROC et de calculer l'aire sous cette courbe, mais cela devrait être considéré comme complémentaire à votre analyse principale, plutôt que l'analyse primaire elle-même. Au lieu de cela, vous souhaitez adapter un modèle de régression logistique .

Le modèle de régression logistique sera livré en standard avec un test du modèle dans son ensemble. (En fait, puisque vous n'avez qu'une seule variable, cette valeur de p sera la même que la valeur de p pour votre variable de résultat de test.) Cette valeur de p est celle que vous recherchez. Le modèle vous permettra de calculer la probabilité prédite d'une observation d'être malade. Une caractéristique de fonctionnement du récepteur vous indique comment la sensibilité et la spécificité seront arbitrées si vous utilisez différents seuils pour convertir la probabilité prédite en une classification prédite. Étant donné que la probabilité prédite sera fonction de votre variable de résultat de test, elle vous indique également comment ils se négocient si vous utilisez différentes valeurs de résultat de test comme seuil.


Si vous n'êtes pas très familier avec la régression logistique, certaines ressources sont disponibles sur Internet (en plus de la page Wikipedia liée ci-dessus):

gung - Réintégrer Monica
la source
C'était très instructif. Je vous remercie! J'ai donc adapté un modèle logistique glm binomial (logit). Ensuite, je le compare à un modèle nul et ce test me donne la valeur de p que je recherche?
user32530
Oui, cela devrait le faire pour vous. LR rendra aussi beaucoup d'autres choses possibles, mais c'est peut-être tout ce dont vous avez besoin.
gung - Rétablir Monica
Le code serait donc le suivant? GLM.1 <- glm (Groupe ~ continuVar, famille = binomial (logit), données = diagnosticData) résumé (GLM.1) GLM.2 <- glm (Groupe ~ 1, famille = binomial (logit), données = diagnosticData) anova (GLM.2, GLM.1, test = "Chisq")
user32530
summary(GLM.1)devrait vous donner ce dont vous avez besoin, et je pense anova(GLM.1)qu'il le testera par rapport au modèle nul sans que vous ayez à l'adapter également. Mais votre chemin fonctionnera certainement, oui.
gung - Rétablir Monica
9

Fondamentalement, vous voulez tester H0 = "L'AUC est égale à 0,5".

Cela équivaut en fait à dire H0 = "La répartition des rangs dans les deux groupes est égale".

Cette dernière est l'hypothèse nulle du test de Mann-Whitney (Wilcoxon) (voir par exemple Gold, 1999 ).

En d'autres termes, vous pouvez utiliser en toute sécurité un test de Mann-Whitney-Wilcoxon pour répondre à votre question (voir par exemple Mason & Graham, 2002 ). C'est exactement ce que fait le package de vérification mentionné par Franck Dernoncourt.

Calimo
la source
Pourquoi serait-il intéressant de montrer que les prédictions ne sont pas aléatoires? Cela n'évalue pas l'utilité.
Frank Harrell
1
@FrankHarrell Parce que dans de nombreux cas, vos prévisions peuvent ne pas être meilleures qu'aléatoires - auquel cas l'utilité que vous signalez est en fait nulle. Bien sûr, il serait plus utile de rendre compte d'un intervalle de confiance des mesures d'utilité (sensibilité et spécificité). Mais tester la différence entre deux groupes est monnaie courante au moins dans la littérature clinique (et en fait, souvent, les groupes ne diffèrent pas) et j'ai vu des examinateurs le demander spécifiquement.
Calimo
Cela n'a aucun sens à mon humble avis. Je veux savoir à quel point quelque chose est utile, pas si c'est mieux que de simplement lancer une pièce.
Frank Harrell
Si ce n'est pas mieux que de lancer une pièce, pourquoi voudriez-vous passer par tout ce travail? Il suffit de lancer la pièce.
Scott
4

Vous pouvez utiliser roc.area () à partir de la vérification du package :

install.packages("verification")
library("verification")

# Data used from Mason and Graham (2002).
a<- c(1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990,
 1991, 1992, 1993, 1994, 1995)
d<- c(.928,.576, .008, .944, .832, .816, .136, .584, .032, .016, .28, .024, 0, .984, .952)

A<- data.frame(a,d)
names(A)<- c("year", "p2")

# For model without ties
roc.area(A$event, A$p2)

Il reviendra $p.value [1] 0.0069930071

Franck Dernoncourt
la source
Merci beaucoup, mais je n'ai pas de valeurs c et d. J'ai un test standard qui fait le regroupement avec / sans maladie, et je veux trouver une valeur seuil pour une détermination biologique à partir d'un échantillon de sang. A côté de cela, j'ai besoin de la zone sous la courbe. Donc non, je n'ai pas de régression. J'ai la variable binaire standard et la variable continue de valeur biologique
user32530
oh ok je pensais que vous aviez d, car je supposais que vous aviez déjà une courbe ROC.
Franck Dernoncourt
3
C'est généralement une erreur de chercher un seuil arbitraire lorsque la vraie relation avec la probabilité de maladie est lisse. En outre, tester l'hypothèse nulle selon laquelle la zone ROC est de 0,5 est une hypothèse assez ennuyeuse. Pour la plupart des prédictions, vous vous souciez de la qualité de la prédiction, et non de son caractère aléatoire.
Frank Harrell
Pas de problème, et merci, Frank Demoncourt, il y a peut-être un moyen d'obtenir d.
user32530
Dans le domaine médical, ils ont parfois besoin de ces points de coupure pour créer des tests de diagnostic. Avec ceux qu'ils veulent savoir si le sujet est malade ou non, ne pas prédire quelque chose. Parfois, ils doivent réduire les coûts avec une détermination moins coûteuse pour identifier l'état de la maladie.
user32530
0

Deux courbes ROC peuvent être comparées dans pROC en utilisant roc.test(). Cela produit également une valeur p. De plus, l'utilisation roc(..., auc=TRUE, ci=TRUE)vous donnera les intervalles de confiance inférieurs et supérieurs avec l'ASC dans la sortie lors de la création de l'objet ROC, ce qui peut être utile.

Voici un exemple de code qui teste si les miles par gallon ou le poids d'une voiture sont un meilleur indicateur du type de transmission dont elle est équipée (automatique ou manuelle):

library(pROC)
roc_object_1 <- roc(mtcars$am, mtcars$mpg, auc=T, ci=T) #gives AUC and CI
roc_object_2 <- roc(mtcars$am, mtcars$wt, auc=T, ci=T) #gives AUC and CI

roc.test(roc_object_1, roc_object_2) #gives p-value

Le poids est un prédicteur nettement meilleur que la consommation de carburant, semble-t-il. Cependant, cela compare deux courbes et non une seule courbe avec un nombre tel que 0,5. En regardant l'intervalle de confiance pour voir s'il contient le nombre 0,5 nous indique s'il est significativement différent, mais il ne produit pas de valeur p.

naco
la source
Fournit-il également la valeur de p?
Michael R. Chernick
Bien que la question soit posée spécifiquement en termes de R, notre politique générale ici est que nous sommes un site de Q&A de statistiques (machine learning, etc.). Ainsi, il est nécessaire qu'un Q ait un contenu statistique, et il est fortement préférable que les As ne soient pas uniquement fournis en termes spécifiques au logiciel. À la lumière de cela, pouvez-vous en dire plus sur ce qu'est ce test et comment il fonctionne, au-delà de simplement mentionner qu'il existe dans R & en montrant le code R pour cela?
gung - Rétablir Monica
Ok, je
mettrai à