一、回归(Regression)能做什么?

除了上一节说的预测 PM2.5 之外,还有其他非常有用的案例:

  • 股市预测:

    • 输入:过去十年内各种股票的涨跌资料或某些公司并购的资料
    • 输出:未来道琼工业平均指数
  • 自动驾驶:
    • 输入:无人车红外线所探测的数据、镜头所看到的数据
    • 输出:方向盘的角度(左转15°、右转35°等)
  • 推荐系统:
    • 输入:使用者A + 商品B
    • 输出:使用者A 购买 商品B的 可能性

分类问题是没有“逼近”概念的。

二、利用回归进行预测

预测宝可梦的CP值

2.1 背景

  • “CP值”是一只宝可梦的战斗力。你抓到一只宝可梦“妙蛙种子”,给它吃一些糖果以后,它就会进化成“妙蛙草”,此时CP值就变了。
  • 如果能预测一只宝可梦在进化后的CP值,你就可以评估是否需要进化,以充分利用糖果的资源,来进化更多更强的宝可梦。

操作:找一个function,输入为一只宝可梦 x x x的各种属性值,输出为进化后的CP值 y y y,如图所示。

一只宝可梦记作 x x x,其属性值如下:

标记 解释
x c p x_{cp} xcp​ 进化前的CP值(14)
x s x_s xs​ 物种(妙蛙种子)
x h p x_{hp} xhp​ 生命值(10)
x w x_w xw​ 重量(11.62kg)
x h x_h xh​ 身高(0.88m)

2.2 如何解决这个问题呢?

上一节我们知道有三个步骤:

  1. 建模:选一个模型(function set)
  2. 评估:评价模型中function的好坏
  3. 择优:找一个最好的function

详细步骤

2.2.1 找模型(使用一次函数)

先找一个简单的 一次函数
y = b + w ∗ x c p y = b + w*x_{cp} y=b+w∗xcp​
即进化后的CP值y等于某一个常数项b,加上某一个数值w乘以输入的宝可梦x在进化前的CP值。

w和b是参数,为任意值,取不同的数值就得到不同的function

如下图所示:

f 3 f_3 f3​ 显然不太可能是正确的,因为进化后CP值变负数了。 这就需要训练集来告诉我们哪些function才是合理的function

  • 将无穷多个 w i ∗ x i w_i*x_i wi​∗xi​相加之和再加上b,就得到了一个 线性模型
  • x i x_i xi​中抽取出来的各种属性值称作 “特征”(feature),当做function的输入
  • w i w_i wi​ 为权重(weight), b b b 为偏置(bias)
2.2.2 评价映射的好坏
1. 收集训练集

先收集训练集,才能找这个function。这是一个监督学习的模型,需要手动给出输入和输出,本例中,它们都是数值。

举例来说,杰尼龟 能进化成 卡咪龟,用 x 1 x^1 x1表示杰尼龟的各种特征,用 y ^ 1 \hat y^1 y^​1表示进化后的CP值979: x 1 → y ^ 1 x^1→\hat y^1 x1→y^​1。其中这个979是我们实际观察到的正确数值。

继续上述操作,收集更多的 x i → y ^ i x^i→\hat y^i xi→y^​i。首先我们通过少量数据来进行训练,这里收集了10只宝可梦进化后的CP值,将输入作为横轴,输出作为y轴,标记在图像上:

2. 定义映射的好坏

定义另一个函数,用以评价Model中function的糟糕程度——损失函数 L L L(Loss function):

  • 输入:一个function
  • 输出:糟糕程度
  • 定义: L ( f ) = L ( w , b ) L(f) = L(w, b) L(f)=L(w,b),此处使用 最小二乘法

f由w和b决定,因此损失函数实际上是用来衡量一组参数的好坏

用真正的数值减去预测的数值再取平方,就是估测的误差。再将它们相加取和就得到损失函数:

损失函数值越大,即误差越大,function效果越差。

2.2.3 找出最好的映射

根据损失函数的定义可得:找到 使损失函数值最小 的function即为最好的function。可穷举w和b,代入使得损失函数最小,但这个非常消耗时间
,显然不可接受。因此就需要一种方法来较快地寻找 —— 梯度下降法(Gradient Descent)。

梯度下降法

在高等数学中我们学过,梯度就是可微函数 f 在各个方向上求偏导数的向量 ( f x ′ , f y ′ , f z ′ , . . . ) (f'_x, f'_y, f'_z, ...) (fx′​,fy′​,fz′​,...),表示某一函数在该点处的方向导数沿着该方向取得最大值。

前提:函数 L ( w ) L(w) L(w) 可微分。
做法:

  • 随机选取一个初始点 w 0 w^0 w0
  • 做 L L L 对 w w w 在 w 0 w_0 w0​ 处的微分,即切线的斜率
    • 斜率为负↘,则增大w: w w w 右移 → L ( w ) L(w) L(w) 减小
    • 斜率为正↗,则减小w: w w w 左移 → L ( w ) L(w) L(w) 减小

那么问题来了,参数值如何增加呢,该增加多少呢?

w向右走的步伐大小取决于两个条件:

  1. 现在的微分值大小:微分值越大,越陡峭,步伐越大;反之越小。
  2. 学习率(Learning rate)η:事先定好的数值,η越大,步伐越大,参数更新的幅度越大,学习的效率更快;反之越小。

注意是减号,微分正,减小w。

  • 重复上述步骤的迭代,直到w移动到 局部最小值

梯度下降法不能找到全局最小值,但是在 线性回归问题 中并没有局部最小,因为线性回归模型的损失函数是 凸函数(convex),局部极值必为全局极值。
【若函数可二阶导(或二阶可偏导),则可利用二阶导数(或偏导数)大于零证明】

以上是一个参数的问题,现在由一个参数推广到两个参数:

类似地,将b利用w的方法,分别计算出L对w和b的偏导数,反复迭代,求出最小的损失函数。

梯度下降法参数调整在等高线中展示效果如下:

2.3 测试训练结果


可以看到曲线拟合得并不完美,在某些点处有很大的误差,或许拟合曲线并不是一条直线。那么我们还能做的更好吗?当然,可以考虑换个更复杂的模型。

2.3.1 换模型(二次函数)

y = b + w 1 ∗ x c p + w 2 ∗ ( x c p ) 2 y=b + w_1*x_{cp}+w_2*(x_{cp})^2 y=b+w1​∗xcp​+w2​∗(xcp​)2
可以用上述方法找到一个最好的 function:

  • b = − 10.3 b = -10.3 b=−10.3
  • w 1 = 1.0 , w 2 = 2.7 × 1 0 − 3 w_1=1.0, w_2=2.7×10^{-3} w1​=1.0,w2​=2.7×10−3

在训练集上的图像如下:

看起来更加合理了,且平均误差为15.4。那么在测试集上表现如何呢:

平均误差为18.4!有没有可能做得更好呢?

上图分别为二次、三次、四次、五次函数。可以发现,到五次函数的时候已经将训练集拟合得很好了,但是测试集上误差反而更大!这种现象称为 “过拟合”(Overfitting)

2.3.2 过拟合

如何解释这种现象呢?

如上图所示,次数越高的函数,它的解空间包含了低次数函数的解空间。因此越复杂的模型,它包含越多的函数,理论上就可以找出一个函数使得训练误差越来越低,前提是梯度下降法能真正帮我们找到最好的函数,不能出现局部最优。

但是在测试集上的结果与训练集的结果是不一样的:

在到第三个式子为止,测试集的误差一直在降低;但是越往后走,误差就暴增了!越复杂的模型并不一定得到越好的结果,这就是 过拟合。因此我们需要选择一个合适的模型。

2.4 收集大量数据来训练测试

现在我们收集60只宝可梦,把原来和进化后的CP值作图(如下图所示),会发现右上角几个点被某种“隐藏力量”影响了。这到底是什么呢?答案就是物种。

隐藏因素

我们将不同的物种用不同的颜色表示

只考虑进化前的CP值是远远不够的,还要考虑物种对进化的影响,因此需要重新设计模型:不同的物种就代入不同的线性函数。

但是把 if 放在 function 里面,这样不就不是一个线性模型了吗?后续还能对损失函数进行微分、用梯度下降法吗?

可以把上述式子改写成 一个 线性函数:

通过控制δ函数的值,来控制函数的结构,具体如下:

那么对于更换后的模型,它的结果怎么样呢?


对于不同的物种,线的颜色不一样。当分不同的种类来考虑时,所预测的误差比原来的模型误差更小。

但这里还是有不能拟合得很好的点,还有其他可能的因素影响着模型预测结果。

可以把所有因素加入模型,看看结果如何:

可以看到又是过拟合了。怎么办呢?使用 正则化 (Regularization)

我们重新定义损失函数,加入一些辅助的额外项λ,让我们找到比较好的function。其中,λ项越趋于0越好:

这里不需要考虑 bais 这一项。因为我们要找一个平滑的function,调整b的大小只是将函数图像上下移动而已,和平滑程度并无关系。

当我们加上λ项时,就说这个function是比较 平滑的(smooth) ——当输入有变化时,输出对输入的变化是比较 不敏感 的。

假设模型为一次函数模型,在某一个 x i x_i xi​ 加上一个 Δ x i \Delta x_i Δxi​,即:
y = b + ∑ w i x i + Δ x i y = b + \sum w_ix_i + \Delta x_i y=b+∑wi​xi​+Δxi​
这个时候输出的变化:
y → y + w i Δ x i y→y+w_i \Delta x_i y→y+wi​Δxi​
当 w i w_i wi​越接近0,输出的变化就越小,也即输出对输入的变化不敏感。

为什么我们喜欢比较平滑的 function ?

  • 假设我们的输入在测试的时候被噪声干扰了,那么一个比较平滑的function就能受到比较小的影响,从而给出一个好的结果。

实验结果

  • λ值越大,代表考虑平滑项的影响力越大,找到的function就越平滑。
  • 当λ值越大时,在测试集上的误差就越大,因为这时就越倾向于考虑 w w w 的数值,而减小考虑训练的误差。
  • 有趣的是,在训练集上得到的误差越大,在测试集上得到的误差是可能比较小的。我们喜欢平滑的function,但不喜欢太平滑的function。

如何找出function有多平滑呢?

  • 这就需要我们调λ的值来决定平滑程度
  • 如上图,选择λ = 100,在测试集上的误差最小。

总结

  • 宝可梦进化前的CP值和进化后的CP值,以及它是哪个物种是非常有关系的,也可能会有其他的因素
  • 梯度下降法的原理和技巧
  • 过拟合和正则化
  • 我们最后得到测试集的平均误差结果是11.1。但是如果用于其他的数据集来预测,得到的误差会是怎样的?

三、代码实现

导入模块

import numpy as np
from matplotlib import pyplot as plt

定义训练数据和损失函数

x_data = [338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]
y_data = [640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]# 使用线性回归模型:y_data = b + w * x_data
x = np.arange(-200, -100, 1)   # bias 横坐标范围
y = np.arange(-5, 5, 0.1)          # weight 纵坐标范围
Z = np.zeros((len(x), len(y)))
X, Y = np.meshgrid(x, y)       # meshgrid 返回结果:y为行,x为列
# 损失函数
for i in range(len(x)):for j in range(len(y)):b = x[i]w = y[j]Z[j][i] = 0for n in range(len(x_data)):Z[j][i] += (y_data[n] - b - w * x_data[n]) ** 2Z[j][i] /= len(x_data)

初始化参数,并使用梯度下降法求参数b, w

b = -120    # 初始化 b
w = -4     # 初始化 w
lr = 1     # 学习率
iteration = 100000# 存储参数值以便于绘图展示
b_history = [b]
w_history = [w]# b和w使用不同的学习率
lr_b = 0
lr_w = 0
# 使用梯度下降法求参数
for i in range(iteration):b_grad = 0.0w_grad = 0.0for n in range(len(x_data)):b_grad = b_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * 1.0w_grad = w_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * x_data[n]lr_b += b_grad ** 2lr_w += w_grad ** 2# 更新参数b -= lr / np.sqrt(lr_b) * b_gradw -= lr / np.sqrt(lr_w) * w_gradb_history.append(b)w_history.append(w)

使用 pyplot 绘图

# 绘图
plt.contourf(x, y, Z, 50, alpha=0.5, cmap=plt.get_cmap('jet'))  # 填充等高线
plt.plot([-188.4], [2.67], 'x', ms=12, mew=3, color="orange")
plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
plt.xlim(-200, -100)
plt.ylim(-5, 5)
plt.xlabel(r'$b$')
plt.ylabel(r'$w$')
plt.title("Linear Regression")
plt.show()

执行结果


从结果可以看出,经过100000次的迭代,(b, w)从初始值走到了终点。当然,这是经过参数调整后的结果。在调整过程中,若参数更新太慢,考虑增加学习率;若遇到过拟合的情况,可考虑将w和b的更新方法分离。

李宏毅《机器学习》Task02 - 回归相关推荐

  1. 李宏毅机器学习课程--回归(Regression)

    近期在学习李宏毅老师的机器学习视频(https://www.bilibili.com/video/av10590361/?p=4),下面写一下自己的心得体会. 李老师用的是精灵宝可梦做的比喻,假设进化 ...

  2. 李宏毅机器学习 之 回归Regression(二)

    目录 1.回归的定义 2.回归的例子 3.建模步骤 1)模型假设,选择模型框架(线性模型) 2)模型评估,如何判断众多模型的好坏(损失函数) 3)模型优化,如何筛选最优的模型(梯度下降) 4.步骤优化 ...

  3. 李宏毅机器学习 02回归

    回归定义和应用例子 回归定义 Regression 就是找到一个函数function,通过输入特征 x,输出一个数值Scalar. 模型步骤 step1:模型假设,选择模型框架(线性模型) 一元线性模 ...

  4. 李宏毅机器学习|Task02

    回归定义:Regression 就是找到一个函数 function,通过输入特征 x,输出一个数值 . 按步骤来 第一步:函数集(model模型) 线性模型:注意区别单特征和多特征的线性模型 y=b+ ...

  5. 【李宏毅机器学习CP1-3】(task1)机器学习简介分类|回归

    文章目录 1.机器学习的过程 2.机器学习相关分类 3.选择合适的model,loss function 4.CP3 一.回归定义和应用例子 回归定义 应用举例 二.模型步骤 Step 1:模型假设 ...

  6. 【李宏毅机器学习】Logistic Regression 逻辑回归(p11) 学习笔记

    李宏毅机器学习学习笔记汇总 课程链接 文章目录 Logistic Regression Step 1: Function Set Step 2: Goodness of a Function Step ...

  7. 【李宏毅机器学习】02:回归Regression

    李宏毅机器学习02:回归Regression 文章目录 李宏毅机器学习02:回归Regression 一.回归(Regression)的定义 1.Regression: Output a scalar ...

  8. 百度飞桨2021李宏毅机器学习特训营学习笔记之回归及作业PM2.5预测

    百度飞桨2021李宏毅机器学习特训营学习笔记之回归及作业PM2.5预测 前言 回归 什么是回归(Regression)? 怎么做回归? 线性回归(Linear Regression) 训练集与验证集 ...

  9. 【李宏毅机器学习】regress case study 回归案例研究(p3) 学习笔记

    李宏毅机器学习学习笔记汇总 课程链接 文章目录 1.应用 2.举例--预测宝可梦进化后的CP值 1.应用 1.预测股票熔断 2.自动驾驶 3.推荐系统 2.举例--预测宝可梦进化后的CP值

  10. 2018-3-19李宏毅机器学习视频学习笔记九----Classification: Probabilistic Generative Model

    视频来源: 李宏毅机器学习(2017)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili https://www.bilibili.com/video/av10590361/?p=10 步骤: (1 ...

