|
| 1 | +import numpy as np |
| 2 | +import csv |
| 3 | +import matplotlib.pyplot as plt |
| 4 | + |
| 5 | +def mse(y_true, y_pred): |
| 6 | + return np.mean((y_true - y_pred) ** 2) |
| 7 | + |
| 8 | +def r2_score(y_true, y_pred): |
| 9 | + ss_total = np.sum((y_true - np.mean(y_true)) ** 2) |
| 10 | + ss_res = np.sum((y_true - y_pred) ** 2) |
| 11 | + return 1 - ss_res / ss_total |
| 12 | + |
| 13 | +def save_csv(filename, X, y_true, y_pred): |
| 14 | + with open(filename, mode='w', newline='') as file: |
| 15 | + writer = csv.writer(file) |
| 16 | + writer.writerow(["X", "True Y", "Predicted Y"]) |
| 17 | + for x, y, y_hat in zip(X, y_true, y_pred): |
| 18 | + writer.writerow([x[0], y, y_hat]) |
| 19 | + |
| 20 | +class LinearRegression: |
| 21 | + def __init__(self): |
| 22 | + self.weights = None |
| 23 | + |
| 24 | + def fit(self, X, y): |
| 25 | + X_bias = np.c_[np.ones((X.shape[0], 1)), X] |
| 26 | + self.weights = np.linalg.pinv(X_bias.T @ X_bias) @ X_bias.T @ y |
| 27 | + |
| 28 | + def predict(self, X): |
| 29 | + X_bias = np.c_[np.ones((X.shape[0], 1)), X] |
| 30 | + return X_bias @ self.weights |
| 31 | + |
| 32 | +class RidgeRegression: |
| 33 | + def __init__(self, alpha=1.0): |
| 34 | + self.alpha = alpha |
| 35 | + self.weights = None |
| 36 | + |
| 37 | + def fit(self, X, y): |
| 38 | + X_bias = np.c_[np.ones((X.shape[0], 1)), X] |
| 39 | + n = X_bias.shape[1] |
| 40 | + I = np.eye(n) |
| 41 | + I[0, 0] = 0 |
| 42 | + self.weights = np.linalg.inv(X_bias.T @ X_bias + self.alpha * I) @ X_bias.T @ y |
| 43 | + |
| 44 | + def predict(self, X): |
| 45 | + X_bias = np.c_[np.ones((X.shape[0], 1)), X] |
| 46 | + return X_bias @ self.weights |
| 47 | + |
| 48 | +class LassoRegression: |
| 49 | + def __init__(self, alpha=1.0, max_iter=1000, tol=1e-4): |
| 50 | + self.alpha = alpha |
| 51 | + self.max_iter = max_iter |
| 52 | + self.tol = tol |
| 53 | + self.weights = None |
| 54 | + |
| 55 | + def fit(self, X, y): |
| 56 | + X_bias = np.c_[np.ones((X.shape[0], 1)), X] |
| 57 | + n_samples, n_features = X_bias.shape |
| 58 | + self.weights = np.zeros(n_features) |
| 59 | + |
| 60 | + for _ in range(self.max_iter): |
| 61 | + weights_old = self.weights.copy() |
| 62 | + for j in range(n_features): |
| 63 | + tmp = X_bias @ self.weights - X_bias[:, j] * self.weights[j] |
| 64 | + rho = np.dot(X_bias[:, j], y - tmp) |
| 65 | + if j == 0: |
| 66 | + self.weights[j] = rho / np.sum(X_bias[:, j] ** 2) |
| 67 | + else: |
| 68 | + if rho < -self.alpha / 2: |
| 69 | + self.weights[j] = (rho + self.alpha / 2) / np.sum(X_bias[:, j] ** 2) |
| 70 | + elif rho > self.alpha / 2: |
| 71 | + self.weights[j] = (rho - self.alpha / 2) / np.sum(X_bias[:, j] ** 2) |
| 72 | + else: |
| 73 | + self.weights[j] = 0 |
| 74 | + if np.linalg.norm(self.weights - weights_old, ord=1) < self.tol: |
| 75 | + break |
| 76 | + |
| 77 | + def predict(self, X): |
| 78 | + X_bias = np.c_[np.ones((X.shape[0], 1)), X] |
| 79 | + return X_bias @ self.weights |
| 80 | + |
| 81 | +class KernelRidgeRegression: |
| 82 | + def __init__(self, alpha=1.0, gamma=0.1): |
| 83 | + self.alpha = alpha |
| 84 | + self.gamma = gamma |
| 85 | + self.X_train = None |
| 86 | + self.alpha_vec = None |
| 87 | + |
| 88 | + def _rbf_kernel(self, X1, X2): |
| 89 | + dists = np.sum((X1[:, np.newaxis] - X2[np.newaxis, :]) ** 2, axis=2) |
| 90 | + return np.exp(-self.gamma * dists) |
| 91 | + |
| 92 | + def fit(self, X, y): |
| 93 | + self.X_train = X |
| 94 | + K = self._rbf_kernel(X, X) |
| 95 | + n = K.shape[0] |
| 96 | + self.alpha_vec = np.linalg.inv(K + self.alpha * np.eye(n)) @ y |
| 97 | + |
| 98 | + def predict(self, X): |
| 99 | + K = self._rbf_kernel(X, self.X_train) |
| 100 | + return K @ self.alpha_vec |
| 101 | + |
| 102 | +if __name__ == "__main__": |
| 103 | + np.random.seed(42) |
| 104 | + X = 2 * np.random.rand(100, 1) |
| 105 | + y = 4 + 3 * X[:, 0] + np.random.randn(100) * 0.5 |
| 106 | + |
| 107 | + models = { |
| 108 | + "linear": LinearRegression(), |
| 109 | + "ridge": RidgeRegression(alpha=1.0), |
| 110 | + "lasso": LassoRegression(alpha=0.1), |
| 111 | + "kernel_ridge": KernelRidgeRegression(alpha=1.0, gamma=5.0) |
| 112 | + } |
| 113 | + |
| 114 | + for name, model in models.items(): |
| 115 | + model.fit(X, y) |
| 116 | + y_pred = model.predict(X) |
| 117 | + mse_val = mse(y, y_pred) |
| 118 | + r2_val = r2_score(y, y_pred) |
| 119 | + print(f"{name} -> MSE: {mse_val:.4f}, R2: {r2_val:.4f}") |
| 120 | + save_csv(f"predictions_{name}.csv", X, y, y_pred) |
0 commit comments