# --------------------------------------------------------------------------
# ----------------------- Rozpoznawanie Obrazow --------------------------
# --------------------------------------------------------------------------
# Zadanie 1: Regresja liniowa
# autorzy: A. Gonczarek, J. Kaczmar, S. Zareba
# 2017
# --------------------------------------------------------------------------
import numpy as np
from utils import polynomial
def mean_squared_error(x, y, w):
'''
:param x: ciag wejsciowy Nx1
:param y: ciag wyjsciowy Nx1
:param w: parametry modelu (M+1)x1
:return: blad sredniokwadratowy pomiedzy wyjsciami y
oraz wyjsciami uzyskanymi z wielowamiu o parametrach w dla wejsc x
'''
return np.sum((y - polynomial(x, w))**2)/x.shape[0]
def design_matrix(x_train,M):
'''
:param x_train: ciag treningowy Nx1
:param M: stopien wielomianu 0,1,2,...
:return: funkcja wylicza Design Matrix Nx(M+1) dla wielomianu rzedu M
'''
return [np.concatenate([x_train[i] ** j for j in range(M+1)]) for i in range(x_train.shape[0])]
def least_squares(x_train, y_train, M):
'''
:param x_train: ciag treningowy wejscia Nx1
:param y_train: ciag treningowy wyjscia Nx1
:param M: rzad wielomianu
:return: funkcja zwraca krotke (w,err), gdzie w sa parametrami dopasowanego wielomianu, a err blad sredniokwadratowy
dopasowania
'''
dm = np.array(design_matrix(x_train, M))
w = np.linalg.inv(dm.transpose() @ dm) @ (dm.transpose() @ y_train)
return (w, mean_squared_error(x_train, y_train, w))
def regularized_least_squares(x_train, y_train, M, regularization_lambda):
'''/media/Programowanie/Zrodla/Python/Lab2
:param x_train: ciag treningowy wejscia Nx1
:param y_train: ciag treningowy wyjscia Nx1
:param M: rzad wielomianu
:param regularization_lambda: parametr regularyzacji
:return: funkcja zwraca krotke (w,err), gdzie w sa parametrami dopasowanego wielomianu zgodnie z kryterium z regularyzacja l2,
a err blad sredniokwadratowy dopasowania
'''
dm = np.array(design_matrix(x_train, M))
w = np.linalg.inv(dm.transpose() @ dm + regularization_lambda * np.eye(M+1)) @ (dm.transpose() @ y_train)
return (w, mean_squared_error(x_train, y_train, w))
def model_selection(x_train, y_train, x_val, y_val, M_values):
'''
:param x_train: ciag treningowy wejscia Nx1
:param y_train: ciag treningowy wyjscia Nx1
:param x_val: ciag walidacyjny wejscia Nx1
:param y_val: ciag walidacyjny wyjscia Nx1
:param M_values: tablica stopni wielomianu, ktore maja byc sprawdzone
:return: funkcja zwraca krotke (w,train_err,val_err), gdzie w sa parametrami modelu, ktory najlepiej generalizuje dane,
tj. daje najmniejszy blad na ciagu walidacyjnym, train_err i val_err to bledy na sredniokwadratowe na ciagach treningowym
i walidacyjnym
'''
tuple_list = []
min_index = 0
for i in range(len(M_values)):
pair = least_squares(x_train, y_train, M_values[i])
ver_MSE = mean_squared_error(x_val, y_val, pair[0])
tuple_list.append((pair[0], pair[1], ver_MSE))
if (tuple_list[min_index][2] > ver_MSE):
min_index = i
return tuple_list[min_index]
def regularized_model_selection(x_train, y_train, x_val, y_val, M, lambda_values):
'''
:param x_train: ciag treningowy wejscia Nx1
:param y_train: ciag treningowy wyjscia Nx1
:param x_val: ciag walidacyjny wejscia Nx1
:param y_val: ciag walidacyjny wyjscia Nx1
:param M: stopien wielomianu
:param lambda_values: lista ze wartosciami roznych parametrow regularyzacji
:return: funkcja zwraca krotke (w,train_err,val_err,regularization_lambda), gdzie w sa parametrami modelu, ktory najlepiej generalizuje dane,
tj. daje najmniejszy blad na ciagu walidacyjnym. Wielomian dopasowany jest wg kryterium z regularyzacja. train_err i val_err to
bledy na sredniokwadratowe na ciagach treningowym i walidacyjnym. regularization_lambda to najlepsza wartosc parametru regularyzacji
'''
tuple_list = []
min_index = 0
for i in range(len(lambda_values)):
pair = regularized_least_squares(x_train, y_train, M, lambda_values[i])
ver_MSE = mean_squared_error(x_val, y_val, pair[0])
tuple_list.append((pair[0], pair[1], ver_MSE, lambda_values[i]))
if (tuple_list[min_index][2] > ver_MSE):
min_index = i
return tuple_list[min_index]