모형의 예측 확률에 대한 보정 시각화


23

각 인스턴스에 대해 각 클래스에 대한 확률을 생성하는 예측 모델이 있다고 가정합니다. 이제 이러한 확률을 분류 (정밀도, 리콜 등)에 사용하려는 경우 이러한 모델을 평가할 수있는 여러 가지 방법이 있음을 알고 있습니다. 또한 ROC 곡선과 그 아래의 영역을 사용하여 모델이 클래스를 얼마나 잘 구별하는지 확인할 수 있습니다. 그것들은 내가 요구하는 것이 아닙니다.

모델 의 캘리브레이션 평가에 관심 이 있습니다. 나는 알고있다 • 그래도 채점 규칙찔레 점수가 이 작업에 유용 할 수 있습니다. 괜찮습니다. 그 라인을 따라 무언가를 포함시킬 것입니다. 그러나 평범한 사람에게 그러한 메트릭이 얼마나 직관적 일지는 잘 모르겠습니다. 좀 더 시각적 인 것을 찾고 있습니다. 결과를 해석하는 사람이 모델이 무언가가 70 % ~ 실제로 시간의 70 % 정도 발생할 가능성이 70 %라고 예측할 때이를 확인할 수 있기를 원합니다.

나는 QQ 플롯에 대해 들었지만 (사용한 적이 없음) 처음에는 이것이 내가 찾던 것이라고 생각했습니다. 그러나 실제로 두 확률 분포 를 비교하기위한 것 같습니다 . 그것은 내가 가진 것이 아닙니다. 나는 많은 경우에 대해 나의 예상 확률과 사건이 실제로 발생했는지 여부를 가지고 있습니다.

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

QQ 플롯은 실제로 내가 원하는 것입니까, 아니면 다른 것을 찾고 있습니까? QQ 플롯을 사용해야하는 경우 데이터를 확률 분포로 변환하는 올바른 방법은 무엇입니까?

예측 확률에 따라 두 열을 정렬 한 다음 빈을 만들 수 있다고 생각합니다. 내가해야 할 일이 그런가? 아니면 어딘가에서 생각할 때가 아닌가? 나는 다양한 이산화 기법에 익숙하지만 이런 종류의 표준 쓰레기통으로 분리하는 구체적인 방법이 있습니까?

답변:


19

당신의 생각은 좋습니다.

John Tukey는 데이터를 반으로 나누기를 권장했습니다. 데이터를 위와 아래로 나눈 다음 반을 나눈 다음 극한 반을 재귀 적으로 나눕니다. 너비가 같은 비닝과 비교하면 너무 많은 그래픽 요소를 대량의 데이터 (중간)에 할당하지 않고도 테일 동작을 육안으로 검사 할 수 있습니다.

다음은 Tukey 접근 방식의 예 (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) 매우 감사합니다. 나는 색상이 목적에서 약간 산만해질 수 있다고 생각하지만 나머지는 좋은 생각이었고 매우 좋은 설명이었습니다.
Michael McGowan

마이클, 나는 양쪽 끝에 나타나는 아주 작은 원을보기 위해 약간의 색이 필요 하다는 것을 알았습니다 . 물론 일정한 색은 이것을 달성 할 것입니다. col=colors원하는 색상으로 바꾸십시오 ( 예 :) col="Red".
whuber

+1, 이것은 매우 좋습니다. 그러나 기준선이 올바른 로지스틱 회귀선 또는 황토 대신 단순하고 직각 45 도인 이유는 무엇입니까? 나는 그것들이 예측의 질을 판단하기 위해 더 적절한 참조가 될 것이라고 생각해야한다.
gung-복직 모니카

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

@gung (Take 2) 내가 생각할 수있는 것은 잔차의 예상 변화를 설명하기 위해 시각화를 개선하는 것입니다. 그 변동은 비례해야합니다(1)/

4

또 다른 옵션은 등장 성 회귀입니다. 출력이 엄격하게 증가해야함에 따라 빈이 반으로 분할되는 대신 동적으로 생성된다는 점을 제외하고는 whuber의 답변과 비슷합니다.

등장 성 회귀 분석의 기본 사용법은 확률이 잘못 보정 된 경우 확률을 재보 정하는 것이지만 시각화에도 사용될 수 있습니다. 기본적으로 등장 성 회귀선이 Y = X 선을 거의 따르는 경우 확률이 올바르게 보정됩니다.

확률에 대한 등장 성 회귀

이것은 Whuber가 보여주는 문제에 적용된 등장 성 회귀입니다.

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


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.