8.9 KiB
Uczenie maszynowe — laboratoria
5. Ewaluacja
Do wykonania zadań wykorzystaj wiedzę z wykładów.
5.1. Korzystanie z gotowych implementacji algorytmów na przykładzie pakietu _scikit-learn
Scikit-learn jest otwartoźródłową biblioteką programistyczną dla języka Python wspomagającą uczenie maszynowe. Zawiera implementacje wielu algorytmów uczenia maszynowego.
Poniżej przykład, jak stworzyć klasyfikator regresji liniowej wielu zmiennych z użyciem scikit-learn
.
Na podobnej zasadzie można korzystać z innych modeli dostępnych w bibliotece.
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
FEATURES = [
"Powierzchnia w m2",
"Liczba pokoi",
"Liczba pięter w budynku",
"Piętro",
"Rok budowy",
]
def preprocess(data):
"""Wstępne przetworzenie danych"""
data = data.replace({"parter": 0, "poddasze": 0}, regex=True)
data = data.map(np.nan_to_num) # Zamienia "NaN" na liczby
return data
# Nazwy plików
dataset_filename = "flats.tsv"
# Wczytanie danych
data = pd.read_csv(dataset_filename, header=0, sep="\t")
columns = data.columns[1:] # wszystkie kolumny oprócz pierwszej ("cena")
data = data[FEATURES + ["cena"]] # wybór cech
data = preprocess(data) # wstępne przetworzenie danych
# Podział danych na zbiory uczący i testowy
data_train, data_test = train_test_split(data, test_size=0.2)
# Uczenie modelu
y_train = pd.Series(data_train["cena"])
x_train = pd.DataFrame(data_train[FEATURES])
model = LinearRegression() # definicja modelu
model.fit(x_train, y_train) # dopasowanie modelu
# Predykcja wyników dla danych testowych
y_expected = pd.DataFrame(data_test["cena"])
x_test = pd.DataFrame(data_test[FEATURES])
y_predicted = model.predict(x_test) # predykcja wyników na podstawie modelu
print(y_predicted[:10]) # Pierwsze 10 wyników
[279661.8663101 279261.14658016 522543.09697553 243798.45172733 408919.21577439 272940.5507781 367515.38801642 592972.56867895 418509.89826131 943578.7139463 ]
Biblioteka _scikit-learn dostarcza również narzędzi do wstępnego przetwarzania danych, np. skalowania i normalizacji: https://scikit-learn.org/stable/modules/preprocessing.html
5.2. Metody ewaluacji
Bilioteka _scikit-learn dostarcza również narzędzi do ewaluacji algorytmów zaimplementowanych z wykorzystaniem jej metod.
Te narzędzia znajdują się w module sklearn.metrics
.
Ewaluacja regresji
Do ewaluacji regresji z powyższego przykładu możemy np. użyć metryki mean_squared_error
:
from sklearn.metrics import mean_squared_error
error = mean_squared_error(y_expected, y_predicted)
print(f"Błąd średniokwadratowy wynosi {error}")
Błąd średniokwadratowy wynosi 137394744518.31197
Większość modeli posiada też metodę score
, która zwraca wartość metryki tak skonstruowanej, żeby jej wartość wynosiła 1.0
, jeżeli y_predicted
jest równe y_expected
. Im mniejsza wartość score
, tym gorszy wynik.
print(model.score(x_test, y_expected))
0.2160821272059249
Ewaluacja klasyfikacji
Dla ewaluacji algorytmów klasyfikacji możemy użyć metody precision_recall_fscore_support
, która oblicza wartości metryk precyzji, pokrycia i F-score. Przydatna może być też metoda classification_report
.
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import precision_recall_fscore_support
from sklearn.model_selection import train_test_split
FEATURES = ["pl", "pw", "sl", "sw"]
# Wczytanie danych
data_iris = pd.read_csv("../wyk/iris.csv")
data_iris["Iris setosa?"] = data_iris["Gatunek"].apply(
lambda x: 1 if x == "Iris-setosa" else 0
)
# Podział danych na zbiór uczący i zbiór testowy
data_train, data_test = train_test_split(data_iris, test_size=0.2)
# Uczenie modelu
y_train = pd.Series(data_train["Iris setosa?"])
x_train = pd.DataFrame(data_train[FEATURES])
model = LogisticRegression() # definicja modelu
model.fit(x_train, y_train) # dopasowanie modelu
# Predykcja wyników
y_expected = pd.DataFrame(data_test["Iris setosa?"])
x_test = pd.DataFrame(data_test[FEATURES])
y_predicted = model.predict(x_test) # predykcja wyników na podstawie modelu
# Dla klasyfikacji dwuklasowej właśniwe będzie użycie `average="binary", pos_label=1`.
# W przeciwnym wypadku wartości Prec., Rec. i F1 będą identyczne, ponieważ będą liczone jako średnie dla obu klas.
# Z definicji zać Prec. dla pos_label=1 jest identyczna jak Rec. dla pos_label=0;
# analogicznie: Rec. dla pos_label=1 jest identyczne jak Prec. dla pos_label=0.
precision, recall, fscore, support = precision_recall_fscore_support(
y_expected, y_predicted, average="binary", pos_label=1
)
print(f"Precision: {precision}")
print(f"Recall: {recall}")
print(f"F-score: {fscore}")
score = model.score(x_test, y_expected)
print(f"Model score: {score}")
Precision: 1.0 Recall: 1.0 F-score: 1.0 Model score: 1.0