吴恩达机器学习,监督学习线性回归与梯度下降(MATLAB实现)

监督学习模型描述

在这里插入图片描述
学习算法通过训练集得到一个假设函数h,h接收输入可以得到一个输出。
列如:
已知房子大小与对应的价格,通过学习算法驯良可以得到一个假设函数 h h h
h = θ 0 + θ 1 x h=\theta_0+\theta_1x h=θ0+θ1x
设x为房子大小, h h h所得到值即为房价。通过训练集的学习确定假设h的两个系数。

代价函数

对于我们的假设函数h,需要定义一个标准来表明假设所得值与真实值之间的误差,通常我们用平方误差来表明误差,这个我们记为代价函数 J J J
代价函数是所有样本误差的平均。
J ( θ 0 , θ 1 ) = 1 2 m ∑ i = 1 m ( h ( x i ) − y i ) 2 J(\theta_0,\theta_1)=\cfrac{1}{2m}\sum_{i=1}^m(h(x^i)-y^i)^2 J(θ0,θ1)=2m1i=1m(h(xi)yi)2
综上,我们要找到一对系数 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1来使得代价函数 J J J最小

梯度下降(Bath梯度下降)

  1. 给定 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1初始值,一般都直接设为0
  2. 更改 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1以减小 J ( θ 0 , θ 1 ) J(\theta_0,\theta_1) J(θ0,θ1)

(注意:梯度下降可能会使得代价函数位于局部最低值,而不是最小值)
更改系数的方法是利用偏导数来进行。

重复直至收敛{ θ j = θ j − α ∂ ∂ θ j J ( θ 0 , θ 1 ) \theta_j=\theta_j-\alpha\cfrac{\partial}{\partial\theta_j}J(\theta_0,\theta_1) θj=θjαθjJ(θ0,θ1)}
其中 θ j \theta_j θj为各个系数,这个问题中的 j = 0 , 1 j=0,1 j=0,1 α \alpha α为学习率,控制梯度下降的速度,如果 α \alpha α过小,会导致迭代速度慢, α \alpha α过大会导致无法收敛,因为学习率太大,每次都会越过最低点。
在这里插入图片描述
如上图,横坐标相当是系数 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1的综合效应,纵坐标为代价函数 J ( θ 0 , θ 1 ) J(\theta_0,\theta_1) J(θ0,θ1)。当前为A点,原本应该会被下降到B点,可是由于学习率过大导致越过了B点到达了C点。
学习率适当不是说取0.5(刚开始时我选择了0.5)正常情况下为0.1,0.03,0.01,0.003,0.001…

数据拟合

我们先将老师提供的数据画出来

clear;
clc;
data=load('ex1data1.txt');
size=data(:,1)';
price=data(:,2)';
figure(1);
plot(size,price,'o');
title('训练集');
xlabel('房子大小');
ylabel('房价')

在这里插入图片描述
通过拟合获取函数

clear;
clc;
%%
%画出原始图像
data=load('ex1data1.txt');
size=data(:,1)';
price=data(:,2)';
figure(1);
plot(size,price,'o');
title('训练集');
xlabel('房子大小');
ylabel('房价')
%%
%拟合函数
syms h J k0 k1 f0 f1;%定义变量
h=k0+k1*size;%定义假设函数h
J=sum((h-price).^2)/(2*length(size));%定义代价函数J
f0=diff(J,k0);%求得代价函数对k0的偏导
f1=diff(J,k1);%求得代价函数对k1的偏导
%初始化k0,k1
k0=0;
k1=0;
nowJ=subs(J);%记录当前代价
lastJ=2*nowJ;%记录之前代价
a=0.01;%学习率
while (lastJ-nowJ)/lastJ>=0.00001%当代价变动不大时即为收敛,退出循环
    %获取新的k0,k1值
    temp0=vpa(subs(k0-a*f0));
    temp1=vpa(subs(k1-a*f1));
    k0=temp0;
    k1=temp1;
    lastJ=nowJ;
    nowJ=subs(J);%计算新的代价函数 
