import pandas as pd
__ = 0 # ignorujte, slouží dále jako volné místo pro doplnění
(Bude se vám hodit get_dummies, která kategoriální hodnoty zakóduje pomocí one hot encoding (pomocí nul a jedniček). (Pozn. dummies proto, že nám přibudou pomocné proměnné (sloupce), které se označují jako dummy variables.)
fish_data = pd.read_csv("fish_data.csv", index_col=0)
# dopište kód
...
V teorii strojového učení se vstupy modelu (příznaky, vstupní proměnné) typicky označují písmenem X a výstupy písmenem y. Takto se často označují i proměnné v kódu. X představuje matici (neboli tabulku), kde každý řádek odpovídá jednomu datovému vzorku a každý sloupec jednomu příznaku (vstupní proměnné). y je vektor, neboli jeden sloupec s odezvou.
Na vyzobnutí odezvy se výborně hodí metoda pop.
# doplň výběr příznaků a odezvy
y = __
X = __
Metoda train_test_split nám data rozdělí náhodně na trénovací a testovací sadu. Velikost testovací množiny můžeme specifikovat parametrem test_size, jeho přednastavená (default) hodnota je 0.25, t. j. 25%.
from sklearn.model_selection import train_test_split
# doplň rozdělení na testovací a trénovací data
# X_train, X_test, y_train, y_test = ...
Pro dnešek možno zkusit:
U příkladů s černými krabičkami v první hodině jsme si (za vašimi zády) několikrát trochu pomohli a krabičce jsme předali na začátku nějaké parametry. Krabička totiž často umožňuje uživateli, aby si ji nakonfiguroval. V terminologii krabiček si můžeme představit, že krabička má na sobě různé páčky, kterými se dá seřídit. Těmito páčkami se nastavují tzv. hyper-parametry modelu. Všechny modely, které najdeš v knihovně Scikit-learn, mají nějaké výchozí nastavení a půjdou použít i bez toho, aby ses nastavením těchto hyper-parametrů zabývala. V případě, že model nedává uspokojivý výsledek, můžeš zkusit tyto parametry upravit, např. vyzkoušet několik různých nastavení a porovnat hodnotu metriky na testovací množině.
U seznamu výše máme některé hyperparametry uvedené. Parametry často souvisejí s regularizací (výše alpha, C). Regularizace znamená, že model kromě toho, že se snaží nafitovat tak, aby odpovídal datům (dával správné odpovědi), zohledňuje nějaké další kriterium. Typicky toto kritérium hlídá, aby výstup modelu moc neosciloval, apod. Podobně jako jsi v příkladu s krajinou říkala, že řešení volíš tak, aby bylo plynulé, hezké, odpovídalo obvyklým krajinám.
Proces výběru modelu včetně jeho parametrů se nazývá model selection, v knihovně Scikit-learn najdeš nástroje, které ti mohou pomoci, pod heslem Model selection.
from sklearn.linear_model import LinearRegression, Lasso, SGDRegressor
from sklearn.svm import SVR
# neboj se seznam změnit nebo zkusit jiné hodnoty parametrů
model_zoo = [
(LinearRegression, {}),
(Lasso, {"alpha": 1.0}),
(Lasso, {"alpha": 0.5}),
(SVR, {"kernel": "rbf"}),
(SVR, {"kernel": "poly"})
]
K trénovaní (fitování) slouží metoda fit
, k predikci pro nové vzory metoda predict
.
model.fit(X_train, y_train)
pred = model.predict(X_test)
Metriku nemusíš programovat, k dispozici máš mean_absolute_error
, mean_squared_error
a r2_score
.
metrika = mean_absolute_error(y_test, pred)
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
def ml_game(X_train, y_train, X_test, y_test,
model_class, parametry):
""" 1. Vytvoří vybraný model s danými parametry.
2. Natrénuje jej na trénovací množině.
3. Spočte a vypíše hodnoty metrik na trénovací i testovací množině.
returns naučený model
"""
# vytvoříme model
model = model_class(**parametry)
# doplň kód dle bodů výše
return model
# stačí odkomentovat
#trained_models = []
#for classname, parametry in model_zoo:
# model = ml_game(X_train, y_train, X_test, y_test, classname, parametry)
# trained_models.append(model)
Naučili jsme několik modelů. Zamysli se teď na chvilku, který by sis vybrala a proč.
Označme si jej jako best_model
. Můžeš si i zkusit pohrát s hyperparametry a zvolit jiné nastavení.
# doplň pořadí modelu, který jsi vybrala
# best_model = trained_models[__]
Data jsme si rozdělili na trénovací a testovací. Trénovací jsme použili na učení modelu. Ale pozor! Testovací množinu jsme použili k výběru modelu. Metrika na testovací množině nám tedy nedává nezávislý odhad toho, jak se bude náš model chovat na neznámých datech. Byl totiž vybrán tak, aby dával dobré výsledky na testovací množině.
Testovací množina nám slouží jako odhad generalizačních schopností modelu. Neměla by ale být použita ani při učení, ani při výběru modelu. Část, kterou si oddělíme na "testování" pro účely výběru modelu, nazýváme správně validační množina. Pozor: Pokud jsme ale tuto validační množinu použili k výběru modelu, nesmíme ji používat k samotnému hodnocení generalizačních schopností tohoto modelu.
A proto teď přichází opravdová testovací data, načtěte je ze souboru fish_data_test.csv
.
test_data = pd.read_csv("fish_data_test.csv", index_col=0)
test_data = pd.get_dummies(test_data.drop(columns=["ID"]))
y_real_test = test_data.pop("Weight")
X_real_test = test_data
#y_pred_test = best_model.predict(X_real_test)
#print(f"MAE {mean_absolute_error(y_real_test, y_pred_test):.3f}")
#print(f"MSE {mean_squared_error(y_real_test, y_pred_test):.3f}")
#for weight, predicted_weight in zip(y_real_test, y_pred_test):
# print(f"{weight:>10.1f} {predicted_weight:>10.1f}")
mam_hotovy_prechozi_kod = False
if mam_hotovy_prechozi_kod:
is_pike = X["Species_Pike"] == 1
pike = X[is_pike]["Length3"]
pike_weights = y[is_pike]
predicted_pike_weights = trained_models[0].predict(X[is_pike])
is_roach = X["Species_Roach"] == 1
roach = X[is_roach]["Length3"]
roach_weights = y[is_roach]
predicted_roach_weights = trained_models[0].predict(X[is_roach])
import matplotlib.pyplot as plt
if mam_hotovy_prechozi_kod:
fig, ax = plt.subplots(1, 2)
ax[0].plot(pike, pike_weights, label="true weight");
ax[0].plot(pike, predicted_pike_weights, label="prediction");
ax[0].legend()
ax[1].plot(roach, roach_weights, label="true weight");
ax[1].plot(roach, predicted_roach_weights, label="prediction");
ax[1].legend()