Візуалізація калібрування передбачуваної ймовірності моделі


23

Припустимо, у мене є прогнозована модель, яка створює для кожного примірника ймовірність для кожного класу. Тепер я визнаю, що існує багато способів оцінити таку модель, якщо я хочу використовувати ці ймовірності для класифікації (точність, відкликання тощо). Я також усвідомлюю, що крива ROC та площа під нею можна використовувати для визначення того, наскільки добре модель розрізняє класи. Це не те, про що я прошу.

Мені цікаво оцінити калібрування моделі. Я знаю, що для цього завдання може бути корисним правило зарахування балів, як оцінка Brier . Це нормально, і я, ймовірно, буду включати щось у цьому напрямку, але я не впевнений, наскільки інтуїтивно зрозумілі будуть такі показники для непрофесіонала. Я шукаю щось більш наочне. Я хочу, щоб людина, що інтерпретує результати, змогла побачити, коли модель прогнозує щось чи не так, 70% ймовірно, що це трапиться ~ 70% часу тощо.

Я чув (але ніколи не використовував) сюжети QQ , і спочатку думав, що це те, що я шукав. Однак, схоже, це дійсно призначено для порівняння двох розподілів ймовірностей . Це не безпосередньо те, що я маю. Я маю для багатьох випадків свою передбачувану ймовірність, а потім, чи дійсно відбулася подія:

Index    P(Heads)    Actual Result
    1          .4            Heads
    2          .3            Tails
    3          .7            Heads
    4         .65            Tails
  ...         ...              ...

Тож чи QQ сюжет дійсно те, що я хочу, або я шукаю щось інше? Якщо графік QQ - це те, що я повинен використовувати, який правильний спосіб перетворення моїх даних у розподіл ймовірностей?

Я думаю, я міг би сортувати обидва стовпчики за передбачуваною ймовірністю, а потім створити кілька бункерів. Це такий тип речей, яким я повинен займатися, чи я десь замислююся? Мені знайомі різні методи дискретизації, але чи існує специфічний спосіб дискретизації бункерів, який є стандартним для подібних речей?

Відповіді:


19

Ваше мислення добре.

Джон Тукі рекомендував розшифровувати на половинки: розділити дані на верхню та нижню половини, потім розділити ці половини, потім розділити крайні половини рекурсивно. У порівнянні з бінінгу однакової ширини, це дозволяє візуально перевірити поведінку хвоста, не приділяючи занадто багато графічних елементів основній частині даних (посередині).

Ось приклад (з використанням R) підходу Тукі. (Це зовсім не те саме: він реалізував mletterтрохи інакше.)

Спочатку створимо деякі прогнози та деякі результати, які відповідають цим прогнозам:

set.seed(17)
prediction <- rbeta(500, 3/2, 5/2)
actual <- rbinom(length(prediction), 1, prediction)
plot(prediction, actual, col="Gray", cex=0.8)

Діаграма не дуже інформативна, тому що всі actualзначення, звичайно, або (не відбулося), або (мали місце). (На першому малюнку нижче він з’являється як фон сірих відкритих кіл.) Цей сюжет потребує згладжування. Для цього ми накопичуємо дані. Функція виконує поділ на половинки. Перший її аргумент - це масив рангів між 1 і (другий аргумент). Він повертає унікальні (числові) ідентифікатори для кожного контейнера:101mletterrn

mletter <- function(r,n) {
    lower <-  2 + floor(log(r/(n+1))/log(2))
    upper <- -1 - floor(log((n+1-r)/(n+1))/log(2))
    i <- 2*r > n
    lower[i] <- upper[i]
    lower
}

Використовуючи це, ми позначаємо як прогнози, так і результати та порівнюємо кожен з них. Попутно ми обчислюємо кількість сміття:

classes <- mletter(rank(prediction), length(prediction))
pgroups <- split(prediction, classes)
agroups <- split(actual, classes)
bincounts <- unlist(lapply(pgroups, length)) # Bin populations
x <- unlist(lapply(pgroups, mean))           # Mean predicted values by bin
y <- unlist(lapply(agroups, mean))           # Mean outcome by bin

