线性回归是很多机器学习机器学习算法的基础,所谓基础决定上层建筑,学好线性回归及其各种优化技巧,能为以后学习聚类乃至神经网络奠定坚实基础。我将从线性回归解析解,梯度下降,随机梯度下降,归一化,正则化等角度较为系统的为大家阐述线性回归及其各种优化策略,并给出部分Python代码,在阅读过程中大以下两种思想会贯穿读者始终:

1.很多策略都是TeadeOff的,在工作中根据自身追求的目标去合理调节。

2.有时不一定要追求全局最优解,只要找到一组解,worked就可以了。




一.解析解

假设你已经熟悉最小二乘法(可以去读我的上一篇深入浅出最小二乘法),目标函数为:



另一种表达:




我们要找最优解,即为上面损失函数值最小的解,多元线性函数中偏导数为0的点为驻点,但驻点不一定唯一,下面我用Hessian矩阵的正定性来证明上式的驻点是全局最优解。

对J损失函数求二阶导得:




自身和自身相乘一定是非负的,所以Hessian矩阵是半正定的,根据Hessian矩阵的正定性能够判断损失函数为凸函数,函数图像开口向上并有有极小值。所以对J求偏导,另导数为0的一组解就是使损失函数最小的解,我们得到:



下面是利用解析解得方式求得二元线性回归方程解得Python代码:

#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
__author__ = 'yasaka'
# 这里相当于是随机X维度X1,rand是随机均匀分布
X = 2 * np.random.rand(100, 1)
# 人为的设置真是的Y一列,np.random.randn(100, 1)是设置error,randn是标准正太分布
y = 4 + 3 * X + np.random.randn(100, 1)
# 整合X0和X1
X_b = np.c_[np.ones((100, 1)), X]
# 常规等式求解theta
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
print(theta_best)
# 创建测试集里面的X1
X_new = np.array([[0], [2]])
X_new_b = np.c_[(np.ones((2, 1))), X_new]
print(X_new_b)
y_predict = X_new_b.dot(theta_best)
print(y_predict)
// 做出函数图像和测试集点分布
plt.plot(X_new, y_predict, 'r-')
plt.plot(X, y, 'b.')
plt.axis([0, 2, 0, 15])


plt.show()


下图为我在pycharm中运行结果:



不足:上面利用公式求解里面对称阵是N维乘以N维的,复杂度是O的三次方,换句话说,就是如果你的特征数量翻倍,你的计算时间大致上要乘上2的三次方,8倍的慢。


二.梯度下降(BGD)


就好像我们有个人被随机空降到一座山上,他要想下山,最好的方法就是每次环顾一下四周,选择当前最陡的方向step,然后再环顾一下四周,选择最陡的方向step。。。,直到走到山底为止。这里的方向最陡就是我们的损失函数偏导数为零的方向,step指我们的学习率,学习率的大小决定下山的速度。

当step小的时候



当step大的时候:












数学推导如下:




求导:





在代码实现中有个小tip,当距离最优解很远时,我们希望学习率大些,加快学习速度,当距离最优解较近是我们希望减小学习率,避免来回震荡,下面是给出自适应超参数的Python代码:

#!/usr/bin/python

import numpy as np
__author__ = 'xuhaifeng'

X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
n_epochs = 500
t0, t1 = 5, 50  # 超参数
m = 100
def learning_schedule(t):
    return t0 / (t + t1)
theta = np.random.randn(2, 1)
for epoch in range(n_epochs):
    for i in range(m):
        random_index = np.random.randint(m)
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = 2*xi.T.dot(xi.dot(theta)-yi)
        learning_rate = learning_schedule(epoch*m + i)
        theta = theta - learning_rate * gradients


print(theta)

三.随机梯度下降(SGD)与Mini-batch SGD


随机梯度下降就是每次求梯度时只随机选择一条样本,这样大大减少了计算量,但是这次的方向很肯不是最好的。Mini-batch
SGD就是每次选取批量样本做梯度下降,如下图:


















    





























   







友情链接
ioDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信