基於matlab的梯度下降法實現線性迴歸

基於matlab的梯度下降法實現線性迴歸

1 緒論

1.1線性迴歸的定義
1.2單變量線性迴歸
1.3多變量線性迴歸

2 梯度下降
2.1 cost function
2.2 梯度下降:解決線性迴歸的方法之一
2.3 feature scaling:加快梯度下降執行速度的方法
2.4 梯度下降的實現

3 梯度下降的擴展和比較


摘要:本文首先說明線性迴歸的定義,以及在統計機器學習中的意義和現實生活中的影響,引出梯度下降法的需求和好處。然後分析了梯度下降的基本原理,給出基於matlab的具體實現方法。總結梯度下降算法的特點,並分析相關參數對算法運行結果的影響。最後,擴展並比較了其他幾種算法(批梯度下降算法、增量梯度下降算法、最小二乘法)以及相關實現。

關鍵詞: 線性迴歸;梯度下降;機器學習

1 緒論
1.1線性迴歸的定義
線性迴歸,是利用數理統計中迴歸分析,來確定兩種或兩種以上變量間相互依賴的定量關係的一種統計分析方法,運用十分廣泛。其表達形式爲y = w’x+e,e爲誤差服從均值爲0的正態分佈。
具體來說,如果輸入 x是列向量,目標 y 是連續值(實數或連續整數),預測函數 f(x)的輸出也是連續值。這種機器學習問題是迴歸問題。如果我們定義 f(x)是線性函數,f(x) = wTx + b, 這就是線性迴歸問題(Linear Regression)。

1.2單變量線性迴歸
單變量線性迴歸就是從一個輸入值預測一個輸出值。輸入/輸出的對應關係就是一個線性函數。

1.3多變量線性迴歸
多變量線性迴歸就是說輸出值受多個輸入變量x影響,每個變量的影響大小用w(weight)來刻畫,w與x呈線性關係,然後把多個wx線性組合(w1x1,w2x2,,,)相加,再和輸出y的對應關係就是一個多變量線性迴歸問題。注意:多變量線性迴歸不是指y與X是線性的,而是指各自的w與x呈線性關係。所以最終的結果,在幾何上甚至可能呈現出曲線,而不是必須是直線。

2 梯度下降
2.1 cost function
線性迴歸屬於監督學習,因此方法和監督學習應該是一樣的,先給定一個訓練集,根據這個訓練集學習出一個線性函數,然後測試這個函數訓練的好不好(即此函數是否足夠擬合訓練集數據),挑選出最好的函數(cost function最小)即可。

1)下面給出單變量線性迴歸的模型:
從上面“方法”中,我們肯定有一個疑問,怎麼樣能夠看出線性函數擬合的好不好呢?
我們需要使用到Cost Function(代價函數),代價函數越小,說明線性迴歸地越好(和訓練集擬合地越好),當然最小就是0,即完全擬合。

2)舉個實際的例子:
我們想要根據房子的大小,預測房子的價格,給定如下數據集:
這裏寫圖片描述

根據以上的數據集畫在圖上,如下圖所示:
這裏寫圖片描述
我們需要根據這些點擬合出一條直線,使得cost Function最小。雖然我們現在還不知道Cost Function內部到底是什麼樣的,但是我們的目標是:給定輸入向量x,輸出向量y,theta向量,輸出Cost值。

3)Cost Function的用途:對假設的函數進行評價,cost function越小的函數,說明擬合訓練數據擬合的越好。
下圖詳細說明了當cost function爲黑盒的時候,cost function 的作用。
這裏寫圖片描述

4)但是我們肯定想知道cost Function的內部構造是什麼?因此我們下面給出公式:
這裏寫圖片描述

其中:
這裏寫圖片描述 表示向量x中的第i個元素;這裏寫圖片描述 表示向量y中的第i個元素;
這裏寫圖片描述 表示已知的假設函數; m 爲訓練集的數量。

