[ch04-01] 用最小二乘法解决线性回归问题
系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI,
点击star加星不要吝啬,星越多笔者越努力。
4.1 最小二乘法
4.1.1 历史
最小二乘法,也叫做最小平方法(Least Square),它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。其他一些优化问题也可通过最小化能量或最小二乘法来表达。
1801年,意大利天文学家朱赛普·皮亚齐发现了第一颗小行星谷神星。经过40天的跟踪观测后,由于谷神星运行至太阳背后,使得皮亚齐失去了谷神星的位置。随后全世界的科学家利用皮亚齐的观测数据开始寻找谷神星,但是根据大多数人计算的结果来寻找谷神星都没有结果。时年24岁的高斯也计算了谷神星的轨道。奥地利天文学家海因里希·奥尔伯斯根据高斯计算出来的轨道重新发现了谷神星。
高斯使用的最小二乘法的方法发表于1809年他的著作《天体运动论》中。法国科学家勒让德于1806年独立发明“最小二乘法”,但因不为世人所知而默默无闻。勒让德曾与高斯为谁最早创立最小二乘法原理发生争执。
1829年,高斯提供了最小二乘法的优化效果强于其他方法的证明,因此被称为高斯-马尔可夫定理。
4.1.2 数学原理
线性回归试图学得:
\[z(x_i)=w \cdot x_i+b \tag{1}\]
使得:
\[z(x_i) \simeq y_i \tag{2}\]
其中,\(x_i\)是样本特征值,\(y_i\)是样本标签值,\(z_i\)是模型预测值。
如何学得w和b呢?均方差(MSE - mean squared error)是回归任务中常用的手段:
\[
J = \sum_{i=1}^m(z(x_i)-y_i)^2 = \sum_{i=1}^m(y_i-wx_i-b)^2 \tag{3}
\]
\(J\)称为损失函数。实际上就是试图找到一条直线,使所有样本到直线上的残差的平方和最小。
图4-3 均方差函数的评估原理
图4-3中,圆形点是样本点,直线是当前的拟合结果。如左图所示,我们是要计算样本点到直线的垂直距离,需要再根据直线的斜率来求垂足然后再计算距离,这样计算起来很慢;但实际上,在工程上我们通常使用的是右图的方式,即样本点到直线的竖直距离,因为这样计算很方便,用一个减法就可以了。
假设我们计算出初步的结果是虚线所示,这条直线是否合适呢?我们来计算一下图中每个点到这条直线的距离,把这些距离的值都加起来(都是正数,不存在互相抵消的问题)成为误差。
因为上图中的几个点不在一条直线上,所以不能有一条直线能同时穿过它们。所以,我们只能想办法不断改变红色直线的角度和位置,让总体误差最小(用于不可能是0),就意味着整体偏差最小,那么最终的那条直线就是我们要的结果。
如果想让误差的值最小,通过对w和b求导,再令导数为0(到达最小极值),就是w和b的最优解。
推导过程如下:
\[
\begin{aligned}
{\partial{J} \over \partial{w}} &={\partial{(\sum_{i=1}^m(y_i-wx_i-b)^2)} \over \partial{w}} \\
&= 2\sum_{i=1}^m(y_i-wx_i-b)(-x_i)
\end{aligned}
\tag{4}
\]
令公式4为0:
\[
\sum_{i=1}^m(y_i-wx_i-b)x_i=0 \tag{5}
\]
\[
\begin{aligned}
{\partial{J} \over \partial{b}} &={\partial{(\sum_{i=1}^m(y_i-wx_i-b)^2)} \over \partial{b}} \\
&=2\sum_{i=1}^m(y_i-wx_i-b)(-1)
\end{aligned}
\tag{6}
\]
令公式6为0:
\[
\sum_{i=1}^m(y_i-wx_i-b)=0 \tag{7}
\]
由式7得到(假设有m个样本):
\[
\sum_{i=1}^m b = m \cdot b = \sum_{i=1}^m{y_i} - w\sum_{i=1}^m{x_i} \tag{8}
\]
两边除以m:
\[
b = {1 \over m}(\sum_{i=1}^m{y_i} - w\sum_{i=1}^m{x_i})=\bar y-w \bar x \tag{9}
\]
其中:
\[
\bar y = {1 \over m}\sum_{i=1}^m y_i, \bar x={1 \over m}\sum_{i=1}^m x_i \tag{10}
\]
将公式10代入公式5:
\[
\sum_{i=1}^m(y_i-wx_i-\bar y + w \bar x)x_i=0
\]
\[
\sum_{i=1}^m(x_i y_i-wx^2_i-x_i \bar y + w \bar x x_i)=0
\]
\[
\sum_{i=1}^m(x_iy_i-x_i \bar y)-w\sum_{i=1}^m(x^2_i - \bar x x_i) = 0
\]
\[
w = {\sum_{i=1}^m(x_iy_i-x_i \bar y) \over \sum_{i=1}^m(x^2_i - \bar x x_i)} \tag{11}
\]
将公式10代入公式11:
\[
w={\sum_{i=1}^m (x_i \cdot y_i) - \sum_{i=1}^m x_i \cdot {1 \over m} \sum_{i=1}^m y_i \over \sum_{i=1}^m x^2_i - \sum_{i=1}^m x_i \cdot {1 \over m}\sum_{i=1}^m x_i} \tag{12}
\]
分子分母都乘以m:
\[
w={m\sum_{i=1}^m x_i y_i - \sum_{i=1}^m x_i \sum_{i=1}^m y_i \over m\sum_{i=1}^m x^2_i - (\sum_{i=1}^m x_i)^2} \tag{13}
\]
\[
b=\frac{1}{m}\sum_{i=1}^m(y_i-wx_i) \tag{14}
\]
而事实上,式13有很多个变种,大家会在不同的文章里看到不同版本,往往感到困惑,比如下面两个公式也是正确的解:
\[
w = {\sum_{i=1}^m y_i(x_i-\bar x) \over \sum_{i=1}^m x^2_i - (\sum_{i=1}^m x_i)^2/m} \tag{15}
\]
\[
w = {\sum_{i=1}^m x_i(y_i-\bar y) \over \sum_{i=1}^m x^2_i - \bar x \sum_{i=1}^m x_i} \tag{16}
\]
以上两个公式,如果把公式10代入,也应该可以得到和式13相同的答案,只不过需要一些运算技巧。比如,很多人不知道这个神奇的公式:
\[
\begin{aligned}
\sum_{i=1}^m (x_i \bar y) &= \bar y \sum_{i=1}^m x_i =\frac{1}{m}(\sum_{i=1}^m y_i) (\sum_{i=1}^m x_i) \\
&=\frac{1}{m}(\sum_{i=1}^m x_i) (\sum_{i=1}^m y_i)= \bar x \sum_{i=1}^m y_i \\
&=\sum_{i=1}^m (y_i \bar x)
\end{aligned}
\tag{17}
\]
4.1.3 代码实现
我们下面用Python代码来实现一下以上的计算过程:
计算w值
# 根据公式15
def method1(X,Y,m):
x_mean = X.mean()
p = sum(Y*(X-x_mean))
q = sum(X*X) - sum(X)*sum(X)/m
w = p/q
return w
# 根据公式16
def method2(X,Y,m):
x_mean = X.mean()
y_mean = Y.mean()
p = sum(X*(Y-y_mean))
q = sum(X*X) - x_mean*sum(X)
w = p/q
return w
# 根据公式13
def method3(X,Y,m):
p = m*sum(X*Y) - sum(X)*sum(Y)
q = m*sum(X*X) - sum(X)*sum(X)
w = p/q
return w
由于有函数库的帮助,我们不需要手动计算sum(), mean()这样的基本函数。
计算b值
# 根据公式14
def calculate_b_1(X,Y,w,m):
b = sum(Y-w*X)/m
return b
# 根据公式9
def calculate_b_2(X,Y,w):
b = Y.mean() - w * X.mean()
return b
4.1.4 运算结果
用以上几种方法,最后得出的结果都是一致的,可以起到交叉验证的作用:
w1=2.056827, b1=2.965434
w2=2.056827, b2=2.965434
w3=2.056827, b3=2.965434
代码位置
ch04, Level1
[ch04-01] 用最小二乘法解决线性回归问题的更多相关文章
- 机器学习中梯度下降法原理及用其解决线性回归问题的C语言实现
本文讲梯度下降(Gradient Descent)前先看看利用梯度下降法进行监督学习(例如分类.回归等)的一般步骤: 1, 定义损失函数(Loss Function) 2, 信息流forward pr ...
- 03_利用pytorch解决线性回归问题
03_利用pytorch解决线性回归问题 目录 一.引言 二.利用torch解决线性回归问题 2.1 定义x和y 2.2 自定制线性回归模型类 2.3 指定gpu或者cpu 2.4 设置参数 2.5 ...
- Python实现实现基于最小二乘法的线性回归
下面展示利用Python实现基于最小二乘法的线性回归模型,同时不需要引入其他科学计算以及机器学习的库. 利用Python代码表示如下: #首先引入数据集x,和y的值的大小利用Python的数据结构:列 ...
- 02_利用numpy解决线性回归问题
02_利用numpy解决线性回归问题 目录 一.引言 二.线性回归简单介绍 2.1 线性回归三要素 2.2 损失函数 2.3 梯度下降 三.解决线性回归问题的五个步骤 四.利用Numpy实战解决线性回 ...
- [ch04-02] 用梯度下降法解决线性回归问题
系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 4.2 梯度下降法 有了上一节的最小二乘法做基准,我们这 ...
- [ch04-03] 用神经网络解决线性回归问题
系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 4.3 神经网络法 在梯度下降法中,我们简单讲述了一下神 ...
- 0-1背包问题python解决
def f(i,j): while i>=0: if i==0 and j>=l[i][0]: return l[i][1] elif i==0 and j<l[i][0]: ret ...
- Mathematica/偏导数/最小二乘法(线性回归)
a = / a //输出的还是2/123 N[a] //输出的就是小数点 N[a,] //保留三位小数点 Clear[a] Solve[== x^- , x] //结果-3 和 3 Plot[Sin[ ...
- 机器学习:R语言中如何使用最小二乘法
详细内容见上一篇文章:http://www.cnblogs.com/lc1217/p/6514734.html 这里只是介绍下R语言中如何使用最小二乘法解决一次函数的线性回归问题. 代码如下:(数据同 ...
随机推荐
- JavaFX简介和Scene Builder工具的安装使用简易教程
JavaFX概述和简介 富互联网应用是那些提供与Web应用程序类似的功能,并可作为桌面应用程序体验的应用.与用户的正常网络应用程序相比,它们提供更好的视觉体验.这些应用程序可作为浏览器插件或作为虚拟机 ...
- js如何展示上传的图片
前言:本文章主要讲的是上传的图片如何展示在页面上. 一般来说,我们会先将本地图片上传到服务器,上传成功后,由后台返回图片的网络地址再在前端显示.但是,我今天讲的是不通过前面说的过程,而是直接使用js将 ...
- SpringBoot 整合 Elasticsearch深度分页查询
es 查询共有4种查询类型 QUERY_AND_FETCH: 主节点将查询请求分发到所有的分片中,各个分片按照自己的查询规则即词频文档频率进行打分排序,然后将结果返回给主节点,主节点对所有数据进行汇总 ...
- shell 队列实现线程并发控制
需求:并发检测1000台web服务器状态(或者并发为1000台web服务器分发文件等)如何用shell实现? 方案一:(这应该是大多数人都第一时间想到的方法吧) 思路:一个for循环1000次,顺序执 ...
- 转:nginx和php-fpm的两种通信方式
原文地址:https://segmentfault.com/q/1010000004854045 Nginx和PHP-FPM的进程间通信有两种方式,一种是TCP,一种是UNIX Domain Sock ...
- C++学习笔记10_输入输出流.文件读写
//从键盘输入到程序,叫标准input:从程序输出到显示器,叫标准output:一并叫标准I/O //文件的输入和输出,叫文件I/O cout<<"hellow word&quo ...
- TCP/IP协议第一卷第二章
环回接口: 127全网段均被作为环回地址. 传给广播地址或多播地址的数据报复制一份给环回接口,然后传送到以太网上.这是因为广播传送和多播传送的定义包含自己本身. 任何传给该主机IP地址的数据均送到环回 ...
- AndroidOS体系结构
首先上图一张 对照着图,我们再来看Android 系统的体系结构就爽多了.我们从底层向上进行分析. 一.Linux 内核层 Linux Kernel 基于linux2.6.其核心系统服务如安全性.内存 ...
- 重置root密码!
偶尔把密码忘记了也不用慌,重置密码只需简单几步: 第1步:开机后在内核上敲击“e”. 第2步:在linux16这行的后面输入“rd.break”并敲击“ctrl+x“. 第3步:进入到了系统的紧急求援 ...
- Helm 3 发布 | 云原生生态周报 Vol. 27
作者 | 墨封.元毅.冬岛.敖小剑.衷源 业界要闻 1.Helm 3 发布 美国时间 11 月 13 日,Helm 团队发布 Helm 3 第一个稳定版本.Helm 3 以 Helm 2 的核心特性为 ...