Skip to content

Przewodniki

Klasyfikatory i regresory

Model predykcyjny ocenia się jak każdy inny system: funkcja wywoływalna zwraca predykcję dla każdego przypadku, a ewaluatory ją odczytują. Zmieniają się mianowniki. Trafność, czułość (recall) i precyzja to trzy odsetki liczone na trzech różnych zbiorach wierszy, a model może dobrze wyglądać w jednym z nich, nie odpowiadając na pytanie, które zadaje biznes.

examples/churn_model/ to projekt, na którym opiera się ta strona: dwieście kont, deterministyczny model odejść klientów i brak poświadczeń dostawcy.

Predykcja

System zwraca etykietę oraz, jeśli model ją ma, stojący za nią wynik liczbowy:

from oloproof import system


@system(name="churn-model", version="slice-f-example")
def run(account):
    score = churn_score(account)
    return {"label": score >= 0.5, "score": round(score, 4)}

Przypadek deklaruje prawdę pod expected:

{"expected": {"label": false}, "id": "account_000", "input": {"recent_upgrade": true, "support_contacts": 0, "tenure_months": 0}, "metadata": {"plan": "enterprise"}}

Blok `predictive:`

To, gdzie znajdują się predykcja, jej wynik i prawda, deklaruje się raz, dla całego projektu:

predictive:
  label_field: label
  score_field: score
  expected_field: label
  positive: true
  calibration_bins: 10
  thresholds: [0.3, 0.4, 0.5, 0.6, 0.7]
PoleDomyślnieZnaczenie
label_fieldlabelpole wyjścia zawierające przewidywaną etykietę
score_fieldscorepole wyjścia zawierające stojący za nią wynik
expected_fieldlabelpole pod expected zawierające prawdę
positivetruektóra wartość etykiety liczy się jako pozytywna; refund, 1 lub true
calibration_bins10ile przedziałów wyniku wykorzystuje tabela kalibracji
thresholdsbrakprogi odcięcia do przejrzenia; każdy jest dowodem, nigdy rekomendacją
averagebrakmacro lub micro, dla agregatu nad kilkoma klasami

Każdy ewaluator predykcyjny, który sam nie podaje field, expected_field ani positive, przejmuje je z tego bloku, więc jeden zestaw ma jedną klasę pozytywną. Ten blok wytwarza też liczebności macierzy pomyłek, tabelę kalibracji i przegląd progów; projekt bez niego otrzymuje metryki i nic poza nimi.

Klasa pozytywna, której nie odpowiada etykieta żadnego przypadku, jest odrzucana, zanim cokolwiek zostanie uruchomione, ponieważ czułość względem niej byłaby odsetkiem z niczego. Ten sam projekt z positive: churned:

Configuration error: evaluator 'recall' counts 'churned' as the positive class, and no case's 'label' is 'churned' (labels: False, True); declare `positive:` on the evaluator or in the `predictive:` block

Ewaluatory

evaluators:
  - {type: predictive_correct, criterion: accuracy}
  - {type: predictive_recall, criterion: recall}
  - {type: predictive_precision, criterion: precision}
  - {type: predictive_brier, criterion: brier}
  - {type: predictive_log_loss, criterion: log_loss, clip: 0.02}
  - {type: predictive_ranking, criterion: rank}
metrics:
  - {id: roc_auc, type: ranking, criterion: rank, statistic: roc_auc}
  - {id: pr_auc, type: ranking, criterion: rank, statistic: average_precision}
slices: [metadata.plan, "confidence:0.5"]
min_slice_support: 20

predictive_log_loss wymaga clip, ponieważ w przeciwnym razie jedna pewna pomyłka daje nieskończoność. predictive_ranking to kryterium, według którego metryka rankingowa porządkuje wiersze, i wymaga wpisu w metrics: wskazującego statystykę: ROC-AUC i średnia precyzja odpowiadają na różne pytania, a silnik nie wybierze jednej za Ciebie.