比如給定數據集(1,1)、(2,2)、(3,3)
則x = [1;2;3],y = [1;2;3](此處的語法爲Octave語言的語法,表示3*1的矩陣)
如果我們預測theta0 = 0,theta1 = 1,則h(x) = x,則cost function:
J(0,1) = 1/(2*3) * [(h(1)-1)^2+(h(2)-2)^2+(h(3)-3)^2] = 0;
如果我們預測theta0 = 0,theta1 = 0.5,則h(x) = 0.5x,則cost function:
J(0,0.5) = 1/(2*3) * [(h(1)-1)^2+(h(2)-2)^2+(h(3)-3)^2] = 0.58;

如果theta0 一直爲 0, 則theta1與J的函數爲:
這裏寫圖片描述

如果有theta0與theta1都不固定(即都爲變量),則theta0、theta1、J 的函數爲:
這裏寫圖片描述
當然我們也能夠用二維的圖來表示,即等高線圖。
這裏寫圖片描述

注意:如果是線性迴歸,則costfunctionJ與theta0、theta1的函數一定是碗狀的,即只有一個最小點。

2.2 梯度下降:解決線性迴歸的方法之一
但是又一個問題引出了,雖然給定一個函數,我們能夠根據cost function知道這個函數擬合的好不好,但是畢竟函數有這麼多,總不可能一個一個試吧?因此我們引出了梯度下降:能夠找出cost function函數的最小值;梯度下降原理:將函數比作一座山,我們站在某個山坡上,往四周看,從哪個方向向下走一小步,能夠下降的最快。當然解決問題的方法有很多,梯度下降只是其中一個,還有一種方法叫Normal Equation。

方法:
(1)先確定向下一步的步伐大小,我們稱爲Learning rate;
(2)任意給定一個初始值:這裏寫圖片描述 這裏寫圖片描述
(3)確定一個向下的方向,並向下走預先規定的步伐,並更新這裏寫圖片描述 這裏寫圖片描述
(4)當下降的高度小於某個定義的值,則停止下降。

算法:
這裏寫圖片描述
特點:
(1)初始點不同,獲得的最小值也不同,因此梯度下降求得的只是局部最小值;
(2)越接近最小值時,下降速度越慢。

問題a:如果初始值就在local minimum的位置,則會如何變化?
答:因爲已經在local minimum位置,所以derivative肯定是0,因此不會變化。
如果取到一個正確的值,則cost function應該越來越小。
問題b:怎麼取值?
答:隨時觀察值,如果cost function變小了,則ok,反之,則再取一個更小的值。

下圖就詳細的說明了梯度下降的過程:
這裏寫圖片描述
從上面的圖可以看出:初始點不同,獲得的最小值也不同,因此梯度下降求得的只是局部最小值。

注意:下降的步伐大小非常重要,因爲如果太小,則找到函數最小值的速度就很慢,如果太大,則可能會出現overshoot the minimum的現象;下圖就是overshoot minimum現象:
這裏寫圖片描述
如果Learning rate取值後發現J function 增長了,則需要減小Learning rate的值。
因此我們能夠對cost function運用梯度下降,即將梯度下降和線性迴歸進行整合,如下圖所示:
這裏寫圖片描述
梯度下降是通過不停的迭代,而我們比較關注迭代的次數,因爲這關係到梯度下降的執行速度,爲了減少迭代次數,因此引入了Feature Scaling。

2.3 feature scaling:加快梯度下降執行速度的方法
思想:將各個feature的值標準化,使得取值範圍大致都在-1<=x<=1之間。常用的方法是Mean Normalization,即
這裏寫圖片描述
或者:[X-mean(X)]/std(X)。

舉個實際的例子,有兩個Feature:
(1)size,取值範圍0~2000;
(2)#bedroom,取值範圍0~5;
則通過feature scaling後,
這裏寫圖片描述
這裏寫圖片描述
2.4 梯度下降的實現
1)代碼:

