50 KiB
Kkolejna część zajęć będzie wprowadzeniem do drugiej, szeroko używanej biblioteki w Pythonie: sklearn
. Zajęcia będą miały charaktere case-study poprzeplatane zadaniami do wykonania. Zacznijmy od załadowania odpowiednich bibliotek.
# ! pip install matplotlib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
Zacznijmy od załadowania danych. Na dzisiejszych zajęciach będziemy korzystać z danych z portalu gapminder.org.
df = pd.read_csv('gapminder.csv', index_col=0)
Dane zawierają różne informacje z większość państw świata (z roku 2008). Poniżej znajduje się opis kolumn:
- female_BMI - średnie BMI u kobiet
- male_BMI - średnie BMI u mężczyzn
- gdp - PKB na obywatela
- population - wielkość populacji
- under5mortality - wskaźnik śmiertelności dzieni pon. 5 roku życia (na 1000 urodzonych dzieci)
- life_expectancy - średnia długość życia
- fertility - wskaźnik dzietności
zad. 1
Na podstawie danych zawartych w df
odpowiedz na następujące pytania:
- Jaki był współczynniki dzietności w Polsce w 2018?
- W którym kraju ludzie żyją najdłużej?
- Z ilu krajów zostały zebrane dane?
df.head(10)
df.loc['Poland', 'fertility']
df[df['life_expectancy'].max() == df['life_expectancy']]
len(df.index)
175
zad. 2 Stwórz kolumnę gdp_log
, która powstanie z kolumny gdp
poprzez zastowanie funkcji log
(logarytm).
Hint 1: Wykorzystaj funkcję apply
(https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.apply.html#pandas.Series.apply).
Hint 2: Wykorzystaj fukcję log
z pakietu np
.
df['gdp_log'] = df['gdp'].apply(np.log)
Naszym zadaniem będzie oszacowanie długości życia (kolumna life_expectancy
) na podstawie pozostałych zmiennych. Na samym początku, zastosujemy regresje jednowymiarową na fertility
.
y = df['life_expectancy'].values
X = df['fertility'].values
print("Y shape:", y.shape)
print("X shape:", X.shape)
Y shape: (175,) X shape: (175,)
Będziemy korzystać z gotowej implementacji regreji liniowej z pakietu sklearn. Żeby móc wykorzystać, musimy napierw zmienić shape na dwuwymiarowy.
y = y.reshape(-1, 1)
X = X.reshape(-1, 1)
print("Y shape:", y.shape)
print("X shape:", X.shape)
Y shape: (175, 1) X shape: (175, 1)
Jeszcze przed właściwą analizą, narysujmy wykres i zobaczny czy istnieje "wizualny" związek pomiędzy kolumnami.
df.plot.scatter('gdp_log', 'gdp')
<Axes: xlabel='gdp_log', ylabel='gdp'>
zad. 3 Zaimportuj LinearRegression
z pakietu sklearn.linear_model
.
Tworzymy obiekt modelu regresji liniowej.
from sklearn.linear_model import LinearRegression
model = LinearRegression()
Trening modelu ogranicza się do wywołania metodu fit
, która przyjmuje dwa argumenty:
model.fit(X, y)
LinearRegression()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LinearRegression()
Współczynniki modelu:
print("Wyraz wolny (bias):", model.intercept_)
print("Współczynniki cech:", model.coef_)
Wyraz wolny (bias): [83.2025629] Współczynniki cech: [[-4.41400624]]
zad. 4 Wytrenuj nowy model model2
, który będzie jako X przyjmie kolumnę gdp_log
. Wyświetl parametry nowego modelu.
y = df['life_expectancy'].values
X = df['gdp_log'].values
y = y.reshape(-1, 1)
X = X.reshape(-1, 1)
model.fit(X, y)
print("Wyraz wolny (bias):", model.intercept_)
print("Współczynniki cech:", model.coef_)
Wyraz wolny (bias): [20.24520889] Współczynniki cech: [[5.47719379]]
Mając wytrenowany model możemy wykorzystać go do predykcji. Wystarczy wywołać metodę predict
.
X_test = X[:5,:]
y_test = y[:5,:]
output = model.predict(X_test)
for i in range(5):
print("input: {}\t predicted: {}\t expected: {}".format(X_test[i,0], output[i,0], y_test[i,0]))
input: 7.1785454837637 predicted: 59.56349361537759 expected: 52.8 input: 9.064620717626777 predicted: 69.89389316839483 expected: 76.8 input: 9.418492105471156 predicted: 71.83211533534711 expected: 75.5 input: 8.86827250899781 predicted: 68.81845597997369 expected: 56.7 input: 10.155646068918863 predicted: 75.86965044411781 expected: 75.5
Sprawdzenie jakości modelu - metryki: $MSE$
Istnieją 3 metryki, które określają jak dobry jest nasz model:
- $MSE$: błąd średnio-kwadratowy
- $RMSE = \sqrt{MSE}$
from sklearn.metrics import mean_squared_error
rmse = np.sqrt(mean_squared_error(y, model.predict(X)))
print("Root Mean Squared Error: {}".format(rmse))
Root Mean Squared Error: 5.542126033117308
# Import necessary modules
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
# Create training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.30, random_state=42)
# Create the regressor: reg_all
reg_all = LinearRegression()
# Fit the regressor to the training data
reg_all.fit(X_train, y_train)
# Predict on the test data: y_pred
y_pred = reg_all.predict(X_test)
# Compute and print R^2 and RMSE
print("R^2: {}".format(reg_all.score(X_test, y_test)))
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print("Root Mean Squared Error: {}".format(rmse))
R^2: 0.768485708231896 Root Mean Squared Error: 4.108807300711791
Regresja wielu zmiennych
Model regresji liniowej wielu zmiennych nie różni się istotnie od modelu jednej zmiennej. Np. chcąc zbudować model oparty o dwie kolumny: fertility
i gdp
wystarczy zmienić X (cechy wejściowe):
X = df[['fertility', 'gdp']]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.30, random_state=42)
print(X.shape)
model_mv = LinearRegression()
model_mv.fit(X_train, y_train)
print("Wyraz wolny (bias):", model_mv.intercept_)
print("Współczynniki cech:", model_mv.coef_)
y_pred = model_mv.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print("Root Mean Squared Error: {}".format(rmse))
(175, 2) Wyraz wolny (bias): [78.39388437] Współczynniki cech: [[-3.68816683e+00 1.38298454e-04]] Root Mean Squared Error: 4.347105512793037
zad. 7
- Zbuduj model regresji liniowej, która oszacuje wartność kolumny
life_expectancy
na podstawie pozostałych kolumn. - Wyświetl współczynniki modelu.
- Oblicz wartości metryki rmse na zbiorze trenującym.
from sklearn.linear_model import LogisticRegression, LinearRegression, LogisticRegressionCV
from sklearn.model_selection import train_test_split
X = df.drop('life_expectancy', axis='columns')
y = df['life_expectancy']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3)
model = LinearRegression()
model.fit(X_train, y_train)
print("Wyraz wolny (bias):", model.intercept_)
print("Współczynniki cech:", model.coef_)
y_pred = model.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print(f"Root Mean Sqared Error: {rmse}")
Wyraz wolny (bias): 51.77966340645703 Współczynniki cech: [-1.26558913e+00 1.58457647e+00 -1.19465585e-05 8.99682207e-10 -1.32027358e-01 3.09413223e-01 1.74214537e+00] Root Mean Sqared Error: 3.42188778846474
zad. 6
Zaimplementuj metrykę $RMSE$ jako fukcję rmse (szablon poniżej). Fukcja rmse przyjmuje dwa parametry typu list i ma zwrócić wartość metryki $RMSE$ .
def rmse(expected, predicted):
"""
argumenty:
expected (type: list): poprawne wartości
predicted (type: list): oszacowanie z modelu
"""
if len(expected) != len(predicted):
raise ValueError("Lists have to be equal length, can't proceed.")
mse = 0
for i in range(len(expected)):
mse += pow((expected[i] - predicted[i]),2)
return np.sqrt(mse/len(expected))
y = df['life_expectancy'].values
X = df[['fertility', 'gdp']].values
test_model = LinearRegression()
test_model.fit(X, y)
predicted = list(test_model.predict(X))
expected = list(y)
# expected.append(1)
print(rmse(predicted,expected))
print(np.sqrt(mean_squared_error(predicted, expected)))
[1;31m---------------------------------------------------------------------------[0m [1;31mValueError[0m Traceback (most recent call last) [1;32mj:\Python\2023-programowanie-w-pythonie\zajecia3\sklearn cz. 1.ipynb Cell 39[0m line [0;36m2 [0;32m <a href='vscode-notebook-cell:/j%3A/Python/2023-programowanie-w-pythonie/zajecia3/sklearn%20cz.%201.ipynb#X53sZmlsZQ%3D%3D?line=25'>26</a>[0m expected[39m.[39mappend([39m1[39m) [0;32m <a href='vscode-notebook-cell:/j%3A/Python/2023-programowanie-w-pythonie/zajecia3/sklearn%20cz.%201.ipynb#X53sZmlsZQ%3D%3D?line=27'>28</a>[0m [39m# print(rmse(predicted,expected))[39;00m [1;32m---> <a href='vscode-notebook-cell:/j%3A/Python/2023-programowanie-w-pythonie/zajecia3/sklearn%20cz.%201.ipynb#X53sZmlsZQ%3D%3D?line=28'>29</a>[0m [39mprint[39m(np[39m.[39msqrt(mean_squared_error(predicted, expected))) File [1;32mc:\software\python3\lib\site-packages\sklearn\utils\_param_validation.py:211[0m, in [0;36mvalidate_params.<locals>.decorator.<locals>.wrapper[1;34m(*args, **kwargs)[0m [0;32m 205[0m [39mtry[39;00m: [0;32m 206[0m [39mwith[39;00m config_context( [0;32m 207[0m skip_parameter_validation[39m=[39m( [0;32m 208[0m prefer_skip_nested_validation [39mor[39;00m global_skip_validation [0;32m 209[0m ) [0;32m 210[0m ): [1;32m--> 211[0m [39mreturn[39;00m func([39m*[39margs, [39m*[39m[39m*[39mkwargs) [0;32m 212[0m [39mexcept[39;00m InvalidParameterError [39mas[39;00m e: [0;32m 213[0m [39m# When the function is just a wrapper around an estimator, we allow[39;00m [0;32m 214[0m [39m# the function to delegate validation to the estimator, but we replace[39;00m [0;32m 215[0m [39m# the name of the estimator by the name of the function in the error[39;00m [0;32m 216[0m [39m# message to avoid confusion.[39;00m [0;32m 217[0m msg [39m=[39m re[39m.[39msub( [0;32m 218[0m [39mr[39m[39m"[39m[39mparameter of [39m[39m\[39m[39mw+ must be[39m[39m"[39m, [0;32m 219[0m [39mf[39m[39m"[39m[39mparameter of [39m[39m{[39;00mfunc[39m.[39m[39m__qualname__[39m[39m}[39;00m[39m must be[39m[39m"[39m, [0;32m 220[0m [39mstr[39m(e), [0;32m 221[0m ) File [1;32mc:\software\python3\lib\site-packages\sklearn\metrics\_regression.py:474[0m, in [0;36mmean_squared_error[1;34m(y_true, y_pred, sample_weight, multioutput, squared)[0m [0;32m 404[0m [39m@validate_params[39m( [0;32m 405[0m { [0;32m 406[0m [39m"[39m[39my_true[39m[39m"[39m: [[39m"[39m[39marray-like[39m[39m"[39m], [1;32m (...)[0m [0;32m 415[0m y_true, y_pred, [39m*[39m, sample_weight[39m=[39m[39mNone[39;00m, multioutput[39m=[39m[39m"[39m[39muniform_average[39m[39m"[39m, squared[39m=[39m[39mTrue[39;00m [0;32m 416[0m ): [0;32m 417[0m [39m [39m[39m"""Mean squared error regression loss.[39;00m [0;32m 418[0m [0;32m 419[0m [39m Read more in the :ref:`User Guide <mean_squared_error>`.[39;00m [1;32m (...)[0m [0;32m 472[0m [39m 0.825...[39;00m [0;32m 473[0m [39m """[39;00m [1;32m--> 474[0m y_type, y_true, y_pred, multioutput [39m=[39m _check_reg_targets( [0;32m 475[0m y_true, y_pred, multioutput [0;32m 476[0m ) [0;32m 477[0m check_consistent_length(y_true, y_pred, sample_weight) [0;32m 478[0m output_errors [39m=[39m np[39m.[39maverage((y_true [39m-[39m y_pred) [39m*[39m[39m*[39m [39m2[39m, axis[39m=[39m[39m0[39m, weights[39m=[39msample_weight) File [1;32mc:\software\python3\lib\site-packages\sklearn\metrics\_regression.py:99[0m, in [0;36m_check_reg_targets[1;34m(y_true, y_pred, multioutput, dtype)[0m [0;32m 65[0m [39mdef[39;00m [39m_check_reg_targets[39m(y_true, y_pred, multioutput, dtype[39m=[39m[39m"[39m[39mnumeric[39m[39m"[39m): [0;32m 66[0m [39m [39m[39m"""Check that y_true and y_pred belong to the same regression task.[39;00m [0;32m 67[0m [0;32m 68[0m [39m Parameters[39;00m [1;32m (...)[0m [0;32m 97[0m [39m correct keyword.[39;00m [0;32m 98[0m [39m """[39;00m [1;32m---> 99[0m check_consistent_length(y_true, y_pred) [0;32m 100[0m y_true [39m=[39m check_array(y_true, ensure_2d[39m=[39m[39mFalse[39;00m, dtype[39m=[39mdtype) [0;32m 101[0m y_pred [39m=[39m check_array(y_pred, ensure_2d[39m=[39m[39mFalse[39;00m, dtype[39m=[39mdtype) File [1;32mc:\software\python3\lib\site-packages\sklearn\utils\validation.py:409[0m, in [0;36mcheck_consistent_length[1;34m(*arrays)[0m [0;32m 407[0m uniques [39m=[39m np[39m.[39munique(lengths) [0;32m 408[0m [39mif[39;00m [39mlen[39m(uniques) [39m>[39m [39m1[39m: [1;32m--> 409[0m [39mraise[39;00m [39mValueError[39;00m( [0;32m 410[0m [39m"[39m[39mFound input variables with inconsistent numbers of samples: [39m[39m%r[39;00m[39m"[39m [0;32m 411[0m [39m%[39m [[39mint[39m(l) [39mfor[39;00m l [39min[39;00m lengths] [0;32m 412[0m ) [1;31mValueError[0m: Found input variables with inconsistent numbers of samples: [175, 176]