uczenie-maszynowe/lab/05_Ewaluacja.ipynb
Paweł Skórzewski 7bf375944a Lab. 5 i wyk. 6
2024-04-18 09:44:59 +02:00

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