Щоб ефективно символізувати сюжет, ми повинні зробити площі символів пропорційними кількості відходів. Буде корисно також трохи змінити кольори символів, звідки:

binprop <- bincounts / max(bincounts)
colors <- -log(binprop)/log(2)
colors <- colors - min(colors)
colors <- hsv(colors / (max(colors)+1))

Маючи це в руці, ми тепер покращуємо попередній сюжет:

abline(0,1, lty=1, col="Gray")                           # Reference curve
points(x,y, pch=19, cex = 3 * sqrt(binprop), col=colors) # Solid colored circles
points(x,y, pch=1, cex = 3 * sqrt(binprop))              # Circle outlines

Малюнок

Як приклад поганого прогнозування, давайте змінимо дані:

set.seed(17)
prediction <- rbeta(500, 5/2, 1)
actual <- rbinom(length(prediction), 1, 1/2 + 4*(prediction-1/2)^3)

Повторний аналіз виробляє цей сюжет, в якому відхилення чіткі:

Малюнок 2

Ця модель, як правило, є надто оптимістичною (середній результат для прогнозів у діапазоні від 50% до 90% занадто низький). У кількох випадках, коли прогноз низький (менше 30%), модель є занадто песимістичною.


(+1) Дуже приємно, дякую. Я думаю, що кольори можуть трохи відволіктися від мети, але решта була приємною ідеєю і дуже приємним поясненням.
Майкл МакГоуан

Майкл, я виявив, що потрібен якийсь колір, щоб допомогти побачити дуже маленькі кола, які з’являються на будь-якому кінці. Постійний колір, звичайно, досягнув би цього. Просто замініть col=colorsпотрібним кольором, наприклад col="Red".
whuber

+1, це дуже приємно. Однак я не зовсім інтуїтивно зрозумів, чому опорна лінія є простою, прямою 45 градусною лінією, а не правильною логістичною регресійною лінією чи льосом? Думаю, це будуть більш відповідні посилання, на основі яких можна судити про якість прогнозів.
gung - Відновіть Моніку

pp±[0,1]×[0,1]
whuber

p(1-p)/нpн

4

Інший варіант - ізотонічна регресія. Це схоже на відповідь Уабера, за винятком того, що бункери генеруються динамічно, а не розщепленням навпіл, з вимогою, щоб виходи суворо збільшувалися.

Основне використання ізотонічної регресії полягає в повторному калібруванні ймовірностей, якщо вони виявляються погано відкаліброваними, але також можуть бути використані для візуалізації. В основному, якщо ізотонічна лінія регресії приблизно відповідає лінії Y = X, то ваші ймовірності правильно відкалібровані.

Ізотонічна регресія щодо ймовірностей

Це ізотонічна регресія, застосована до проблеми, показаної Вюбером.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.isotonic import IsotonicRegression

prediction = np.random.beta(3.0/2.0, 5.0/2.0, size=500)
actual = np.random.binomial(1,prediction, len(prediction))
plt.scatter(prediction, actual,  facecolors='none', edgecolors=[0.3,0.3,0.3], label='Data')

ir = IsotonicRegression()
isotonic = ir.fit_transform(prediction, actual)
plt.plot(prediction, isotonic,'ok', label='Isotonic Fit')

plt.xlabel('Prediction')
plt.ylabel('Actual')
plt.plot([0,1],[0,1], '--k', label='y=x line')
plt.legend(loc = 'center left')

http://fa.bianp.net/blog/2013/isotonic-regression/

http://stat.wikia.com/wiki/Isotonic_regression


0

Ви також можете переглянути "підтвердження" пакета:

http://cran.r-project.org/web/packages/verification/index.html

У віньєтці є сюжети, які можуть бути корисні:

http://cran.r-project.org/web/packages/verification/vignettes/verification.pdf


1
Посилання на віньєтку більше не працює, і на першому посиланні CRAN, схоже, більше немає віньєтки.
BLT
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.