Wizualizacja kalibracji przewidywanego prawdopodobieństwa modelu

23

Załóżmy, że mam model predykcyjny, który generuje dla każdej instancji prawdopodobieństwo dla każdej klasy. Teraz zdaję sobie sprawę, że istnieje wiele sposobów oceny takiego modelu, jeśli chcę wykorzystać te prawdopodobieństwa do klasyfikacji (precyzja, przywołanie itp.). Rozumiem również, że krzywa ROC i obszar pod nią mogą być użyte do określenia, jak dobrze model rozróżnia klasy. Nie o to pytam.

Jestem zainteresowany oceną kalibracji modelu. Wiem, że zasada punktacji, taka jak wynik Briera, może być przydatna w tym zadaniu. Zgadza się i prawdopodobnie uwzględnię coś w tym stylu, ale nie jestem pewien, jak intuicyjne będą takie wskaźniki dla osób świeckich. Szukam czegoś bardziej wizualnego. Chcę, aby osoba interpretująca wyniki mogła zobaczyć, czy model przewiduje 70% prawdopodobieństwo, że tak się stanie ~ 70% czasu itp.

Słyszałem (ale nigdy nie korzystałem) z wykresów QQ i na początku myślałem, że tego właśnie szukam. Wydaje się jednak, że tak naprawdę służy porównywaniu dwóch rozkładów prawdopodobieństwa . Nie to mam bezpośrednio. Mam, na kilka przykładów, moje przewidywane prawdopodobieństwo, a następnie to, czy zdarzenie rzeczywiście miało miejsce:

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

Czy więc fabuła QQ jest naprawdę tym, czego chcę, czy szukam czegoś innego? Jeśli powinienem używać wykresu QQ, jaki jest właściwy sposób na przekształcenie moich danych w rozkłady prawdopodobieństwa?

Wyobrażam sobie, że mógłbym posortować obie kolumny według przewidywanego prawdopodobieństwa, a następnie utworzyć kilka koszy. Czy to jest rodzaj rzeczy, którą powinienem robić, czy też gdzieś się zastanawiam? Znam różne techniki dyskretyzacji, ale czy istnieje specyficzny sposób dyskretyzacji na pojemniki, który jest standardem w tego typu sprawach?

Michael McGowan
źródło

Odpowiedzi:

19

Twoje myślenie jest dobre.

John Tukey zalecił podział na połowy: podziel dane na górną i dolną połowę, następnie podziel te połówki, a następnie podziel rekurencyjnie skrajne połówki. W porównaniu z binowaniem o równej szerokości, pozwala to na wizualną kontrolę zachowania ogona bez poświęcania zbyt wielu elementów graficznych dużej ilości danych (w środku).

Oto przykład (przy użyciu R) podejścia Tukeya. (To nie jest dokładnie to samo: zaimplementował mlettertrochę inaczej.)

Najpierw utwórzmy przewidywania i wyniki zgodne z tymi przewidywaniami:

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

Fabuła nie jest zbyt pouczająca, ponieważ wszystkie actualwartości to oczywiście (nie wystąpiło) lub (wystąpiło). (Pojawia się jako tło szarych otwartych kółek na pierwszym rysunku poniżej.) Ta fabuła wymaga wygładzenia. Aby to zrobić, zbieramy dane na bin. Funkcja wykonuje podział na pół. Pierwszym argumentem jest tablica rang między 1 a (drugi argument). Zwraca unikalne (numeryczne) identyfikatory dla każdego pojemnika: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
}

Korzystając z tego, dzielimy zarówno prognozy, jak i wyniki, i uśredniamy każdy w każdym bin. Po drodze obliczamy populacje bin:

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

Aby skutecznie symbolizować wykres, powinniśmy uczynić obszary symboli proporcjonalnymi do liczby bin. Przydatne może być również nieznaczne zróżnicowanie kolorów symboli, skąd:

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

Mając je w ręku, ulepszamy teraz poprzedni wątek:

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

Postać

Jako przykład złej prognozy zmieńmy dane:

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

Powtórzenie analizy daje wykres, w którym odchylenia są wyraźne:

Rysunek 2

Ten model jest zwykle zbyt optymistyczny (średni wynik dla prognoz w zakresie 50% do 90% jest zbyt niski). W kilku przypadkach, w których przewidywanie jest niskie (mniej niż 30%), model jest zbyt pesymistyczny.

Whuber
źródło
(+1) Bardzo miło, dzięki. Myślę, że kolory mogą nieco odwrócić uwagę od celu, ale reszta była fajnym pomysłem i bardzo ładnym wyjaśnieniem.
Michael McGowan
Michael, odkryłem, że potrzebny jest jakiś kolor, aby zobaczyć bardzo małe kółka, które pojawiają się na obu końcach. Stały kolor oczywiście by to osiągnął. Wystarczy zastąpić żądanym col=colorskolorem, takim jak col="Red".
whuber
+1, to jest bardzo miłe. Nie do końca jednak rozumiem, dlaczego linia odniesienia jest prostą, prostą linią 45 stopni zamiast właściwej linii regresji logistycznej, czy też lesssem? Powinienem pomyśleć, że byłyby to bardziej odpowiednie odniesienia, na podstawie których można ocenić jakość prognoz.
gung - Przywróć Monikę
@gung Pomyśl o tym: prognoza jest dokładna, gdy wyniki są zgodne z prognozą. Dlatego wśród zbioru prognoz zbliżonych do lepiej byłoby, gdyby przeciętny wynik był również zbliżony do . Każdy inny związek odzwierciedlałby nieścisłości. W szczególności, jak zaproponowałbyś narysowanie „właściwej linii regresji logistycznej” - która wydaje się rozciągać do wzdłuż jednej lub obu osi - na wykresie, który musi zawierać się w kwadracie jednostkowym ? p ± [ 0 , 1 ] × [ 0 , 1 ]pp±[0,1]×[0,1]
whuber
@gung (Take 2) Myślę, że możesz mieć na myśli poprawę wizualizacji w celu uwzględnienia oczekiwanej zmienności reszt. Ta zmiana powinna być proporcjonalna do dla punktu związanego z przewidywaniami w pobliżu składającego się z obserwacji. Ciekawym wyzwaniem jest wymyślenie użytecznego, najlepiej gestaltowanego sposobu, aby przedstawić to na takiej grafice statystycznej. (Przypuszczam, że można pnp(1p)/npn
ustawić
4

Inną opcją jest regresja izotoniczna. Jest podobny do odpowiedzi Whubera, z tym wyjątkiem, że pojemniki są generowane dynamicznie zamiast przez dzielenie na pół, z warunkiem, że produkcja ściśle rośnie.

To podstawowe zastosowanie regresji izotonicznej polega na ponownej kalibracji prawdopodobieństw, jeśli okażą się źle skalibrowane, ale można je również wykorzystać do wizualizacji. Zasadniczo, jeśli linia regresji izotonicznej z grubsza podąża za linią Y = X, wówczas prawdopodobieństwa są odpowiednio skalibrowane.

Regresja izotoniczna na prawdopodobieństwach

Jest to regresja izotoniczna zastosowana do problemu pokazanego przez Whubera.

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

Bscan
źródło