最新文章

  1. 修改归档模式的存档终点 archive log list
  2. 匿名管道 阻塞_Linux系统编程—有名管道
  3. HTML5中使用SpeechSynthesisAPI实现语音合成
  4. 导致View树遍历的时机
  5. 85-scala版spark2.x读取es6.x
  6. django ajax页面加载,Python Django 之 基于JQUERY的AJAX 登录页面
  7. excel保存快捷键_这应该算是Windows电脑中最强的几组快捷键!
  8. 电脑和服务器之间怎么传送大文件夹,WIN10两台电脑之间快速传输大量文件 - 卡饭网...
  9. 谷歌浏览器未发送任何数据_将 service worker 引入谷歌搜索
  10. 模拟银行叫号系统(c代码)
  11. Python自动登录QQ
  12. 如鹏网.Net基础2 第六章:MYSQL
  13. html5给文字添加拼音,h5 给汉字加拼音 加进度条
  14. 如何把照片压缩到20k一下_怎么样才能把大于20k的照片缩小到20k之内?分享解决问题的方法...
  15. GB28181-2016 协议(一)
  16. Java中输出所有的水仙花数
  17. 嵌入式工程师学习第一天
  18. canvas初探 —— 实现手机壳效果(适用于移动端)
  19. 超详解六西格玛管理法与案例分享|优思学院
  20. 全国计算机表格试题及答案,全国计算机等级考试四、Excel电子表格操作试题.doc...

热门文章

  1. FSM学习笔记20210905
  2. 给无业游民的用户介绍木偶
  3. 如何将mac的键位改为windows的键位
  4. 作为品牌方你在采媒宝找知乎MCN机构做知乎推广?那么本文将对你有帮助了
  5. .net 使用Polly进行失败重试
  6. Elasticsearch 避免term对text字段使用查询
  7. vue 阻止change事件冒泡
  8. 算法和数据结构的关系?
  9. 倪文迪陪你学蓝桥杯2021寒假每日一题:2.1日(2019省赛A组第10题)
  10. Docker三剑客之swarm