-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoverfitting.py
More file actions
170 lines (129 loc) · 7.59 KB
/
overfitting.py
File metadata and controls
170 lines (129 loc) · 7.59 KB
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_validate
from sklearn.model_selection import KFold
from sklearn.model_selection import LeaveOneOut
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
from sklearn.model_selection import learning_curve
import matplotlib.pyplot as plt
import seaborn as sns
RANDOM_SEED = 0
## creiamo una funzione per valutare il modello
def evaluate(model, dataset) -> None:
x, y = dataset
y_pred = model.predict(x)
print(f"MSE: {mean_squared_error(y, y_pred):.3f}")
print(f"R2: {r2_score(y, y_pred):.3f}")
if __name__ == "__main__":
#usiamo make regression usando un dataset che causa un overfitting
x ,y = make_regression(
n_samples = 100,
n_features= 100,
n_informative= 10,
n_targets= 1,
random_state= RANDOM_SEED
)
print(x.shape, y.shape)
#partiamo dalla tecnica hold out, dividendo il dataset in train e test
#QUINDI QUESTO COMANDO DIVIDE IL DATASET CON UNA PERCENTUALE CHE DECIDIAMO NOI
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state = RANDOM_SEED) #0.3 è la percentuale di dati che vogliamo usare per il testbuon numero per un dataset medio
ss = StandardScaler() #standard scaler è una tecnica di normalizzazione che trasforma i dati in modo che abbiano media 0 e deviazione standard 1
x_train = ss.fit_transform(x_train) #fit trasforma i dati in modo
x_test = ss.transform(x_test) #transform trasforma i dati in modo che abbiano media 0 e deviazione standard 1
#TUTTI I DATI CHE PASSIAMO AL NOSTRO MODELLO DEVONO AVERE LA STESSA TRANSFORMAZIONE QUINDI SPLITIAMO IL DS MA LI TRASFORMIAMO NELLO STESSO MODO
# ora addestriamo il modello con il set di train
lr = LinearRegression()
lr.fit(x_train, y_train)
evaluate(lr, (x_train, y_train)) #valutiamo il modello con il set di train
evaluate(lr, (x_test, y_test)) #valutiamo il modello con il set di test
#CROSS VALIDATION
score = cross_val_score(lr, x, y, cv=5, scoring="r2") #cross val score è una tecnica di valutazione che divide il dataset
# in k parti e addestra il modello su k-1 parti e lo valuta sulla parte rimanente,
# ripetendo questo processo k volte
cv_result = cross_validate(lr, x, y, cv=5, return_train_score= True) #cross validate è una tecnica di valutazione che divide il dataset in k parti e addestra il modello su k-1 parti e lo valuta sulla parte rimanente, ripetendo questo processo k volte, ma permette di valutare più metriche contemporaneamente
print(cv_result) # fit_time è il tempo impiegato per addestrare il modello,
# score_time è il tempo impiegato per valutare il modello,
# test_score è il punteggio ottenuto sulla parte di test,
# train_score è il punteggio ottenuto sulla parte di train
kf = KFold(n_splits = 5, shuffle = True, random_state = RANDOM_SEED) # k fold è una tecnica di valutazione che divide il dataset in k parti
# addestra il modello su k-1 parti e lo valuta sulla parte rimanente,
# ripetendo questo processo k volte, ma permette di valutare più metriche contemporaneamente,
# shuffle serve per mescolare i dati prima di dividerli in k parti
kf.get_n_splits(x)
train_score = []
test_score = []
for train_index, test_index in kf.split(x): #iterare il processo di divisone per fare il cross
x_train, x_test = x[train_index], x[test_index]
y_train, y_test = y[train_index], y[test_index]
ss = StandardScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.transform(x_test)
lr.fit(x_train, y_train)
r2_train = r2_score(y_train, lr.predict(x_train))
r2_test = r2_score(y_test, lr.predict(x_test))
train_score.append(r2_train)
test_score.append(r2_test)
score = {
"train_score": train_score,
"test_score": test_score
}
print (score)
# vediamo un altra variande eseguiamo l'addestramento in tutto il data set tranne una parte tenuta da partye per il test
# utile quando abbiamo pochi esempi
loo = LeaveOneOut() # leave one out è una tecnica di valutazione che divide il dataset in n parti,
# dove n è il numero di esempi, addestra il modello su n-1 parti e lo valuta sulla parte rimanente,
# ripetendo questo processo n volte
loo.get_n_splits(x) # ci da un numero di split pari al numero di esempi, quindi se abbiamo 100 esempi avremo 100 split,
# ogni split sarà composto da 99 esempi per il train e 1 esempio per il test
train_score = []
test_score = []
for train_index, test_index in kf.split(x): #iterare il processo di divisone per fare il cross
x_train, x_test = x[train_index], x[test_index]
y_train, y_test = y[train_index], y[test_index]
ss = StandardScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.transform(x_test)
lr.fit(x_train, y_train)
# pochi esempi per r2 quindi usiamo mean swaure error
# r2_train = r2_score(y_train, lr.predict(x_train))
# r2_test = r2_score(y_test, lr.predict(x_test))
MSE_train = mean_squared_error(y_train, lr.predict(x_train))
MSE_test = mean_squared_error(y_test, lr.predict(x_test))
train_score.append(MSE_train)
test_score.append(MSE_test)
# come affrontare l'overfitting
# riprendiamo hold out
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state = RANDOM_SEED)
ss = StandardScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.transform(x_test)
# ordinary least square regression
lr.fit(x_train, y_train)
# l2
ridge = Ridge(alpha = 1.0) # alpha è il parametro di regolarizzazione, più è alto più il modello sarà regolarizzato, quindi meno complesso
ridge.fit(x_train, y_train)
print("dopo regolazione l2: ")
evaluate(ridge, (x_train, y_train))
evaluate(ridge, (x_test, y_test))
# l1
lasso = Lasso(alpha = 1.0) # alpha è il parametro di
lasso.fit(x_train, y_train)
print("dopo regolazione l1: ")
evaluate(lasso, (x_train, y_train))
evaluate(lasso, (x_test, y_test))
# esisiste un terzo metodo che bilancia l1 e l2 che si chiama elastic net
elastic_net = ElasticNet(alpha = 1.0, l1_ratio = 0.5) # alpha è il parametro di regolarizzazione, più è alto più il modello sarà regolarizzato,
# quindi meno complesso, l1_ratio è il parametro che bilancia l1 e l2,
# se è 0.5 significa che bilancia l1 e l2 in modo uguale
elastic_net.fit(x_train, y_train)
print("dopo regolazione elastic net: ")
evaluate(elastic_net, (x_train, y_train))
evaluate(elastic_net, (x_test, y_test))
print("tutto ok")