Python机器学习实战_Logistic-Regression(随机梯度上升)
上次写到了梯度上升,这次接着看下所谓的随机梯度上升。
随机梯度上升与梯度上升相比,前者是按照每个样本的梯度进行迭代的,
而后者是按照每次迭代的梯度计算的
所以,如果后者是迭代500次的话,相当于比前者多了500倍的运算量.
不废话了,直接上代码.
#定义随机梯度上升的函数
def stocGradAscent0(dataMatrix, classLabels, iters = 100):
m,n = dataMatrix.shape
alpha = 0.01 #设置在0.3是,有较好的准确率
weights = np.ones(n)
for i in range(iters):#这里是对每个样本的梯度进行计算得到最终的回归系数的
h = sigmoid(sum(dataMatrix[i] * weights)) #与梯度下降不同之处
error = classLabels[i] - h
weights = weights + alpha * error * dataMatrix[i]
return weights
所以,理论上来讲,不管在上面计算的结果weights外面再嵌套多少个循环,回归系数永远是不变的。
#计算每次嵌套循环的回归系数结果
def get_iter_coef_sga(iters=100, coefs=3):
coefMatrix = np.ones((iters, coefs))
for i in range(iters):
weights = stocGradAscent0(np.array(dataMat), labelMat)
coefMatrix[i, :] = np.array(weights).reshape((1,3))
return coefMatrix
weights_sga0_coef = get_iter_coef_sga(100,3)
#可视化每个迭代后的结果(同样可以用在上一张的梯度上升500次迭代的结果中)
def plot_iter(mat):
f, ax = plt.subplots(figsize = (10,7), nrows = mat.shape[1])
for i in range(3):
ax[i].plot(mat[:, i])
ax[i].set_title('coef' + str(i))
如图,发现跟预期的一样。
那我想看根据每个样本的梯度计算100次(这里只有100个样本)的回归是怎么变化的,怎么实现呢?
只需要在随机梯度上升的算法上稍微改造下,返回每个样本的迭代结果就行了。
def get_sample_iter_sga0(dataMatrix, classLabels, iters = 100):
m,n = dataMatrix.shape
alpha = 0.01 #设置在0.3是,有较好的准确率
coefMatrix = np.ones((iters, n))
weights = np.ones(n)
for i in range(iters):
h = sigmoid(sum(dataMatrix[i] * weights)) #与梯度下降不同之处
error = classLabels[i] - h
weights = weights + alpha * error * dataMatrix[i]
coefMatrix[i,:] = weights
return coefMatrix
plot_iter(weights_sga0_coef_sample)
所以,利用随机梯度下降函数stocGradAscent0计算的结果,应该与coefMatrix结果集的最优一个是一样的
#梯度上升结果
weights_sga0 = stocGradAscent0(np.array(dataMat), labelMat, iters = 100)
print weights_sga0
array([ 1.01702007, 0.85914348, -0.36579921])
每个梯度计算的结果集
weights_sga0_coef_sample = get_sample_iter_sga0(np.array(dataMat), labelMat, iters = 100)
print weights_sga0_coef_sample[-7:,:]
array([[ 1.0061018 , 0.881096 , -0.33645573],
[ 1.0111106 , 0.87769103, -0.33034234],
[ 1.0142936 , 0.87984905, -0.32220448],
[ 1.0128275 , 0.87873284, -0.3378827 ],
[ 1.02002151, 0.86313055, -0.33684941],
[ 1.01718876, 0.85919696, -0.36331297],
[ 1.01702007, 0.85914348, -0.36579921]])
#画出根据每个样本的梯度计算出的每次迭代的回归系数
plot_iter(weights_sga0_coef_sample)
根据图看的出来其实回归系数还没有完全收敛,所以最终预测的准确性肯定没有梯度下降的好,但是随机的运算时间只是梯度上升的1/500