1. 程式人生 > >NG機器學習總結-(三)線性迴歸以及python實現

NG機器學習總結-(三)線性迴歸以及python實現

在前面已經簡單介紹了迴歸問題(預測房價),其實在統計學中,線性迴歸(Linear Regression)是利用被稱為線性迴歸方程的最小平方函式(Cost Function)對一個或多個自變數和因變數之間關係進行建模的一種迴歸分析。這種函式式一個或多個被稱為迴歸係數的模型引數的線性組合。----此話出自《統計學習》一書,個人覺得定義的有點拗口。個人見解,線性迴歸其實是通過一個線性模型來找出自變數和因變數之間的關係,依我們以前的老闆看來其實就是y = ax + b。當只有一個自變數的時候就是單變數線性迴歸(Linear Regression with one variable),當自變數是多個的時候就是多變數線性迴歸。

一、單變數線性迴歸

在NG機器學習總結-(二)中已經介紹了單變數線性迴歸的模型表示、損失函式以及梯度下降求解,這裡不再重複介紹,只是簡單將其拿出來複習一下。

1.模型表示

h_{\theta}(x)=\theta_{0}+\theta_{1}x

2.損失函式

J(\theta_{0},\theta_{1})=\frac{1}{2m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)}-y^{(i)})^{2}

3.梯度下降演算法求解

repeat until convergence {

       \theta_{j}:=\theta_{j}-\alpha \frac{\partial }{\partial \theta_{j}}J(\theta_{0},\theta_{1}) \quad for (j = 1 and j = 0)  

}

根據上式求解:

\theta_{0}:=\theta_{0}-\alpha \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})

\theta_{1}:=\theta_{1}-\alpha \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})\cdot x^{(i)}

update \theta_{0}\theta_{1} simultaneously

二、多變數線性迴歸

上面說到多變數線性迴歸(Linear Regression with mutiple variable)其實就是自變數(特徵,features)是多個。假設還是以預測房價為例,以前只有一個自變數(房子的大小,特徵是Size),這裡假設房價不僅受房子的大小(Size)還受到房間的數量(bedroom)和房子的樓層(floor)以及房子的年限(years)影響,這裡就有四個自變數(特徵)。

這就是一個多變數線性迴歸問題。因此我們可以構建如下的線性迴歸模型:

h_{\theta}(x)=\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}+\theta_{3}x_{3}+\theta_{4}x_{4}

當然有的時候特徵變數也會有很多,比如10個、20個、50個等。為了方便以後的表述,這裡給出資料集的一些符號。

  • m表示資料集(訓練集)中樣本的數量
  • n表示自變數(特徵)的數量
  • x^{i}表示訓練集中第i個樣本輸入
  • x^{i}_{j}表示訓練集中第i個樣本中第j個特徵

對照單變數線性迴歸以及上面給出的例子,下面會介紹線性迴歸的模型一般表示、損失函式以及梯度下降求解。

1.模型表示

同樣的根據單變數線性迴歸的模型表示,可以得出多變數線性迴歸的模型表示:

h_{\theta}(x)=\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}+...+\theta_{n}x_{n}

這裡x_{1}可以表示為房子的大小(特徵)、x_{2}表示為為房間的數量、x_{3}表示為房子的位置等等。而相對應的\theta_{1}

\theta_{2}\theta_{3}等等可以表示為對應特徵的引數。\theta_{0}可以簡單理解為房子的基礎價。

一般為了方便程式設計,我們會採用矩陣的方式用來簡化多變數線性迴歸模型:

h_{\theta}(x)=[\theta_{0} \quad \theta_{1} \quad ... \quad \theta_{n}]\begin{bmatrix} x_{0}\\ x_{1}\\ ...\\ x_{n} \end{bmatrix}

2.損失函式

同樣的根據單變數線性迴歸,為了減小預測值和真實值之間的差距,我們的目標就是選擇出使得模型的誤差最小的模型引數,這裡仍然使用誤差平方和來表示,其損失函式如下:

J(\theta)=\frac{1}{2m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)}-y^{(i)})^{2}

3.梯度下降演算法求解

repeat until convergence {

       \theta_{j}:=\theta_{j}-\alpha \frac{\partial }{\partial \theta_{j}}J(\theta) \quad for (j=1,2,...,n)  

}

根據上式求解:

\theta_{0}:=\theta_{0}-\alpha \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})

\theta_{1}:=\theta_{1}-\alpha \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})\cdot x^{(i)}_{1}

\theta_{2}:=\theta_{2}-\alpha \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})\cdot x^{(i)}_{2}

...

\theta_{n}:=\theta_{n}-\alpha \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})\cdot x^{(i)}_{n}

