-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLinearReg.py
More file actions
66 lines (58 loc) · 3 KB
/
LinearReg.py
File metadata and controls
66 lines (58 loc) · 3 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
import numpy as np
class LinearRegression:
def __init__(self, mae_metric=False):
"""
@param mae_metrics: В случае True необходимо следить за
метрикой MAE во время обучения, иначе - за метрикой MSE
"""
self.metric = self.calc_mse_metric if not mae_metric else self.calc_mae_metric
def calc_mae_metric(self, preds, y):
"""
@param preds: предсказания модели
@param y: истиные значения
@return mae: значение MAE
"""
return sum(sum(abs(preds - y))) / (y.shape[0])
def calc_mse_metric(self, preds, y):
"""
@param preds: предсказания модели
@param y: истиные значения
@return mse: значение MSE
"""
return sum(sum((preds - y) ** 2)) / (y.shape[0])
def init_weights(self, input_size, output_size):
"""
Инициализирует параметры модели
W - матрица размерности (input_size, output_size)
инициализируется рандомными числами из
нормального распределения со средним 0 и стандартным отклонением 0.01
b - вектор размерности (1, output_size)
инициализируется нулями
"""
np.random.seed(42)
self.W = np.random.normal(loc=0.0, scale=0.01, size=(input_size, output_size))
self.b = np.zeros((output_size))
self.W_b = np.vstack((self.W, self.b))
def fit(self, X, y, num_epochs=1000, lr=0.001):
"""
Обучение модели линейной регрессии методом градиентного спуска
@param X: размерности (num_samples, input_shape)
@param y: размерности (num_samples, output_shape)
@param num_epochs: количество итераций градиентного спуска
@param lr: шаг градиентного спуска
@return metrics: вектор значений метрики на каждом шаге градиентного
спуска. В случае mae_metric==True вычисляется метрика MAE
иначе MSE
"""
self.init_weights(X.shape[1], y.shape[1])
metrics = []
for _ in range(num_epochs):
preds = self.predict(X)
W_b_grad = 2 * (np.hstack((X, np.ones((len(X), 1)))).T @ (
(np.hstack((X, np.ones((len(X), 1)))) @ self.W_b) - y)) \
/ (y.shape[0])
self.W_b -= lr * W_b_grad
metrics.append(self.metric(preds, y))
return metrics
def predict(self, X):
return np.hstack((X, np.ones((len(X), 1)))) @ self.W_b