機器學習之線性回歸(單一變量)代碼實現(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下載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM