Рассчитайте кривую AUC для ответов в форме cbind (Count_1, Count_0)

Я обучил биномиальную модель, используя glm(Xtrain, ytrain, formula='cbind(Response, n - Response) ~ features', family='binomial'), где ytrain - это матрица ответов со столбцами counts (да), counts (нет).

Тестовые ответы, которые я представил, представлены в той же форме матрицы ответов. Однако функция предсказать () возвращает вероятности - по одной для каждой строки обучающих данных. Теперь я хочу использовать пакет ROCR или AUC для создания кривых AUC, но мои прогнозы и наблюдения представлены в разных форматах. Кто-нибудь знает как это сделать?


OK. Добавляем пример. Простите, что это бессмысленно / неполноценно / мало, я хочу только проиллюстрировать свой случай.

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")

На этом этапе predict(model, dftest) возвращает логарифмические шансы (дающие вероятность смерти) для последних двух наборов функций в моем фреймворке данных. Теперь я хочу вычислить кривую AUC. Мои наблюдения в dftest[c('died','didntdie')]. Мои прогнозы по сути являются вероятностями. AUC, ROCR и т. Д. Ожидают, что и прогнозы, и наблюдения будут списком ответов Бернулли. Я не могу найти документацию о том, как использовать эту матрицу ответов. Любая помощь приветствуется.


person Erin    schedule 08.06.2016    source источник
comment
Вы должны предоставить воспроизводимый пример, чтобы вам было легче помочь. ты. Что такое Xtrain? Функция glm() по умолчанию не имеет параметра eqtn=. С чем вы сравниваете вероятности? Как именно вы хотите рассчитать ROC с этими данными?   -  person MrFlick    schedule 08.06.2016


Ответы (1)


Для начала вы можете расширить фрейм данных, чтобы синтезировать двоичные результаты со счетчиками, которые используют аргумент 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)

Если вы хотите выполнить разделение «поезд / тест», вам нужно будет выполнить другое расширение, на этот раз дублируя строки на weight. В противном случае ваш набор тестов не является случайным отклонением, по крайней мере, одним рандомизированным на уровне отдельного предприятия, что может сделать ваши результаты недействительными (в зависимости от того, что вы пытаетесь сделать).

Таким образом, вы бы сделали что-то вроде

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

Обратите внимание, что это AUC в образце. Для оценки AUC вне выборки следует использовать рандомизированное отклонение (или, еще лучше, перекрестную проверку). Использование N верхних строк data.frame для разделения не является хорошей идеей, если порядок строк уже не был рандомизирован.

person C8H10N4O2    schedule 08.06.2016
comment
Ах! Спасибо за пример того, как расширить df. Думаю, это сработает. (Хотя, к сожалению, ROCR не имеет параметра, позволяющего вводить другие формы данных.) - person Erin; 09.06.2016
comment
@Erin в этом примере я показал вам, как вычислить его, используя pROC::auc. ROCR::prediction работает слишком медленно, если вам нужна только AUC. ROCR делает под капотом и другие классные вещи. Вы также можете написать свою собственную функцию AUC, которую я использую при работе в data.table (здесь не применимо). - person C8H10N4O2; 09.06.2016
comment
круто, спасибо за дополнительную информацию о pROC. Не беспокойтесь о том, что я могу посоветовать мне, что я не могу, - я знаю, как я это делаю. - person Erin; 09.06.2016