update \theta_{0},\theta_{1}.,...,\theta_{n} simultaneously

In other words:

repeat until converagence:{

        \theta_{j}:=\theta_{j}-\alpha \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})\cdot x^{(i)}_{j} \quad for(j=0,1,2,...,n)

}

三、特徵縮放和學習速率

1.特徵縮放(feature scaling)

從剛剛的房價預測資料我們取兩個特徵,一個是房子的大小(size),另一個是房間的數量(num of bedrooms),明顯看出房子的大小的取值範圍是0-2200,而房間的數量取值是1-5,兩者的數值差距很大。我們在NG學習總結-(二)中已經畫過特徵引數和損失函式的等高線圖,這裡我們以特徵引數\theta_{1}(size)和特徵引數\theta_{2}(number of bedrooms),簡化等高線圖如下(NG的課程裡面這個size假設是0-2000不要受上面資料集的影響):

從上圖可以看出如果不同特徵之間的取值範圍差距過大,在使用梯度下降演算法的過程中會造成損失函式收斂到最小值的速度太慢。因此為了加速損失函式的收斂,我們會將不同的特徵取值範圍粗略的處理成範圍相近的取值。這裡我們給出一種方法是:x_{i}=\frac{x_{i}}{max(x_{i})},通過這種方式,得出的每個特徵的取值的範圍大約會在[-1,1]之間。比如剛剛的房價預測中房子的大小(size)和房間的數量(number of bedrooms),經過這種方式處理後,可以得出下面的等高線圖:

經過這種方式的特徵縮放後,收斂的速度會快很多(沒有明確定義所有的特徵值一定要嚴格在[-1,1]之間,比如原來的資料集中某一項特徵的取值範圍是[0.5-2]之間這樣也是可以的,各個特徵的取值範圍接近即可)。另外一種方式是標準化(mean normalization)這是一種使用比較多的特徵縮放方法,其計算方式如下:x_{i}=\frac{x_{i}-\mu _{i}}{max(x_{i})-min(x_{i})},這裡的\mu _{i}是指各項特徵的取值的平均值。通過這種方式,特徵縮放後的取值一般是[-0.5,0.5]的範圍內。

2.學習速率

我們知道梯度下降演算法的求解公式如下:

\theta_{j}:=\theta_{j}-\alpha \frac{\partial }{\partial \theta_{j}}J(\theta) \quad for (j=1,2,...,n)

但是我們怎麼確定在梯度下降演算法的求解過程中一定是正確的呢?換一句話說每次的迭代引數都應該會使損失函式減小,那我們怎麼確保這個過程是正常的,這個時候需要去檢測。如果給定搞一個有效的學習速率\alpha,那麼經過每一次迭代,特徵引數都能降低損失函式的值,這個過程應該就是正確的,至少可以說每一次迭代損失函式有收斂到最小值的趨勢。(當經過一次迭代後,如果損失函式的值減小了小於0.001,那麼我們可以認為是收斂了。)

下面會給出幾種梯度下降過程中的異常情況。

比如第一種情況(上圖中左上角圖),這說明梯度下降演算法的過程不正確,(在確保你程式寫的正確的情況下)說明可能學習速率取值太大(對應右下角圖);第二種情況(上圖中左下角圖),這說明可能學習速率\alpha取值太大,導致了波動。這個時候需要調整學習速率。學習速率是一個很重要的值,如果學習速率取值太小,收斂太慢;如果學習速率取值太大,每一次迭代損失函式不一定會減小,甚至不會收斂(當然也會導致收斂很慢)。那麼如何選取一個合適的學習速率呢?NG課程中表示這個時候需要去進行多次的實驗來嘗試,比如取值可以是...,0.001,...,0.01,...,0.1,...,通過實驗來找到合適的學習速率。

四、多項式迴歸

對於剛剛提到的房價預測問題,現在假設有兩個自變數(特徵),一個是房子的寬度(frontage)x_{1},一個是房子的長度(depth)x_{2},因此我們可以建立的房價預測模型為:

h_{\theta}(x)=\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}

但是我們換一個角度思考,這其實可以用房子的面積(size)x作為自變數(特徵)來預測房價(x=x_{1}\times x_{2}),因此我們可以建立的房價預測模型為:

h_{\theta}(x)=\theta_{0}+\theta_{1}x

當然這仍然是一個線性迴歸模型,但是並不是所有的問題都可以用線性模型來擬合數據集,比如下面的資料集:

如果用線性模型去擬合數據,明顯效果是不好的。但是如果我們同時用曲線1和曲線2去擬合數據,我們發現曲線1在對稱軸的右方會有下降的趨勢,這種擬合也是不合理的,而曲線2明顯很好的擬合數據集。曲線1和曲線2的模型表示為:

