-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.py
118 lines (96 loc) · 4.51 KB
/
content.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# --------------------------------------------------------------------------
# ------------ Metody Systemowe i Decyzyjne w Informatyce ----------------
# --------------------------------------------------------------------------
# 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: ciąg wejściowy Nx1
:param y: ciąg wyjsciowy Nx1
:param w: parametry modelu (M+1)x1
:return: błąd średniokwadratowy pomiędzy wyjściami y oraz wyjściami
uzyskanymi z wielowamiu o parametrach w dla wejść x
"""
return np.sum((y - polynomial(x, w)) ** 2) / x.shape[0]
def design_matrix(x_train, M):
"""
:param x_train: ciąg treningowy Nx1
:param M: stopień wielomianu 0,1,2,...
:return: funkcja wylicza Design Matrix Nx(M+1) dla wielomianu rzędu M
"""
N = x_train.shape[0]
result_matrix = np.array([[x_train.flatten()[n] ** m for m in range(M + 1)] for n in range(N)])
return (result_matrix)
def least_squares(x_train, y_train, M):
"""
:param x_train: ciąg treningowy wejśćia Nx1
:param y_train: ciąg treningowy wyjscia Nx1
:param M: rzad wielomianu
:return: funkcja zwraca krotkę (w,err), gdzie w są parametrami dopasowanego
wielomianu, a err to błąd średniokwadratowy dopasowania
"""
features_matrix = design_matrix(x_train, M)
w = np.linalg.inv((features_matrix.T @ features_matrix)) @ features_matrix.T @ y_train
error = mean_squared_error(x_train, y_train, w)
return w, error
def regularized_least_squares(x_train, y_train, M, regularization_lambda):
"""
:param x_train: ciąg treningowy wejśćia Nx1
:param y_train: ciąg treningowy wyjscia Nx1
:param M: rzad wielomianu
:param regularization_lambda: parametr regularyzacji
:return: funkcja zwraca krotkę (w,err), gdzie w są parametrami dopasowanego
wielomianu zgodnie z kryterium z regularyzacją l2, a err to błąd
średniokwadratowy dopasowania
"""
features_matrix = design_matrix(x_train, M)
w = np.linalg.inv((features_matrix.T @ features_matrix + regularization_lambda * np.eye(features_matrix.shape[1]))) @ features_matrix.T @ y_train
error = mean_squared_error(x_train, y_train, w)
return w, error
def model_selection(x_train, y_train, x_val, y_val, M_values):
"""
:param x_train: ciąg treningowy wejśćia Nx1
:param y_train: ciąg treningowy wyjscia Nx1
:param x_val: ciąg walidacyjny wejśćia Nx1
:param y_val: ciąg walidacyjny wyjscia Nx1
:param M_values: tablica stopni wielomianu, które mają byc sprawdzone
:return: funkcja zwraca krotkę (w,train_err,val_err), gdzie w są parametrami
modelu, ktory najlepiej generalizuje dane, tj. daje najmniejszy błąd na
ciągu walidacyjnym, train_err i val_err to błędy na sredniokwadratowe na
ciągach treningowym i walidacyjnym
"""
results = []
errors = []
for M in M_values:
w_train, error_train = least_squares(x_train, y_train, M)
error_val = mean_squared_error(x_val, y_val, w_train)
errors.append(error_val)
results.append((w_train, error_train, error_val))
return results[np.argmin(errors)]
def regularized_model_selection(x_train, y_train, x_val, y_val, M, lambda_values):
"""
:param x_train: ciąg treningowy wejśćia Nx1
:param y_train: ciąg treningowy wyjscia Nx1
:param x_val: ciąg walidacyjny wejśćia Nx1
:param y_val: ciąg walidacyjny wyjscia Nx1
:param M: stopień wielomianu
:param lambda_values: lista z wartościami różnych parametrów regularyzacji
:return: funkcja zwraca krotkę (w,train_err,val_err,regularization_lambda),
gdzie w są parametrami modelu, ktory najlepiej generalizuje dane, tj. daje
najmniejszy błąd na ciągu walidacyjnym. Wielomian dopasowany jest wg
kryterium z regularyzacją. train_err i val_err to błędy średniokwadratowe
na ciągach treningowym i walidacyjnym. regularization_lambda to najlepsza
wartość parametru regularyzacji
"""
results = []
errors = []
for reg_lambda in lambda_values:
w_train, error_train = regularized_least_squares(x_train, y_train, M, reg_lambda)
error_val = mean_squared_error(x_val, y_val, w_train)
errors.append(error_val)
results.append((w_train, error_train, error_val, reg_lambda))
return results[np.argmin(errors)]