以下是我使用随机梯度下降法实现的线性回归模型,但得到的拟合线并不是最佳的。我如何改进这一点?
import matplotlib.pyplot as pltfrom matplotlib import styleimport numpy as npstyle.use("fivethirtyeight")x=[[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]]y=[[3],[5],[9],[9],[11],[13],[16],[17],[19],[21]]X=np.array(x)Y=np.array(y)learning_rate=0.015m=1c=2gues=[]for i in range(len(x)): guess=m*x[i][0]+c error=guess-y[i][0] if error<0: m=m+abs(error)*x[i][0]*learning_rate c=c+abs(error)*learning_rate if error>0: m=m-abs(error)*x[i][0]*learning_rate c=c-abs(error)*learning_rate gues.append([guess])t=np.array(gues)plt.scatter(X,Y)plt.plot(X,t)plt.show()from sklearn.linear_model import LinearRegressionvar=LinearRegression()var.fit(X,Y)plt.scatter(X,Y)plt.plot(X,var.predict(X))plt.show()
由于我需要最小化误差,即(guess-y),对误差函数关于m
的偏导数得到x
,关于c
的偏导数得到常数。
回答:
您正在进行随机梯度下降,每个数据点都在评估拟合。因此,最终的m
和c
为您提供了拟合关系的参数。您绘制的线条是拟合线的“演变”。
这是我绘图的方式,并对您的代码进行了一些其他调整,以便理解您的做法:
import numpy as npimport matplotlib.pyplot as pltX = np.array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])Y = np.array([ 3, 5, 9, 9, 11, 13, 16, 17, 19, 21])learning_rate = 0.015m = 1c = 2gues = []for xi, yi in zip(X, Y): guess = m * xi + c error = guess - yi m = m - error * xi * learning_rate c = c - error * learning_rate gues.append(guess)t = np.array(gues)# 绘制模型线。y_hat = m * X + cplt.figure(figsize=(10,5))plt.plot(X, y_hat, c='red')# 绘制数据点。plt.scatter(X, Y)# 绘制猜测值的演变。plt.plot(X, t)plt.show()
我在代码中做的主要修改包括:通过zip
函数遍历X
和Y
,这样您就可以在不进行索引的情况下使用它们。我还将它们简化为一维数组。如果您直接使用梯度,而不使用abs
,则不需要针对正负情况使用不同的路径。