Как pROC обрабатывает многоуровневые метки факторов?

Я рассчитываю AUC модели в R. Модель обучена предсказывать двухуровневый фактор (хороший/плохой). Он применялся к данным, имеющим трехуровневый результат (хороший/плохой/отсутствующий). Я в порядке с подсчетом очков. Я получаю вероятность на основе набора предикторов для каждого наблюдения.

Я не понимаю, что происходит, когда я вычисляю AUC с использованием roc(data$label, data$score), потому что теперь roc$label имеет 3 уровня (хорошо/плохо/отсутствует), но оценка была обучена на данных, которые имели только 2 уровня (хорошо/плохо). Новый уровень игнорируется? Должен ли я вручную исключить все такие наблюдения из данных, чтобы получить точную меру AUC?

data <- structure(list(label = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 1L, 2L, 2L, 3L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 2L), .Label = c("missing", 
"good", "bad"), class = "factor"), score = c(0.151147571051044, 
0.0411329810171418, 0.0688491931089625, 0.0457818202643564, 0.0411038297454905, 
0.0652004019004794, 0.105964115208592, 0.0538514549969684, 0.0415476305130247, 
0.0533831523731155, 0.0639788335617257, 0.0434341986489527, 0.0520826001358534, 
0.0642210548642832, 0.0536219837901353, 0.0415821872079014, 0.0416555537422, 
0.0491937562992912, 0.0469082976746886, 0.0538194884632293)), row.names = c(NA, 
-20L), class = c("tbl_df", "tbl", "data.frame"))

roc(data$label, data$score)

person DGenchev    schedule 04.10.2019    source источник
comment
Почему близкие голоса? Это явный вопрос программирования (и хороший), и он будет совершенно не по теме stats.SE.   -  person Calimo    schedule 04.10.2019


Ответы (2)


Если у вас не особенно старая версия pROC или у вас нет чего-то, что отключает диагностические сообщения, он должен сказать вам, что он делает:

> roc(data$label, data$score)
Setting levels: control = missing, case = good
Setting direction: controls < cases

Как видите, он использует «отсутствующий» класс в качестве контрольного или отрицательного класса.

Он продолжает показывать вам, какие данные были использованы:

[...]
Data: data$score in 3 controls (data$label missing) < 16 cases (data$label good).

Опять же, вы можете заметить, что он использует метку «отсутствует» в качестве элемента управления.

Наконец, это дает вам подсказку о том, как решить проблему:

[...]
Warning message:
In roc.default(data$label, data$score) :
  'response' has more than two levels. Consider setting 'levels' explicitly or using 'multiclass.roc' instead

В вашем случае проще всего установить аргумент levels, как было предложено:

> roc(data$label, data$score, levels=c("good", "bad"))
Setting direction: controls > cases

Call:
roc.default(response = data$label, predictor = data$score, levels = c("good",     "bad"))

Data: data$score in 16 controls (data$label good) > 1 cases (data$label bad).
Area under the curve: 0.8125

Теперь он правильно использует уровни «хороший/плохой», как вы просили.

И последнее, обратите внимание, что pROC по-прежнему автоматически устанавливает направление:

Setting direction: controls > cases

Вы должны убедиться, что это соответствует направлению (независимо от того, положительные случаи выше или ниже отрицательных), которые вы получили на обучающих данных.

train.roc <- roc(train.data$label, train.data$score, levels=c("good", "bad"))
roc(data$label, data$score, levels=c("good", "bad"), direction=train.roc$direction)

В противном случае вы можете внести некоторую погрешность в свои AUC, и вы можете подумать, что ваш предиктор работает отлично, когда это не так.

В общем, вы хотите явно установить аргументы levels и direction, когда это возможно. если направление каким-то образом изменится между обучением и тестированием.

person Calimo    schedule 04.10.2019
comment
Спасибо за подробный ответ! Все это имеет смысл сейчас. - person DGenchev; 08.10.2019

Категория missing является одним из 3 уровней фактора data$label.
Вы можете установить missing на реальное отсутствие, а затем отбросить этот уровень:

library(pROC)
# Set 'missing' to a real missing
data$label[data$label=="missing"] <- NA
# Drop 'missing' levels from 'label' factor
data$label <- droplevels(data$label)
# ROC estimation
roc(data$label, data$score)

Результат:

Setting levels: control = good, case = bad
Setting direction: controls > cases

Call:
roc.default(response = data$label, predictor = data$score)

Data: data$score in 16 controls (data$label good) > 1 cases (data$label bad).
Area under the curve: 0.8125
person Marco Sandri    schedule 04.10.2019