机器学习之线性回归(单一变量)代码实现(matlab代码实现)

  本案例主要利用matlab代码解决“采用实现线性回归(单一变量)来预测一辆食品卡车的利润的问题”,代码中涉及到机器学习中的线性回归理论知识,本文不着重介绍(详细可参考吴恩达的《机器学习》),主要介绍其代码实现过程(源代码参考吴恩达的《机器学习》的课后作业)。

  一、ex1.m实现代码如下:代码主要包括三部分:Part 1: 将该线性回归问题的数据集在图中表示、 Part 2: 梯度下降算法实现线性回归、Part 3: 图像化函数J(theta_0, theta_1)。

%%机器学习练习-线性回归函数
%  说明
%  ------------
% 这个文件包含的代码将帮助你开始线性回归问题的练习。
%并且该文件代码将用到以下子函数:
%
%     warmUpExercise.m 简单的函数例子,产生5*5的特征矩阵函数
%     plotData.m    显示数据,画图
%     gradientDescent.m  单一变量批量梯度下降函数
%     computeCost.m    计算线线回归的单一变量损失函数算法

%
% x指的是10万人口的人口规模
% y指的是10万美元的利润
%

%% 初始化
clear ; close all; clc

%% ======================= Part 1: 将该线性回归问题的数据集,在图中表示 =======================
fprintf('画出训练集的数据 ...\n')
data = load('ex1data1.txt');
%文件ex1data1.txt包含了我们的线性回归问题的数据集。
%第一列是城市的人口,第二列是城市里的一辆食品卡车的利润。
%利润的负值表示损失。
X = data(:, 1); y = data(:, 2);

m = length(y); % 训练集的数量

% 画出数据,调用画图函数
plotData(X, y);

fprintf('运行暂停.按enter键继续..\n');
pause;

%% =================== Part 2: 梯度下降算法 ===================
fprintf('运行梯度下降算法 ...\n')

X = [ones(m, 1), data(:,1)]; % 在X中添加一列数(m个1)
theta = zeros(2, 1); % 初始化拟合参数(0,0)

% 一些梯度下降函数设置
iterations = 1600;%迭代次数设置为1500次
alpha = 0.01;%学习率设置为0.01.

% 计算和显示初始的成本值
%调用损失函数,计算初值,此时theta值为(0,0)
computeCost(X, y, theta)

%运行批量梯度下降函数
theta = gradientDescent(X, y, theta, alpha, iterations);

% 将theta值打印在屏幕上
fprintf('通过批量梯度下降法找到的Theta值: ');
fprintf('%f %f \n', theta(1), theta(2));

% 画出线性拟合图
hold on; % 保持先前的图可见
plot(X(:,2), X*theta, '-')
%实际拟合的函数为h=theta1*X(1)+theta2*X(2),X(1)=1,X(2)为训练集中的特征值x
legend('训练数据', '线性回归')
hold off % 不要在这个图上叠加其他的图形

% 预测人口规模为3.5万和7万的利润值
predict1 = [1, 3.5] *theta;
fprintf('当人口为35,000时,我们预测利润为 %f\n',...
    predict1*10000);
predict2 = [1, 7] * theta;
fprintf('当人口为35,000时,我们预测利润为 %f\n',...
    predict2*10000);

fprintf('运行暂停.按enter键继.\n');
pause;

%% ============= Part 3: 图像化函数J(theta_0, theta_1) =============
fprintf('Visualizing J(theta_0, theta_1) ...\n')

%  将计算出的覆盖在网格图中
theta0_vals = linspace(-10, 10, 100);
theta1_vals = linspace(-1, 4, 100);

%初始化J_vals为一个0矩阵,长度为1000 
J_vals = zeros(length(theta0_vals), length(theta1_vals));

% 填入 J_vals矩阵
for i = 1:length(theta0_vals)
    for j = 1:length(theta1_vals)
      t = [theta0_vals(i); theta1_vals(j)];    
      J_vals(i,j) = computeCost(X, y, t);
    end
end

%我们需要在调用surf函数前将J_vals矩阵转置,否则这些轴就会被翻转
J_vals = J_vals';
% 曲面图
figure;
surf(theta0_vals, theta1_vals, J_vals)
xlabel('\theta_0'); ylabel('\theta_1');

% 等值线
figure;
% 将矩阵J_vals画作15个等高线间隔在0.01到100之间
contour(theta0_vals, theta1_vals, J_vals, logspace(-2, 3, 20))
xlabel('\theta_0'); ylabel('\theta_1');
hold on;
plot(theta(1), theta(2), 'rx', 'MarkerSize', 10, 'LineWidth', 2);
View Code

     二、运行结果显示:

