机器学习之线性回归和梯度下降算法
一般来说,我们根据机器学习的任务把不同的业务模型划分为四种基本问题。
回归问题,分类问题,聚类问题和降维问题。
回归问题 \ 都是在有监督条件下,根据已知的输入和输出,构建
分类问题 / 预测模型,对未知输出的输入给出大概率的输出
我们举个例子:
输入 输出
1 2
2 4
3 6
4 8
------- y = x * 2
5 ? -> 10
输出是一个连续值,回归问题。
我们再看一个例子:
输入 输出
1 1
2 0
3 1
4 0
5 1
6 0
------- 奇数->1,偶数->0
7 ? -> 1
输出是一个离散值,分类问题。
聚类问题:在无监督模式下,根据输入的特征划分族群。
降维问题:在无监督模式下,对输入特征进行取舍以降低维度。
输入 输出
x1 y1
x2 y2
…
xm ym
y = w0+w1x - 通过线性方程描述输出和输入之间的关系,已解决回归问题,这就是线性回归。
预测函数:y = w0+w1x
预测输出为:
x1 -> y1’=w0+w1x1
x2 -> y2’=w0+w1x2
…
xm->ym’=w0+w1xm
y1 y2 … ym : 实际输出
(y1 - y1’) ^ 2 : 单样本误差
总样本误差:
(y1−y1′)2+(y2−y2′)2+...+(ym−ym′)22=E\frac{(y1-y1') ^ 2 + ( y2-y2') ^ 2 + ... + (ym-ym') ^ 2}{2}
= E 2(y1−y1′)2+(y2−y2′)2+...+(ym−ym′)2=E
损失函数:E = Loss(w0, w1)
损失函数体现了总样本误差即损失值随着模型参数的变化而变化。回归问题的等价问题就是求损失函数的极小值,即是E达到极小值的w0和w1。
模型参数的迭代公式:
w0=w0−n∂E∂w0w0 = w0 - n \frac {∂E} {∂w0}w0=w0−n∂w0∂E
w1=w1−n∂E∂w1w1 = w1 - n \frac{∂E}{∂w1}w1=w1−n∂w1∂E
通过公式推导求微分,我们可以得到:
∂E / ∂w0 = 1/2 [2(y1-y1’)(-1) + 2(y2-y2’)(-1) + …]
= -[(y1-y1’) + (y2-y2’) + …]
∂E / ∂w1 = -[(y1-y1’)x1 + (y2-y2’)x2 + …]
# -*- coding: utf-8 -*- from __future__ import unicode_literals import numpy as np import matplotlib.pyplot as mp from mpl_toolkits.mplot3d import axes3d #已知输入 train_x = np.array([0.5, 0.6, 0.8, 1.1, 1.4]) #已知输出 train_y = np.array([5.0, 5.5, 6.0, 6.8, 7.0]) #迭代次数,以此计算梯度 n_epoches = 1000 #求反向梯度时取学习率,公式中的n,谨慎起见我们取0.01 lrate = 0.01 #epoches实际步数,losses记录每一步的误差 epoches, losses = [], [] #模型参数的初始值,追加的元素我们添加到列表的最后一个元素 w0, w1 = [1], [1] #我们做一个1到1000的循环 for epoch in range(1, n_epoches + 1): epoches.append(epoch) #误差等于实际输出减去预测输出求平方和再除以2 losses.append(((train_y - (w0[-1] + w1[-1] * train_x)) ** 2).sum() / 2) #我们把对应的模型参数和对应的值都打印在终端上 print('{:4}> w0={:.8f}, w1={:.8f}, loss={:.8f}'.format(epoches[-1], w0[-1], w1[-1], losses[-1])) #计算∂E / ∂w0的偏微分 d0 = -(train_y - (w0[-1] + w1[-1] * train_x)).sum() #计算∂E / ∂w1的偏微分 d1 = -((train_y - (w0[-1] + w1[-1] * train_x)) * train_x).sum() #模型参数迭代 w0.append(w0[-1] - lrate * d0) w1.append(w1[-1] - lrate * d1) #第1001个元素切掉 w0 = np.array(w0[:-1]) w1 = np.array(w1[:-1]) #间接索引,升序排列 sorted_indices = train_x.argsort() #x测试集,保证x是升序排列 test_x = train_x[sorted_indices] test_y = train_y[sorted_indices] #把test_x带入公式,可以得到预测输出 pred_test_y = w0[-1] + w1[-1] * test_x mp.figure('Linear Regression', facecolor='lightgray') mp.title('Linear Regression', fontsize=20) mp.xlabel('x', fontsize=14) mp.ylabel('y', fontsize=14) mp.tick_params(labelsize=10) mp.grid(linestyle=':') mp.scatter(train_x, train_y, marker='s', c='dodgerblue', alpha=0.5, s=80, label='Training') mp.legend() mp.show()
在上面的基础上我们再画一条测试图形
mp.scatter(test_x, test_y, marker='D',c='orangered', alpha=0.5, s=60,label='Testing')
我们可以得到这样的图形,因为我们用的数据集是一样的
mp.scatter(test_x, pred_test_y, c='orangered', alpha=0.5, s=80,label='Predicted')
如上图所示,两点间的距离就是损失值。
接下来我们把输出点连起来
mp.plot(test_x, pred_test_y, '--', c='limegreen', label='Regression', linewidth=1) mp.legend()
我们可以看到这条绿色的虚线,其实它就是一条直线,这就是回归线。
接下来,我们通过画图把模型参数,及损失值的收敛过程画出来。
mp.figure('Training Progress', facecolor='lightgray') #第一幅子图 mp.subplot(311) mp.title('Training Progress', fontsize=20) mp.ylabel('w0', fontsize=14) # x轴刻度 mp.gca().xaxis.set_major_locator( mp.MultipleLocator(100)) mp.tick_params(labelsize=10) mp.grid(linestyle=':') mp.plot(epoches, w0, c='dodgerblue', label='w0') mp.legend() #第二幅子图 mp.subplot(312) mp.ylabel('w1', fontsize=14) mp.gca().xaxis.set_major_locator(mp.MultipleLocator(100)) mp.tick_params(labelsize=10) mp.grid(linestyle=':') mp.plot(epoches, w1, c='limegreen', label='w1') mp.legend() #第三幅子图 mp.subplot(313) mp.xlabel('epoch', fontsize=14) mp.ylabel('loss', fontsize=14) mp.gca().xaxis.set_major_locator(mp.MultipleLocator(100)) mp.tick_params(labelsize=10) mp.grid(linestyle=':') mp.plot(epoches, losses, c='orangered', label='loss') mp.legend()
下面,我们把损失函数的曲面画出来。
#数据生成,w0取0-9,500个点,w1取0-3.5,500个点 grid_w0, grid_w1 = np.meshgrid(np.linspace(0, 9, 500), np.linspace(0, 3.5, 500)) #网格平面化 flat_w0, flat_w1 = grid_w0.ravel(), grid_w1.ravel() #flat_w0 + np.outer(train_x, flat_w1)得到预测值矩阵 #每个样本的预测值输出减去实际输出的差求平方,沿着纵向求和再除以2,算出损失值。 flat_loss = ((flat_w0 + np.outer(train_x, flat_w1) - train_y.reshape( -1, 1)) ** 2).sum(axis=0) / 2 #损失值和w0维度保持一致 grid_loss = flat_loss.reshape(grid_w0.shape) mp.figure('Loss Function') ax = mp.gca(projection='3d') mp.title('Loss Function', fontsize=20) ax.set_xlabel('w0', fontsize=14) ax.set_ylabel('w1', fontsize=14) ax.set_zlabel('loss', fontsize=14) ax.plot_surface(grid_w0, grid_w1, grid_loss,rstride=10, cstride=10, cmap='jet') ax.plot(w0, w1, losses, 'o-', c='orangered',label='BGD') mp.legend(loc='lower left')
我们用二维图看下梯度下降
mp.figure('Batch Gradient Desent') mp.title('Batch Gradient Desent', fontsize=20) mp.xlabel('w0', fontsize=14) mp.ylabel('w1', fontsize=14) #取1000阶,颜色映射还是用jet mp.contourf(grid_w0, grid_w1, grid_loss,1000, cmap='jet') #间隔取10 cntr = mp.contour(grid_w0, grid_w1, grid_loss,10, colors='black', linewidths=0.5) #显示等高线 mp.clabel(cntr, inline_spacing=0.1, fmt='%.2f',fontsize=10) mp.plot(w0, w1, 'o-', c='orangered', label='BGD') mp.legend()
基于模型的机器学习实际上就是要找到一个函数,通过实际输出与预测输出之间的误差,表现模型的精度,在求该函数的极小值的过程中,寻找最优的模型参数。
但是并不是损失函数越小越好,我们把一些过于完美的称之为过拟合,一般我们会给它一个惩罚项(超参数)
E = Loss(w0, w1) - 正则项 x 正则强度©
C 我们称为惩罚系数,正则力度
- 机器学习1_线性回归梯度下降算法
- 机器学习1_线性回归梯度下降算法
- 机器学习1_线性回归梯度下降算法
- 机器学习1_线性回归梯度下降算法
- 机器学习1_线性回归梯度下降算法
- 机器学习1_线性回归梯度下降算法
- 机器学习1_线性回归梯度下降算法
- 机器学习1_线性回归梯度下降算法
- 机器学习笔记之应用于线性回归的梯度下降算法
- 机器学习之线性回归及代码示例
- 【机器学习】局部加权线性回归
- 【机器学习】线性回归相关推导
- 机器学习(一)线性回归、逻辑回归
- 机器学习练习(一)——简单线性回归
- 机器学习·一元线性回归之房价预测(MATLAB版)
- 《机器学习》学习笔记(一):线性回归、逻辑回归
- 从零开始机器学习001-线性回归数学推导
- Tensorflow实战学习(八)【机器学习基础 线性回归】
- 机器学习基础(三十) —— 线性回归、正则化(regularized)线性回归、局部加权线性回归(LWLR)
- 机器学习--第十讲--中级线性回归