当前位置:   article > 正文

Python实现线性回归(sklearn工具包、jupyter平台)

Python实现线性回归(sklearn工具包、jupyter平台)

目录

1.线性回归方程实现 

2.批量梯度下降

3.随机梯度下降

4.小批量梯度下降

5.三种策略的对比


算法推导过程在之前的文章中已经给出了求解方法,基于最小二乘法直接求解,但这并不是机器学习的思想,由此引入了梯度下降方法。

1.线性回归方程实现

  1. import numpy as np #导入基础包和一些设置
  2. import os
  3. %matplotlib inline
  4. import matplotlib
  5. import matplotlib.pyplot as plt
  6. plt.rcParams['axes.labelsize'] = 14
  7. plt.rcParams['xtick.labelsize'] = 12
  8. plt.rcParams['ytick.labelsize'] = 12
  9. import warnings
  10. warnings.filterwarnings('ignore')
  11. np.random.seed(42)
  1. import numpy as np #随便构造一个函数
  2. X = 2*np.random.rand(100,1)#0-2之间的数
  3. y = 4+ 3*X +np.random.randn(100,1)
  4. plt.plot(X,y,'b.') #将函数上的点表示出来
  5. plt.xlabel('X_1')
  6. plt.ylabel('y')
  7. plt.axis([0,2,0,15])
  8. plt.show()

根据以下公式(最小二乘法)求出最优的theta值

  1. X_b = np.c_[np.ones((100,1)),X] #插入一列1,方便矩阵运算(偏置项)
  2. theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y) #根据公式的方阵

实际上就是a和b的值(y=ax+b)

将求出的a、b值随便找两个点连成一条线就得到了这条回归方程, 只要我们有数据X和Y就能够得到回归方程。但没有体现机器学习的过程,而且矩阵也不一定都是可逆的,就需要其他的方法了

以上的方法sklearn可以直接调用

2.批量梯度下降

拿到数据后,想都不想第一步就是标准化数据,X-均值u让数据在0的范围内波动,再除上每个特征变量(X、Y)的标准差,使得X、Y两个特征尽可能保持相近的特征结果。比如年龄和薪资的关系,年龄的范围小(0-100),薪资的范围大(0-100w),二者相差过大会导致线性回归收敛过慢。因此除上标准差能够让年龄和薪资的范围差距缩小。

批量梯度下降: 得到的theta值和上面的最小二乘法一致

  1. eta = 0.1 #学习率
  2. n_iterations = 1000 #迭代次数
  3. m = 100 #所有样本数
  4. theta = np.random.randn(2,1) #任意给一个theta值
  5. for iteration in range(n_iterations):
  6. gradients = 2/m* X_b.T.dot(X_b.dot(theta)-y) #梯度下降公式
  7. theta = theta - eta*gradients #更新参数theta

学习率对结果的影响:

  1. theta_path_bgd = [] #用于存储theta的变化情况
  2. def plot_gradient_descent(theta,eta,theta_path = None):
  3. m = len(X_b)
  4. plt.plot(X,y,'b.')
  5. n_iterations = 1000
  6. for iteration in range(n_iterations):
  7. y_predict = X_new_b.dot(theta)
  8. plt.plot(X_new,y_predict,'b-')
  9. gradients = 2/m* X_b.T.dot(X_b.dot(theta)-y)
  10. theta = theta - eta*gradients
  11. if theta_path is not None:
  12. theta_path.append(theta)
  13. plt.xlabel('X_1')
  14. plt.axis([0,2,0,15])
  15. plt.title('eta = {}'.format(eta))
  1. theta = np.random.randn(2,1)
  2. #学习率为0.02、0.1、0.5的不同情况
  3. plt.figure(figsize=(10,4))
  4. plt.subplot(131)
  5. plot_gradient_descent(theta,eta = 0.02)
  6. plt.subplot(132)
  7. plot_gradient_descent(theta,eta = 0.1,theta_path=theta_path_bgd)
  8. plt.subplot(133)
  9. plot_gradient_descent(theta,eta = 0.5)
  10. plt.show()