图一:训练集数据显示图                                                                     图二:梯度下降法实现的线性回归图            

     

                                         图一                                                                                   图二                                                                                                      

  图三:梯度下降法三维曲线图                                                             图四:梯度下降法等高线图

                         

                                  图三                                                                                               图四

预测结果:

通过批量梯度下降法找到的Theta值: -3.674119 1.170765
当人口为35,000时,我们预测利润为 4235.595167
当人口为70,000时,我们预测利润为 45212.381074

 三、实现代码分析

    1)第一部分:“ 将该线性回归问题的数据集,在图中表示 ”代码实现比较简单,主要读取训练数据集ex1data1.txt中的数据,然后将数据用图画出。

    2)第二部分:“梯度下降算法实现线性回归”,主要包括损失函数function J = computeCost(X, y, theta)和批量梯度下降算法function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)。

其损失函数实现代码computeCost.m如下所示:

 1 function J = computeCost(X, y, theta)
 2 %损失函数:
 3 %   J = COMPUTECOST(X, y, theta) 
 4 %   计算使用theta的成本作为线性回归的参数以适应X和y中的数据点,
 5 %选择的参数theta(theta1,theta2)决定了我们得到的直线相对于我们的训练集的准确程度,
 6 %即模型所预测的值与训练集中实际值之间的差距
 7 
 8 % 初始化一些有用值
 9 m = length(y); % 训练样本数
10 
11 % 需要正确地返回下列变量 
12 J = 0;%变量初始化为0
13 
14 % ======================代价函数代码 ======================
15 % 介绍:计算特定的theta(theta0,theta1)的函数值
16              
17 J = sum((X * theta - y).^2) / (2*m);     % 如X(79,2)  theta(2,1)
18 
19 % =========================================================================
20 
21 end
View Code

其批量梯度下降算法实现代码gradientDescent.m如下所示:

 1 function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
 2 %GRADIENTDESCENT Performs gradient descent to learn theta
 3 %该函数执行批量梯度下降法来学习theta值
 4 %   theta = GRADIENTDESENT(X, y, theta, alpha, num_iters) 
 5 %   该函数通过执行梯度下降算法次数来更新theta值,每次迭代次数跟学习率有关
 6 %   函数参数说明:
 7 %   X :代表特征/输入变量
 8 %   y:代表目标变量/输出变量
 9 %   theta:线性回归模型的两个系数值(h(x)=theta(1)+theta(2)*x)
10 %   alpha:学习率
11 %   num_iters:迭代次数
12 % 初始化一些有用的值
13 m = length(y); %训练样本数
14 J_history = zeros(num_iters, 1);%初始化每次迭代时,代价函数的值初始化为0
15 theta_s=theta;%初始化theta变量,赋初值
16 
17 for iter = 1:num_iters
18 
19     % ====================== 批量梯度下降法代码实现======================
20     % 介绍: 在参数向量theta上执行一个梯度步骤。
21     %               
22     %
23     % 提示: 当测试时,它能够打印有用的代价函数值和梯度算法
24     %
25     theta(1) = theta(1) - alpha / m * sum(X * theta_s - y);       
26     theta(2) = theta(2) - alpha / m * sum((X * theta_s - y) .* X(:,2));     % 必须同时更新theta(1)和theta(2),所以不能用X * theta,而要用theta_s存储上次结果。
27     theta_s=theta; 
28     
29 
30     % ============================================================
31 
32     % 将每次迭代次数计算的成本函数J值保存   
33     J_history(iter) = computeCost(X, y, theta);
34 
35 end
36 J_history
37 end
View Code

3)第三部分:“图像化函数J(theta_0, theta_1)”,将最佳的theta值,用三维曲线图和等高线图表示,但是此方法只能得到大概的最佳的theta值。

四、总结

  1)ex1.m中,出现的这两句代码:

  X = [ones(m, 1), data(:,1)]; % 在X中添加一列数(m个1)
  theta = zeros(2, 1); % 初始化拟合参数(0,0)

       第一句代码:生成了一个2*m的矩阵,第一列是系数‘1’,第二列输入变量x(训练集中的城市人口数)可以用“X(:,2)”表示。

      第二句代码:初始化theta向量,包含两个值theta(1)和theta(2)。

      这样编写的好处是,在后续代码中X*theat就相当于单变量模型的h=theta(1)*1+theta(2)*x

  2)ex1.m中,出现的这两句代码:

    iterations = 1500;%迭代次数设置为1500次
    alpha = 0.01;%学习率设置为0.01

   其作用是设置批量梯度下降算法所需要的相关变量,该变量参数可根据实际情况修改。

 3)其余代码实现过程,根据其算法理论知识也很好理解。

 全部代码可以在https://github.com/xtuwang/my_machine-learning_test/blob/master/my-ex1-1.zip下载。

猜你喜欢

转载自www.cnblogs.com/xtu-wlf1212/p/9726526.html