oloproof run
│ accuracy  │ 88.5%    │ [83.2%, 92.6%]  │ 177 / 200 observed · 0 missing · 0 excluded                                │
│ recall    │ 81.2%    │ [69.5%, 90.0%]  │ 52 / 64 observed · 0 missing · 136 excluded                                │
│ precision │ 82.5%    │ [70.9%, 91.0%]  │ 52 / 63 observed · 0 missing · 137 excluded                                │
│ brier     │ 0.120    │ [0.094, 0.154]  │ mean of 200 observed · 0 missing · 0 excluded                              │
│ log_loss  │ 0.389    │ [0.323, 0.499]  │ mean of 200 observed · 0 missing · 0 excluded                              │
│ roc_auc   │ 92.3%    │ [69.3%, 100.0%] │ roc_auc over 64 positive · 136 negative · 0 missing · 0 excluded           │
│ pr_auc    │ 86.5%    │                 │ average_precision over 64 positive · 136 negative · 0 missing · 0 excluded │

Warto przeczytać kolumnę excluded. Czułość mierzy się na 64 kontach, które odeszły, więc pozostałe 136 jest z niej wykluczone; precyzję — na 63 kontach oznaczonych przez model. Trzydzieści dwa procent tych kont odchodzi, więc model przewidujący, że nikt nie odejdzie, ma 68% trafności i nikogo nie znajduje. Sam próg minimalny na trafności by go przepuścił, dlatego polityka z przykładu nakłada próg minimalny na każdy odsetek.

pr_auc ma estymatę, ale nie ma przedziału. Przy dwustu wierszach jego przedział jest faktycznie słabszy niż przedział ROC-AUC, a silnik wstrzymuje granicę, której nie potrafi uzasadnić, zamiast ją pokazywać. Reguła na nim daje:

pr: INSUFFICIENT_EVIDENCE (interval_unavailable)

Obok metryk

Liczebności macierzy pomyłek to liczebności, a nie odsetki:

│ actually positive │ 52                 │ 12                 │
│ actually negative │ 11                 │ 125                │

Reguła wydania wskazująca jedną z nich jest błędem konfiguracji, ponieważ liczebność nie jest metryką:

Configuration error: release rule 'fp' refers to unknown metric 'false_positives'

Tabela kalibracji zestawia to, co model deklarował, z tym, co się wydarzyło, według przedziałów wyniku:

│ 0.2-0.3 │ 26.7%   │ 0.0%     │ 34 rows │
│ 0.5-0.6 │ 53.4%   │ 81.0%    │ 21 rows │

A przegląd progów pokazuje, co zmierzyłby każdy zadeklarowany próg odcięcia:

│ 0.3     │ 57.4%     │ 96.9%  │ 62/108 predicted positive · 62/64 actual positive │
│ 0.5     │ 82.5%     │ 81.2%  │ 52/63 predicted positive · 52/64 actual positive  │
│ 0.7     │ 100.0%    │ 37.5%  │ 24/24 predicted positive · 24/64 actual positive  │

Przegląd ma tytuł Thresholds (exploratory; recommends nothing). Który próg odcięcia jest właściwy, zależy od tego, ile kosztuje wynik fałszywie pozytywny w porównaniu z fałszywie negatywnym, a tego silnik nie może wiedzieć.

Regresja

Regresor jest oceniany błędem bezwzględnym, który wymaga zakresu, w jakim leżą jego wartości docelowe:

evaluators:
  - type: predictive_absolute_error
    criterion: days_error
    field: days
    expected_field: days
    target_range: [0, 20]
rules:
  - id: error-budget
    metric: days_error
    max: 1.5
│ days_error │ 1.02     │ [0.78, 1.88] │ mean of 120 observed · 0 missing · 0 excluded │
error-budget: INSUFFICIENT_EVIDENCE (interval_overlaps_threshold)

target_range jest wymagane i nie ma wartości domyślnej. Błąd bezwzględny to ograniczona średnia, a jej przedział obowiązuje tylko w zakresie, w którym leży każda wartość. Szerszy zakres oznacza szerszy przedział, więc należy zadeklarować zakres, jaki wartości docelowe mogą faktycznie przyjmować. Reguła nie może rozstrzygnąć: estymata mieści się w budżecie, ale 120 zamówień nie wystarcza jeszcze, by wykazać, że prawdziwy średni błąd też się w nim mieści.

Co dalej

  • Wycinki omawiają przedziały confidence: i liczebność wycinków.
  • Reguły porównania omawiają porównywanie dwóch wersji modelu.