Nauč se Python > Kurzy > Datový kurz PyLadies > Úvod do strojového učení, regrese > Regrese - základní metriky

Regresní metriky #

V úvodním příkladu s krajinou jsme si metriku vymýšleli sami. Existuje samozřejmě řada standardním metrik, které se k hodnocení modelů používají. Uvedeme si přehled nejnámějších z nich:

y_y_hat_definice

  • MAE (Mean absolute error) - průměr absolutních hodnot odchylek požadovaných výstupů od predikovaných výstupů

    MAE formula

  • MSE (Mean squared error) - průměr sumy čterců odchylek požadovaných výstupů od predikovaných výstupů

    MSE formula

  • R2 score (Koeficient determinace) - koeficient determinace vyjadřuje, jaký podíl variability závislé proměnné (odezvy) model vyjadřuje. Dá se interpretovat tak, že říká, jak moc je náš model lepší než konstantní baseline daná jako průměr.

    R2 formula

R2 skóre dosahuje maximálně hodnoty jedna, což znamená dokonalou predikci.

Pokud nemáš ráda vzorečky, nelam si s nimi hlavu. Podívej se na následující příklad:

Vytvoříme dataframe, který bude obsahovat odezvy (sloupec "správně") a predikované hodnoty (sloupec "predikováno"). Pro jednoduchost hodnoty odezvy vygenerujeme náhodně a jejich "predikce" vytvoříme tak, že k těmto odezvám přičteme náhodné číslo z intervalu (-10, 10).

In [1]:
import pandas as pd 
import random

df = pd.DataFrame({"správně": [random.randint(10, 90) for _ in range(10)]})
df["predikováno"] = df["správně"].apply(lambda predikovano: predikovano + random.randint(-10, 10))
df
Out[1]:
správně predikováno
0 55 47
1 37 41
2 34 34
3 11 20
4 68 64
5 34 42
6 64 65
7 79 82
8 54 64
9 72 82

Spočteme si MSE, MAE a $R^2$ skóre. Napišme si na to funkci:

In [2]:
def spocti_metriky(skutecna_odezva, predikovano):
    chyby = pd.DataFrame()
    chyby["absolutní_chyba"] = abs(skutecna_odezva - predikovano)
    chyby["chyba_na_druhou"] = (skutecna_odezva - predikovano)**2
    baseline = skutecna_odezva.mean()
    chyby["chyba_na_druhou_baseline"] = (skutecna_odezva - baseline)**2

    MSE = chyby["chyba_na_druhou"].mean()
    MAE = chyby["absolutní_chyba"].mean()
    R2 = 1 - MSE/chyby["chyba_na_druhou_baseline"].mean()
    
    return chyby, MSE, MAE, R2
In [3]:
df_chyby, MSE, MAE, R2 = spocti_metriky(df["správně"], df["predikováno"])
# zobrazme si tabulku spolu s odpovídajícími chybami  
pd.concat([df, df_chyby], axis="columns")
Out[3]:
správně predikováno absolutní_chyba chyba_na_druhou chyba_na_druhou_baseline
0 55 47 8 64 17.64
1 37 41 4 16 190.44
2 34 34 0 0 282.24
3 11 20 9 81 1584.04
4 68 64 4 16 295.84
5 34 42 8 64 282.24
6 64 65 1 1 174.24
7 79 82 3 9 795.24
8 54 64 10 100 10.24
9 72 82 10 100 449.44
In [4]:
# vypišme si hodnoty metrik
print(f"MSE = {MSE}")
print(f"MAE = {MAE}")
print(f"R2 = {R2}")
MSE = 45.1
MAE = 5.7
R2 = 0.8895041160329282

Z tabulky výše i ze zobrazených chyb vidíme, že MSE daleko více penalizuje větší chyby.

Zkusme si ještě nasimulovat řešení, které bude poměrně přesné (náhodná odchylka, kterou přičítáme, bude z intervalu (-1,1)).

In [5]:
df2 = pd.DataFrame()
df2["správně"] = df["správně"]
df2["predikováno"] = df2["správně"].apply(lambda predikovano: predikovano + random.uniform(-1., 1.))
df2
Out[5]:
správně predikováno
0 55 54.769010
1 37 36.652405
2 34 34.909515
3 11 10.047192
4 68 67.872533
5 34 34.457738
6 64 63.634442
7 79 78.875997
8 54 53.542470
9 72 72.378543

Opět zorbrazme chyby:

In [6]:
df2_chyby, MSE_2, MAE_2, R2_2 = spocti_metriky(df2["správně"], df2["predikováno"])
pd.concat([df2, df2_chyby], axis="columns")
Out[6]:
správně predikováno absolutní_chyba chyba_na_druhou chyba_na_druhou_baseline
0 55 54.769010 0.230990 0.053356 17.64
1 37 36.652405 0.347595 0.120822 190.44
2 34 34.909515 0.909515 0.827217 282.24
3 11 10.047192 0.952808 0.907844 1584.04
4 68 67.872533 0.127467 0.016248 295.84
5 34 34.457738 0.457738 0.209524 282.24
6 64 63.634442 0.365558 0.133633 174.24
7 79 78.875997 0.124003 0.015377 795.24
8 54 53.542470 0.457530 0.209334 10.24
9 72 72.378543 0.378543 0.143295 449.44

A vypišme si hodnoty metrik:

In [7]:
print(f"MSE = {MSE_2:.3f} (minule: {MSE})")   # :.2f znamená float na dvě desetinná místa
print(f"MAE = {MAE_2:.3f} (minule: {MAE})")
print(f"R2  = {R2_2:.3f} (minule: {R2})")
MSE = 0.264 (minule: 45.1)
MAE = 0.435 (minule: 5.7)
R2  = 0.999 (minule: 0.8895041160329282)

Vidíme, že hodnoty MSE a MAE jsou teď výrazně menší než minule. To je proto, že "predikované" hodnoty jsou velmi blízko hodnotám skutečným. $R^2$ skóre vyšlo naopak vyšší (blíže jedné).

Pozn.: Pozor, nyní vyšla hodnota MAE vyšší než MSE, to je proto, že jednotlivé chyby jsou teď menší než jedna (mocnina je menší než absolutní hodnota).


Toto je stránka lekce z kurzu, který probíhá nebo proběhl naživo s instruktorem.