在线性回归中使用梯度下降法每次都要更新都需要遍历所有数据,当数据量大的时候耗时非常大。
于是提出了随机梯度下降法,通过一个随机选取的数据来获取“梯度”,进行更新。
与传统梯度下降法的不同在于,随机梯度的步长变化方向不是固定的,如下图所示,不一定沿着最小方向前进。随机梯度下降法
在这种情况中eta,即学习率,不能是一个固定值。因为当随机梯度接近最小值没到最小值时,固定的eta可能会使最小值没有更小反而更大了,所以eta要随着随机梯度下降法迭代次数的增加而 减小。随机梯度下降法
实现过程如下:

#自定义虚拟数据集
import numpy as np
import matplotlib.pyplot as plt
m=100000 #m个样本
x=np.random.normal(size=m)
X=x.reshape(-1,1)
y=4.*x+3.+np.random.normal(0,3,size=m)

def J(theta,X_b,y):
	try:
		return np.sum((y-X_b.dot(theta)**2)/len(X_b)
	except:
		return float('inf')
def dJ_sgd(theta,X_b_i,y_i):
	return X_b_i.T.dot(X_b_i.dot(theta)-y_i)*2.
def sgd(X_b,y,initial_theta,n_iters):
	t0=5
	t1=50
	def learning_rate(t):
		retrun t0/(t+t1)
	theta=initial_theta
	for cur_iter in range(n_iters):
		rand_i=np.random.randint(len(X_b))
		gradient=dJ_sgd(theta,X_b[rand_i],y[rand_i])
		theta=theta-learning_rate(cur_iter)*gradient
		return theta

%%time
X_b=np.hstack([np.ones((len(X),1)),X])
initial_theta=np.zeros(X_b.shape[1])
theta=sgd(X_b,y,initial_theta,n_iters=len(X_b)//3)

运行结果:
随机梯度下降法
可以看出随机梯度下降的准确率和梯度下降差不多,但是时间大大减少了。实际上这里的时间花费只有1/3m。
在sklearn中使用随机梯度下降法

from sklearn.linear_model import SGDRegressor
sgd_reg=SGDRegressor()
%time sgd_reg.fit(x_train_standard,y_train)
sgd_reg.score(x_test_standard,y_test)

相关文章: