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
| class PolynomialRegession: def generatePolynomialFeatures(self, X, degree): self.degree = degree if degree == 0: return np.ones_like(X) n = X.shape[1] ans = np.array(X) if n > 1: for i in range(n): ans = np.hstack([ans, (X[:, i] ** degree).reshape(-1,1)]) for j in range(i+1, n): for k in range(1, degree): ans = np.hstack([ans, (X[:, i] ** k * X[:, j] ** (degree - k)).reshape(-1,1)]) else: for k in range(2, degree + 1): ans = np.hstack([ans, X ** k])
return np.hstack([ans, np.ones(ans.shape[0]).reshape([-1, 1])]) def standardization(self, X): tmp = X[:, :-1] return np.hstack([(tmp - np.mean(tmp, axis=0)) / np.std(tmp, axis = 0), np.ones([len(X), 1])]) def f(self, X_b, y, theta): return np.mean((X_b @ theta - y) ** 2)
def df(self, X_b, y, theta): return X_b.T @(X_b @ theta - y) * 2 / len(y)
def gd(self, X_b, y, theta, eta = 0.01, n_iters = 1e4, epsilon = 1e-6, plot_process = True): i_iter = 0
while i_iter < n_iters: if ((plot_process and (i_iter + 1) % 1000 == 0) and (i_iter + 1) <= 10000) or (i_iter + 1) == n_iters: display.clear_output(wait=True) plt.scatter(x, y1) plt.plot(x, (X_b @ theta).reshape(x.shape), c="green", label = 'predict') plt.plot(x, y2, c="red", label = 'truth') plt.legend() plt.title("degree = " + str(self.degree)) plt.show() plt.pause(0.5)
gradient = self.df(X_b, y, theta) last_theta = theta theta = theta - eta * gradient if abs(self.f(X_b, y, last_theta) - self.f(X_b, y, theta)) < epsilon: break i_iter += 1
return theta def fit(self, X, y, degree, eta = 1e-4, n_iters = 1e4, epsilon = 1e-6, plot_process = True): self.X_b = self.generatePolynomialFeatures(X, degree) self.X_b = self.standardization(self.X_b) initial_theta = np.zeros_like(self.X_b[1]) self.theta = self.gd(self.X_b, y, initial_theta, eta=eta, n_iters=n_iters, epsilon=epsilon, plot_process=plot_process) self.coefficient = self.theta[:-1] self.intercept = self.theta[-1] def predict(self, X): return self.standardization(self.generatePolynomialFeatures(X, self.degree) @ self.theta) def score(self, X, y): return np.mean((predict(X) - y) ** 2)
|