可以看出学习率小时,经过了很多步才达到了理想的位置,学习率为0.1时就快一些,而学习率为0.5时直接偏离了正确结果,因此学习率宁愿小也不要过大

3.随机梯度下降

随机的选择一个样本进行梯度下降。我们指定一个衰减策略:在梯度下降的过程中,我们让开始的收益率最大,在逐渐靠近最优的过程中,收益率逐渐减少。意思就是一开始我们让步长大一些,快速靠近最低的损失值,越靠近最低损失值,我们就越需要更小的步长去靠近它,以防错过最低损失值。

  1. theta_path_sgd=[]
  2. m = len(X_b)
  3. np.random.seed(42)
  4. n_epochs = 50
  5. t0 = 5 #分子
  6. t1 = 50 #分母
  7. def learning_schedule(t):
  8. return t0/(t1+t) #迭代次数越大,就让学习率越小
  9. theta = np.random.randn(2,1)
  10. for epoch in range(n_epochs): #迭代50次
  11. for i in range(m): #每次都遍历每个样本
  12. if epoch < 10 and i<10: #只记录前10个样本
  13. y_predict = X_new_b.dot(theta)
  14. plt.plot(X_new,y_predict,'r-')
  15. random_index = np.random.randint(m) #随机从m个样本中抽出一个样本
  16. xi = X_b[random_index:random_index+1] #取当前这份数据
  17. yi = y[random_index:random_index+1]
  18. gradients = 2* xi.T.dot(xi.dot(theta)-yi) #梯度下降
  19. eta = learning_schedule(epoch*m+i)
  20. theta = theta-eta*gradients #更新参数
  21. theta_path_sgd.append(theta) #记录参数
  22. plt.plot(X,y,'b.')
  23. plt.axis([0,2,0,15])
  24. plt.show()

每次重新执行时,直线都不一样,因为每个样本的差异都不一样,因此有些抖动是正常的。

4.小批量梯度下降

随机选不靠谱,全部选又太慢。因此采用小批量梯度下降(minibatch)。

  1. theta_path_mgd=[]
  2. n_epochs = 50
  3. minibatch = 16
  4. theta = np.random.randn(2,1)
  5. t0, t1 = 200, 1000
  6. def learning_schedule(t):
  7. return t0 / (t + t1)
  8. np.random.seed(42)
  9. t = 0
  10. for epoch in range(n_epochs):
  11. shuffled_indices = np.random.permutation(m) #shuffled洗牌操作,防止获取同一批数据
  12. X_b_shuffled = X_b[shuffled_indices]
  13. y_shuffled = y[shuffled_indices]
  14. for i in range(0,m,minibatch):
  15. t+=1
  16. xi = X_b_shuffled[i:i+minibatch] #获取一部分的样本
  17. yi = y_shuffled[i:i+minibatch]
  18. gradients = 2/minibatch* xi.T.dot(xi.dot(theta)-yi)
  19. eta = learning_schedule(t)
  20. theta = theta-eta*gradients
  21. theta_path_mgd.append(theta)

得到的theta值:

5.三种策略的对比

  1. plt.figure(figsize=(12,6))
  2. plt.plot(theta_path_sgd[:,0],theta_path_sgd[:,1],'r-s',linewidth=1,label='SGD')
  3. plt.plot(theta_path_mgd[:,0],theta_path_mgd[:,1],'g-+',linewidth=2,label='MINIGD')
  4. plt.plot(theta_path_bgd[:,0],theta_
  5. plt.axis([3.5,4.5,2.0,4.0])
  6. plt.show()

蓝色的为批量下降,可以看出直接奔着最优解去了。绿色为小批量下降,围绕着批量下降波动。红色的为随机下降,震荡明显,受个体样本影响大。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/963001?site
推荐阅读
相关标签
  

闽ICP备14008679号