end
disp([k0,k1])
x=(5:0.1:25);
y=k0+k1*x;
hold on;
plot(x,y,'-');

在这里插入图片描述
其中需要注意的是 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1要同时改变,所以先用temp变量记录变换后的值,等到计算结束之后一起更改系数。

特征缩放

在多变量线性回归中,由于不同特征之间的数量级差别可能很大(比如说房子的大小和房间数)会导致代价函数h收敛较慢,所以需要对特征进行处理后使用

  1. 方法一 除以最大值
    所有特征都除以他的最大值,这个方法在特征数据都是同号的时候能够将所有数据都缩放到[0,1]之间,方便收敛。
  2. 方法二 均值归一化
    对于特征向量 x i x_i xi,由于有 θ 0 \theta_0 θ0的原因, x 0 x_0 x0要永远为1,而对于其他特征:
    x i = x i − μ i s i x_i=\frac{x_i-\mu_i}{s_i} xi=sixiμi
    其中, μ i \mu_i μi是特征向量 x i x_i xi的平均值, s i s_i si x i x_i xi的范围, s i = m a x ( x i ) − m i n ( x i ) s_i=max(x_i)-min(x_i) si=max(xi)min(xi)

学习率的选择与代价函数收敛的判断

学习率的选择

虽然学习率可以选择0.01,0.003,0.001…但是他们之间的差距任然很大,就上述数据而言,我选择的学习率为0.012,通过观察代价函数值与迭代次数的关系,我们可以选择学习率。

clear;
clc;
%%
data=load('ex1data1.txt');
size=data(:,1)';
price=data(:,2)';
%%
%拟合函数
syms h J k0 k1 f0 f1;%定义变量
h=k0+k1*size;%定义假设函数h
J=sum((h-price).^2)/(2*length(size));%定义代价函数J
f0=diff(J,k0);%求得代价函数对k0的偏导
f1=diff(J,k1);%求得代价函数对k1的偏导
%初始化k0,k1
k0=0;
k1=0;
nowJ=subs(J);%记录当前代价
lastJ=2*nowJ;%记录之前代价
a=0.012;%学习率
number=0;
J_va=zeros(1,1500);
while number~=1500%当代价变动不大时即为收敛,退出循环
    %获取新的k0,k1值
    temp0=vpa(subs(k0-a*f0));
    temp1=vpa(subs(k1-a*f1));
    k0=temp0;
    k1=temp1;
    lastJ=nowJ;
    nowJ=subs(J);%计算新的代价函数 
    number=number+1;
    J_va(number)=nowJ;
end
figure(2);
plot(1:number,J_va);
xlabel('迭代次数')
ylabel('代价')
title('代价随迭代次数而减小')

在这里插入图片描述
可以看出曲线非常平滑,这是一个比较好的学习率的结果,如果我们选择一个稍微小一点的,比如0.01
在这里插入图片描述
这个曲线很畸形,所以这个学习率并不是太好

代价函数收敛判断

方法一 代价函数变化率小

我们可以记录前一次代价函数的值,然后当前代价进行比较,当变化率小于某个值时退出循环

nowJ=subs(J);
lastJ=2*nowJ+1;
while (lastJ-nowJ)/lastJ>=0.0001%当变化率小于0.0001时退出循环
   temp0=subs(k0-a*f0);
   temp1=subs(k1-a*f1);
   k0=temp0;
   k1=temp1;
   %更改记录的代价函数值
   lastJ=nowJ;
   nowJ=subs(J);
end

这种方法容易实现,但是却不一定准确。收到学习率的影响,变化率可能会一直大于某个数,这个阙值很难找到。

方法二

在上述我们确定学习率的时候,我们得到了学习率和迭代次数的关系图:
在这里插入图片描述
我们可以从这个图中可以得到代价函数在迭代多少次之后趋于收敛。如上图我们可以得知,当迭代次数大于约1200次时,函数趋于收敛。我们可以事先确定好迭代次数来进行数据分析。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有脚的菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值