3、线性回归(解析法和梯度下降法)

mac2025-04-10  4

import random as rd import matplotlib.pyplot as plt import functools import math import numpy as np def sample_generate(n, low, sup, w, e): X = [[(sup-low) * rd.random() + low if j < len(w)-1 else 1 for j in range(len(w))] for i in range(n)] Y = [sum([w[j]*X[i][j] for j in range(len(w))])+e*(rd.random()-0.5) for i in range(n)] return X,Y def inv_calculate(X, Y): n = len(X) X = np.mat(X) Y = np.mat([[Y[i]] for i in range(len(Y))]) w = np.linalg.inv(X.T*X)*X.T*Y w = w.tolist() return [w[i][0] for i in range(len(w))] def LR_2_plot(X, Y, k, b): X = [X[i][0] for i in range(len(X))] x0, x1 = min(X),max(X) y0, y1 = k*x0+b, k*x1+b #点、线展示 plt.scatter(X, Y) plt.plot([x0,x1], [y0,y1], color = 'r') plt.show() def f(w, X, Y): return (w.T*X.T*X*w - 2*Y.T*X*w)[0,0] def mod(dw): return math.sqrt(sum([dw[i,0]*dw[i,0] for i in range(dw.size)])) # r为放缩尺度, step_min为最小步长 def Gradient(X, Y, r = 0.8, step_min = 0.00001): d = len(X[0]) X = np.mat(X) Y = np.mat([[Y[i]] for i in range(len(Y))]) w = [[0] for i in range(d)] w = np.mat(w) # 先采用放缩法确定寻优区间 while True: left = 0 right = 1 dw = -X.T * X * w + X.T * Y while f(w+right*dw, X, Y) < f(w, X, Y): right = right*(2-r) mid1 = left*2/3 + right/3 mid2 = left/3 + right*2/3 while abs(left - right)*mod(dw) > step_min: if f(w+mid1*dw, X, Y) < f(w+mid2*dw, X, Y): right = mid2 else: left = mid1 mid1 = left * 2 / 3 + right / 3 mid2 = left / 3 + right * 2 / 3 if left*mod(dw) < step_min: break w = w + left * dw # 由二分法确定寻优步长 w = w.tolist() return [w[i][0] for i in range(len(w))] if __name__ == "__main__": # y = wTx X, Y = sample_generate(n = 100, low = 10, sup = 20, w = [2,3,4], e = 1) # 解析解,求逆得到, w = (X.T*X)-1 * X.T * Y # w = inv_calculate(X,Y) # print("\nk: ", w[0]) # print("\nb: ", w[1]) # LR_2_plot(X, Y, w[0], w[1]) # 梯度下降法 w = Gradient(X, Y) print("\nw: ", w) # print("\nk: ", w[0]) # print("\nb: ", w[1]) # LR_2_plot(X, Y, w[0], w[1])

 

最新回复(0)