机器学习通俗入门-使用梯度下降法解决最简单的线性回归问题
来源:互联网 发布:林小宅的淘宝店叫什么 编辑:程序博客网 时间:2024/05/12 07:41
动机
一直以来,使用机器学习的算法都是用他人写好的类库,总觉得云里雾里的,弄不清楚到底怎么回事。今天实现了一个最简单的线性回归分析,觉得收货很大。纸上得来终觉浅,绝知此事要躬行。
回归分析
数据
假设有一组数据,知道自变量和因变量的值,如下例:
3.0000 10.00003.1000 10.30003.2000 10.60003.3000 10.90003.4000 11.20003.5000 11.50003.6000 11.80003.7000 12.10003.8000 12.40003.9000 12.70004.0000 13.00004.1000 13.30004.2000 13.60004.3000 13.90004.4000 14.20004.5000 14.50004.6000 14.80004.7000 15.10004.8000 15.40004.9000 15.70005.0000 16.0000
第一列为自变量,第二列为因变量。 使用matlab绘制出一个图像。
plot(x,y,'o');
可以看到:
模型假设
通过观察我们发现,自变量和因变量大体位于一条线上,这样我们就假设他们遵循一个线性函数。
因为现在的自变量x是一个数字(或者看做1维的向量),所以w和b也是一个数字。
现在的情况是,我们知道自变量和变量,但不知道这个w和b。所以我们的目的就是要估计出一个最合理的w和b。
补充
* 入门读者 这个部分可以不看 *
在实际问题中,x可能是一个长度为n的向量,那么w的维度要和x一致。
这种写法非常的繁琐,可以用线性代数的写法,实际上这种写法也是一般所用的写法。
这里w是一个横向量,x是一个列向量,b 是一个标量(就是一个数字)。
误差分析
为了刻画我们的模型的好坏,我们需要给出一个衡量标准。那么怎么衡量的。
通过一定的算法,我们得到了w和b的估计值
那么 y的估计值 ypred:
这个y的估计值 ypred 和y 的差的绝对值
在数学上,计算绝对值不是很方便,因为绝对值函数在0点不可导。我们希望把他给换成一个功能类似的可导函数。
为什么需要可导呢? 后面会看到。
我们使用误差平方和函数来代替绝对值函数。这个又叫做二阶范式。
note: 为什么要加二分之一?
这个函数是可导的。
误差最小化
为了能得到最好的w和b 的估计,我们希望上面表示出的误差能最小。那么如何求一个函数的最小值呢? 微积分告诉我们,当一个函数导数为0的时候,它去极大值或极小值。 那么函数的最小值就在导数为0的地方。
我们把误差函数看成是w的函数,对w进行求导,可以得到:
如果忘记了怎么求导,可以看看我这篇文章复习一下。
http://blog.csdn.net/taiji1985/article/details/72857554
误差函数对b求导,可以得到:
数学方法求误差最小
上面得到了L关于w和b的导数,另导数等于0,可以得到极值。
带入导数公式得到
求解可得最小二乘法公式,这里就不求了。
数值方法求解
上面的方法可以通过让导数为0得到结果,但对于一切比较复杂的模型,求解导数为0的公式是很困难的。这样就需要一些数值方法来学习。
数值方法一般使用迭代的方法来逼近最终答案,最常用的为梯度下降法。梯度下降法的原理是这样的。 随便选择一个x的初始点
具体做法是,在每次迭代时,计算w的新值
其中a称为学习因子,就是梯度每一步走多长。。如果学习因子太大,容易错过极值点,如果比较小,则收敛变慢。 学习因子一般通过经验给出。 可以先设置一个较小的数,逐渐调大,知道找到一个合适的值。
对于我们这个例子,直接让
算法
有了核心的思路就可以写算法了。先给出一个伪代码
while(还没有收敛){ 计算误差 计算误差和上一次误差的差 如果这个差小于某个值,认为是收敛,退出。 根据公式,更新w和b }
matlab代码如下:
function [w,b] = predict(x,y) d = 10; n = length(x); w = rand(1,1); % 随机生成 y = wx+b 中的w和b 做为初始值 b = rand(1,1); olde = 0; %上一次得到的误差 i = 0; %迭代计数器 rate = 0.001; while d>0.001 % d表示两次迭代的误差的差 i= i+1; %计算 yp = w*x+b; %根据公式计算,当前w和b下,计算出的y的估计值 e = sum((yp-y).*(yp-y)); %将估计值和真实值的差的平方和作为误差评估函数 d = abs(olde - e); %计算上一次循环和这一次之间的误差的差 fprintf('%d iter e = %f , d = %f \n',i,e,d); if d<0.01 break; end olde = e; %修改w和b w = w - rate*sum((yp-y).*x); b = b - rate*sum(yp-y); end hold off; plot(x,y,'o'); hold on; xp = min(x):0.01:max(x); yp = w*xp+b; plot(xp,yp);end
写一个函数来调用这个学习函数
x = (3:0.1:5)'; w = 3; % 这是真实的参数值b = 1;y = w*x+b;seed = 333; % 随机数种子,为了让这个实验在重新运行时能重现所有现在的结果rand('seed',seed)y = y+rand(size(x))*0.7;[wp,bp] = predict(x,y)
运行结果
1 iter e = 3335.957691 , d = 3335.957691 2 iter e = 1348.893476 , d = 1987.064216 3 iter e = 545.781076 , d = 803.112400 4 iter e = 221.186873 , d = 324.594203 5 iter e = 89.995526 , d = 131.191346 6 iter e = 36.971877 , d = 53.023650 7 iter e = 15.541291 , d = 21.430586 8 iter e = 6.879684 , d = 8.661607 9 iter e = 3.378919 , d = 3.500765 10 iter e = 1.964014 , d = 1.414905 11 iter e = 1.392151 , d = 0.571863 12 iter e = 1.161021 , d = 0.231130 13 iter e = 1.067605 , d = 0.093416 14 iter e = 1.029850 , d = 0.037756 15 iter e = 1.014590 , d = 0.015260 16 iter e = 1.008422 , d = 0.006168 wp = 2.9827bp = 1.4161
图中直线为根据估计出的w和b画出的函数曲线。
- 机器学习通俗入门-使用梯度下降法解决最简单的线性回归问题
- 最简单的机器学习算法-线性回归和梯度下降法
- 【机器学习】线性回归的梯度下降法
- 【机器学习】线性回归的梯度下降法 续
- 机器学习通俗入门-使用梯度下降法求解二分问题
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- 机器学习入门:线性回归及梯度下降
- Android——有序广播和无序广播
- Windows系统中设置定时开关机方法
- MySQL查询语句执行的过程
- Unity 使用Photon Server 创建一个简单聊天室
- 工作流引擎Activiti学习 --- 小小总结
- 机器学习通俗入门-使用梯度下降法解决最简单的线性回归问题
- AndroidStudio TODO
- 1.串口通信(转)
- 【报错】Duplicate entry '0' for key 'PRIMARY'
- c# MySQL 一些语句
- GetWindowRect和GetClientRect的注意事项
- github emoji 表情列表
- 常见的网页状态码的意思 404 500......
- excel中只去掉列字段的第一个字符