线性回归中梯度下降法的向量化
将梯度式写为
此处,X0(i)== 1。
若将上式转置,则可分解为
或者直接写为下式:
由此,可对我们之前的代码进行修改,如下:
def dJ(theta,X_b,y):
# res = np.empty(len(theta)) # 对每个 theta 求导,所以开辟 len(theta) 个空间
# res[0] = np.sum(X_b.dot(theta) - y) #矩阵第 0 行
# for i in range(1,len(theta)):
# res[i] = (X_b.dot(theta) - y).dot(X_b[:,1]) #矩阵第 1-最后 行
# return res * 2 / len(X_b)
return X_b.T.dot(X_b.dot(theta) - y) * 2. / len(X_b)
添加和之前一样的波士顿房价数据,对比正规方程式和梯度下降法的预测准确度。
若使用正规方程式
from machine_learning.playML.LinearRegression1 import LinearRegression
lin_reg1 = LinearRegression()
%time lin_reg1.fit_normal(X_train,y_train)
lin_reg1.score(X_test,y_test)
可得如下准确度:
0.8129794056212729
使用梯度下降法
lin_reg2 = LinearRegression()
lin_reg2.fit_gd(X_train,y_train)
d:\python\lib\site-packages\numpy\core\fromnumeric.py:90: RuntimeWarning: overflow encountered in reduce
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
E:\pycharm\word\machine_learning\playML\LinearRegression1.py:32: RuntimeWarning: overflow encountered in square
return np.sum((y - X_b.dot(theta)) ** 2) / len(y)
E:\pycharm\word\machine_learning\playML\LinearRegression1.py:53: RuntimeWarning: invalid value encountered in double_scalars
if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
LinearRegression()
可看到,传入 X_train,y_train 两个参数,程序会报错,这时候需要修改其他默认参数。
通过修改 eta 的值
lin_reg2.fit_gd(X_train,y_train,eta=0.000001)
26LinearRegression()27lin_reg2.score(X_test,y_test)
0.27586818724477224
得到只有 0.2……的准确度,我们再试着增大 n_iters 的值
lin_reg2.fit_gd(X_train,y_train,eta=0.000001,n_iters=1e6)
得到了 0.75 的准确度。
lin_reg2.score(X_test,y_test)
0.7542932581943915
准确度比改变参数之前提高了,但是还是比使用正规方程式低。
数据标准化
我们可以通过在梯度下降法前进行数据归一化来让准确度提高到使用正规方程式的准确度,步骤如下:
from sklearn.preprocessing import StandardScaler
standardScaler = StandardScaler()
standardScaler.fit(X_train)
X_train_standard = standardScaler.transform(X_train)
lin_reg3 = LinearRegression()
%time lin_reg3.fit_gd(X_train_standard,y_train)
X_test_standard = standardScaler.transform(X_test)
lin_reg3.score(X_test_standard,y_test)
即可得到如下结果:
0.8129873310487505
总结:使用梯度下降法比正规方程式速度快,数据量越大,速度优势越明显。