%繪製出來最原始的方程的圖像,方程爲f=x^2+y^2;定義域分別設置成爲[-10, 10],然後隨便的設置一個初始點以及迭代的值和步長,來查看使用梯度下降算法的迭代過程%
[x, y] = meshgrid(-10:0.5:10, -10:0.5:10);
z = x.^2 + y.^2;
mesh(x, y, z);
%分別求x和y的偏導數%
%dx = 2*x;
%dy = 2*y;
%設置x,y的初始值,並且每步驟更新的值都加入到這個記錄中來,第一個是初始值,爲了迭代方便設置下第二個元素的值
record_values = [-9;-9]; 
%設置每次更新的步長%
step = 0.1;
%設置迭代次數%
count = 20;
%開始迭代%
for i=1:count
    current_x = record_values(1,i);
    current_y = record_values(2,i);
    temp = [current_x - step*2*current_x, current_y - step*2*current_y];
    %把temp附加到record_values後面%
    record_values(:, i+1) = temp;
end
%計算出來點繪製出來這些點按照順序連線%
hold on;
x_values = record_values(1,:);
y_values = record_values(2,:);
z_values = x_values.*x_values + y_values.*y_values;
plot3(x_values, y_values,z_values, 'k--o');
%我們知道當x,y等於0的時候是最小點,標示出來%
plot3(0, 0, 0, 'rp');

2)截圖:
這裏寫圖片描述

這裏寫圖片描述
3 梯度下降的擴展和比較
1)代碼:

clc

close all

n=1;%特徵向量個數
m=20;%樣本個數
x=ones(n+1,m);
x(2,:)=linspace(0,10,m);%採樣點
y=13*ones(1,m)-3.36*x(2,:)+4*rand(1,m)-2;%樣本值
scatter(x(2,:),y)
hold on
theta=[0,1]';%設置參數
xx=ones(n+1,m);
xx(2,:)=linspace(0,10,m);
yy=theta'*xx;%繪製算法運行生成的曲線
scatter(x(2,:),y)
title('批梯度下降算法結果')
hold on
plot(xx(2,:),yy,'k')
hold off
row=length(xx);
times=0;
%%
tic;
while(1)
    times=times+1;
    step=1/(times*row);
    temp0=theta(1);
    temp1=theta(2);
    H=theta'*x;
    theta=theta-step*((H-y)*x')';%批梯度下降算法
    distant=abs(theta(1)-temp0)+abs(theta(2)-temp1);
    if(distant<0.001)%判斷是否已經收斂
        break;
    end
%     if(times>500)
%         break;
%     end

    scatter(x(2,:),y)
    hold on
    yy=theta'*xx;
    plot(xx(2,:),yy)
    hold off
end
toc;
title('批梯度下降算法結果')

display('批梯度下降')
theta(1)
theta(2)
times
%%
theta=[0,1]';%設置參數
times=0;
figure(2)
tic;
while(1)
    times=times+1;
    step=1/(times*row);
    temp0=theta(1);
    temp1=theta(2);
    H=theta'*x;
    for j=1:m
        theta=theta-step*((H(j)-y(j))*x(:,j));%增量梯度下降算法
    end
    distant=abs(theta(1)-temp0)+abs(theta(2)-temp1);
    if(distant<0.001)%判斷是否已經收斂
        break;
    end
%     if(times>500)
%         break;
%     end

    scatter(x(2,:),y)
    hold on
    yy=theta'*xx;
    plot(xx(2,:),yy)
    hold off
end
toc;
title('增量梯度下降算法結果')
display('增量梯度下降')
theta(1)
theta(2)
times

%%
%用廣義逆的最小二乘
%theta=(X' *X)^(-1)*y;
tic;
theta=inv(x*x')*x*y';
toc;
figure(3)
scatter(x(2,:),y)
    hold on
    yy=theta'*xx;
    plot(xx(2,:),yy)
    hold off
title('最小二乘解析式結果')
display('最小二乘解析式梯度下降')
theta(1)
theta(2)

2)截圖:
這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述


附錄本篇論文下載鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章