曲線1的模型表示:h_{\theta}(x)=\theta_{0}+\theta_{1}x+\theta_{2}x^{2}

曲線2的模型表示:h_{\theta}(x)=\theta_{0}+\theta_{1}x+\theta_{2}x^{2}+\theta_{3}x^{3}

====》h_{\theta}(x)=\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}+\theta_{3}x_{3}

上面提到的兩種模型分別是二次函式和三次函式,因此這些被稱為多項式迴歸模型。通過將特徵的轉化,我們可以將多項式迴歸問題轉化為了線性迴歸模型求解(這個時候特徵縮放就會很重要的,根據上圖右下角的綠色字型,可以看出特徵取值之間差距很大)。當線性模型不能很好的擬合數據集的時候,選取合適的特徵,將其轉化為了多項式模型就顯得很重要了,當然這裡的多項式模型並不僅限於上面給出的模型,你也可以使用h_{\theta}(x)=\theta_{0}+\theta_{1}x+\theta_{2}\sqrt{x},你還可以使用不同特徵之間的組合(x=x_{1}\times x_{2} 等)。

五、標準方程

1.標準方程

無論是單變數線性迴歸和多變數線性迴歸問題,我們都是使用梯度下降演算法來找出使得損失函式最小的時候的特徵引數\theta。我們先來觀察損失函式的表示:

J(\theta)=\frac{1}{2m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)}-y^{(i)})^{2}

h_{\theta}(x)=[\theta_{0} \quad \theta_{1} \quad ... \quad \theta_{n}]\begin{bmatrix} x_{0}\\ x_{1}\\ ...\\ x_{n} \end{bmatrix}=\theta^{T}x

h_{\theta}(x)=y   (當預測值等於真實值) x_{0}=1

這其實不就是多元方程組嘛?中學的時候我們就學過怎麼求解多元方程組,因此當:\frac{\partial J(\theta_{j})}{\partial \theta_{j}}=0的時候我們可以解出所有的引數值。這裡我們用矩陣來表示資料集:

X=\begin{pmatrix} 1&x_{11}& x_{12} & ...& x_{1n}\\ 1&x_{21}& x_{22}& ...& x_{2n} \\ \vdots &\vdots & \vdots & \vdots & \vdots \\ 1&x_{m1}& x_{m2}& ...& x_{mn} \end{pmatrix}=\begin{pmatrix} x^{T}_{0}\\x^{T}_{1}\\ x^{T}_{2}\\ \vdots \\ x^{T}_{m} \end{pmatrix}

損失函式等同於:

J(\theta)=(X\hat{\theta}- y)^{T}(X\hat{\theta} - y)

根據標準方程對其進行引數求導:

\frac{\partial J(\theta)}{\partial \theta}=2X^{T}(X\hat{\theta}-y)=0

求得引數解:

\hat{\theta^{*}}=(X^{T}X)^{-1}X^{T}y

如果學過矩陣相關的知識,我們會發現X^{T}X並不一定會存在可逆矩陣,比如特徵之間的關係不獨立(某兩個特徵之間可能存在某種比例換算關係)、或者當特徵的數量大於訓練集的數量的時候。因此當你想要使用標準方程的時候一定要考慮一下兩個點:

  • 確定是否有相關特徵,如果存在相關特徵,則去掉相關特徵
  • 當特徵數量較多的時候,可以去掉一些不重要的特徵(特徵選擇方法)

2.標準方程和梯度下降演算法比較

梯度下降演算法的優勢:

  • 當特徵的數量比較大時(特徵的數量超過10000),也能夠很好的實現損失函式最小化,同時時間複雜度不是很高;而當特徵的數量比較大時,使用正規方程求解逆運算是非常耗時的,所以此時使用梯度下降法比較合適。 
  • 梯度下降法適用於所有型別的模型,而正規方程的方法一般只適用於線性模型,不適合邏輯迴歸等其他模型。

標準方程的優勢:

  • 當特徵點的數量不是很大時,使用正規方程更加簡單,不需要像梯度下降演算法一樣迭代實現,一次計算就可以得出最優引數。 
  • 對於梯度演算法來說,效能的好壞還與學習率的設定有關,學習率設定不合適,時間消耗較長,甚至得不到最優解,而正規方程的方法不需要學習率的設定

六、python程式碼實現線性迴歸

由於線性迴歸和邏輯迴歸python的實現方式很相似,只是少量的程式碼修改,這裡將python實現線性迴歸和邏輯迴歸放在另一篇部落格,並用邏輯迴歸演算法在實際的資料集來預測病馬的死亡率。