单变量线性回归

  本文档基于吴恩达机器学习课程单变量线性回归部分内容,记录自己对该部分内容的理解,并给出了MATLAB代码实现,以增强自己的理解,也方便后续查阅。

1、线性回归问题描述

  • 回归问题

  对于机器学习而言,主要有量方面的问题——回归和分类,回归可以理解为一种曲线拟合(逻辑回归除外,逻辑回归是分类),线性回归就是对待处理的数据拟合成一条直线,直线的通用表达式如下:
y= kx+b
式中,x是自变量,k为斜率,b为截距,kb都是常数,一旦确定上式中的kb,则确定了一条直线。

  • 约定

  为了方便描述回归问题,在此我们将要用来描述这个回归问题的标记如下:
—— 𝑚代表训练集中实例的数量
—— 𝑥代表特征/输入变量
—— 𝑦代表目标变量/输出变量
—— (𝑥^{(i)}𝑦^{(i)})代表训练集中的实例
—— h 代表学习算法的解决方案或函数也称为假设(hypothesis)

  • 代价函数

  代价函数的直观理解如下图所示:


截屏2021-01-22 下午8.15.48.png
  • 组成要素

a、假设函数h_\theta(x)

  单变量线性回归中,假设函数为一条直线,表达式如下:
h_\theta(x) = \theta_0 + \theta_1x

注意: 虽然此处改变了表达式变量,但实质上与前一节给出的直线表达式相同,改成此处的形式是为了与吴恩达课程一致。

b、代价函数J(\theta_0, \theta_1)

  选择的代价函数为误差平方和取均值,表达式如下:
J(\theta_0,\theta_1) = \frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{i})-y^{i})^2
式中,m为样本个数。

c、目标

  最小化代价函数J(\theta_0, \theta_1),具体实现方式为通过梯度下降算法实现。

d、梯度下降

  梯度下降算法用于最小化代价函数,通过迭代不断地调整参数\theta_0\theta_1的值,迭代终止条件有两种:一是指定迭代次数;二是指定代价函数的目标值err,当代价函数的值小于err后迭代终止。
  梯度下降的实质就是求导数,具体的知识可以查阅相关资料学习,吴恩达课程也有讲解。

2、MATLAB代码实现

%%单变量线性回归
%完成该工作需要以下几个要素
% 1、训练数据 (训练模型的输入)
% 2、假设函数 h (模型集合)
% 3、 代价函数 J(衡量模型输出结果与真值之间误差的大小)
% 4、梯度下降算法 (针对指定的代价函数,根据迭代不断更新模型参数,逐渐减小误差)

clc;close all;clear         % 清除图像fig和工作空间中的变量

%% 1、产生训练数据
m = 100;                    %指定训练数据个数
n = 1;                      %参数个数,(保持与吴恩达课程一致,theta0不算)
x = linspace(0,10,m);
y = 5*x' -1;
y = y + rand(m,1);          %加入误差,得到我们的训练数据集

%% 2、训练模型
alpha = 0.001;              %学习率
Theta = rand(n+1,1);        %参数向量theta0,theta1、、、按列存储
epochNum = 10000;           %指定迭代次数
X = [ones(m,1) x'];         %输入矩阵定义为。每一行为一个训练样本,行数为样本个数,列数为样本特征数

figHand = animatedline('Color', 'b', 'Marker', 'o');    %动态画图展示训练过程中的误差
PlotNum = 1;                %记录从迭代开始到当前迭代时刻需要画图显示的数据个数
ErrMax = 0;                 %记录从迭代开始到当前迭代时刻下误差的最大值 
for epoch = 1 : epochNum
    % (1) 根据假设函数模型计算误差,假设模型函数就是上面内容中描述的h函数
    y_val= X*Theta;
    Err = (y_val - y)' * (y_val -y)/(2*m);    %通过代价函数计算误差
    
    %(2)梯度下降算法更新模型参数
    % 参数更新公式为:theta = theta - alpha*X'*(y_val - y)/m;
    Theta = Theta - alpha*X'*(y_val - y)/m;
    
    %(3)训练过程误差可视化
    ErrMax = max(ErrMax, Err);
    if (epoch == 1 || ~mod(epoch,100))
        addpoints(figHand, PlotNum, Err);
        axis([0, PlotNum+4, 0 , ErrMax*1.1]);
        drawnow
        PlotNum = PlotNum + 1;
    end
end

%% 3、模型预测
y_predict = X*Theta;

%% 4、可视化
figure
plot(x, y, 'r*');
hold on
plot(x, y_predict, 'g+');
legend('真值', '拟合值');

%% 总结:可能出现不收敛情况,很有可能是学习率参数设置太大了,可以减小学习率参数后再试试

3、结果

   训练过程中误差如下图所示:


image.png

   模型预测值与真值(训练样本)比较如下图所示:


image.png

推荐阅读更多精彩内容