Nauč se Python > Kurzy > Datový kurz PyLadies > Strojové učení - úvod, 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 47 47
1 84 90
2 12 9
3 77 78
4 63 67
5 39 29
6 10 16
7 69 71
8 59 59
9 24 30

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 47 47 0 0 1.96
1 84 90 6 36 1267.36
2 12 9 3 9 1324.96
3 77 78 1 1 817.96
4 63 67 4 16 213.16
5 39 29 10 100 88.36
6 10 16 6 36 1474.56
7 69 71 2 4 424.36
8 59 59 0 0 112.36
9 24 30 6 36 595.36
In [4]:
# vypišme si hodnoty metrik
print(f"MSE = {MSE}")
print(f"MAE = {MAE}")
print(f"R2 = {R2}")
MSE = 23.8
MAE = 3.8
R2 = 0.9623441554332004

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 47 47.335226
1 84 84.328972
2 12 11.724504
3 77 77.372055
4 63 62.849184
5 39 39.474096
6 10 9.622450
7 69 69.525895
8 59 58.832013
9 24 23.011594

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 47 47.335226 0.335226 0.112377 1.96
1 84 84.328972 0.328972 0.108223 1267.36
2 12 11.724504 0.275496 0.075898 1324.96
3 77 77.372055 0.372055 0.138425 817.96
4 63 62.849184 0.150816 0.022746 213.16
5 39 39.474096 0.474096 0.224767 88.36
6 10 9.622450 0.377550 0.142544 1474.56
7 69 69.525895 0.525895 0.276566 424.36
8 59 58.832013 0.167987 0.028220 112.36
9 24 23.011594 0.988406 0.976946 595.36

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.211 (minule: 23.8)
MAE = 0.400 (minule: 3.8)
R2  = 1.000 (minule: 0.9623441554332004)

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.