Stanford-Andrew Ng《Machine Learning》week3

1. Logistic Regression

1.1 Classification(分類)

現在開始討論要預測的變量y是離散值的情況下的分類問題,爲此將使用Logistic迴歸算法來處理。Logistic迴歸算法是一個當今最流行、最廣泛使用的學習算法之一。下面是分類問題的一些例子,例如垃圾郵件分類。或是網上交易,例如你有一個賣東西的網站,如果想知道某一個交易是否欺詐,例如是否用盜取的信用卡,或者竊取用戶的密碼,這也是一種分類問題。或者預測腫瘤是良性腫瘤或是惡性腫瘤。

在所有的這些問題中,我們嘗試要預測的輸出變量y都是可以有兩個取值的變量(例如使用0或1來表示這兩種情況),使用0來表示的這一類,還可以稱爲負類,用1來表示的這一類,還可以叫做正類。所以0可以表示良性腫瘤,1(或者說正類)可以表示惡性腫瘤。到底用0表示正類,還是1表示正類,其實是沒有區別的。但通常我們感覺負類就是沒有某樣東西,例如沒有惡性腫瘤,而1即正類,表示具有我們想要尋找的東西,但是到底哪個是正,哪個是負沒有明確的規定,也並不重要。

現在先從只包含0和1兩類的分類問題開始,之後再討論多分類問題,例如變量y可以選取0、1、2、3這些值。

 

所以如何開發一個分類算法呢,下面這個例子是對腫瘤進行惡性或良性分類所得到的數據,在這裏,惡性與否只有兩個值,0(即否),1(即是)。

所以我們可以做的是對於這個給定的訓練集,將之前的線性迴歸算法,應用到這個訓練集,用直線對數據進行擬合,那麼或許就能得到下圖這樣的假設:

如果想要做出假設,你可以做的一件事就是將分類器輸出的閾值設爲0.5,即縱座標值爲0.5,如果假設輸出大於等於0.5,就可以預測y爲1,如果小於0.5,就預測y等於0。

因此在閾值這個點的右邊,我們將預測爲正,因爲這些點對應的縱座標大於0.5,而在閾值點的左邊的點,我們將預測爲負。

在這個特定例子中,似乎線性擬合得還不錯,即使這是一個分類任務。但是,嘗試改變一下問題,將橫軸延長一點,假設我們有另外一個訓練樣本位於右邊遠處,注意這個額外的訓練樣本,它並沒有改變什麼,對吧?

看看現在的訓練集,顯然假設很好,所有在閾值點右邊的,都應該被預測爲正,在左邊的我們應該預測爲負。因爲從這個訓練集來看,如果腫瘤尺寸大於這個閾值,就說明是惡性腫瘤,小於這個閾值,則爲良性腫瘤。但是當我們增加這個額外的訓練樣本以後,如果運行線性迴歸,那麼就會得到另外一條直線來擬合數據,可能會得到下圖中的藍色直線。

現在如果還是將閾值設爲0.5,那麼這似乎是一個相當差勁的線性迴歸了,僅僅通過在右邊遠處添加一個樣本,而且這個樣本並沒有提供任何新信息(也就是說這個樣本很明顯應該屬於惡性腫瘤)。但不知爲何,加了這個訓練樣本之後,使得線性迴歸對數據的擬合直線從洋紅色線變成了藍色直線,變成了一個更差勁的假設。

將線性迴歸應用於分類問題,通常並不是一個好的選擇,對數據集應用線性迴歸有時運氣好,可能效果很好,但通常並不是一個好的方法,所以不推薦將線性迴歸用於分類問題。

 

除此之外,對於分類問題,我們知道Y是0或1,但如果你使用線性迴歸,假設的輸出值將遠大於1或遠小於0,即使所有的訓練樣本標籤都應該是0或1,而這似乎有些奇怪,即使我們知道標籤應該是0或1,但算法的輸出值會出現遠大於1或遠小於0的情況。

所以對於分類問題,我們需要開發一個名叫Logistic迴歸的算法,這個算法的輸出值(或者說是預測值)的範圍介於0和1之間,順便說一下,Logistic迴歸算法是一種分類算法,因爲名字中有迴歸,所以有些時候可能產生誤解,但Logistic迴歸實際上是一種分類算法,它被命名爲這個名字只是由於歷史原因,所以不要感到困惑。Logistic迴歸是一種分類算法,用於標籤y是離散值0或1的情況下。

1.2 Hypothesis Representation(假設函數的表示)

之前我們說過,希望我們的分類器輸出值在0和1之間,因此需要提出一個假設來滿足該性質,讓預測值在0和1之間。

當使用線性迴歸的時候,假設形式是這樣的

而對於logistic迴歸,假設函數是

g函數的定義,如果z是一個實數,那麼就有

這個g函數就是sigmoid函數或者說是logistic函數,這個術語logistic函數就是logistic迴歸的名字來源。

如果將這兩個函數合在一起,就能得到假設函數的另一種表示方法

sigmoid函數的圖像如下圖一樣,類似於一個S形,經過(0,0.5)這個點,一端趨近於0,一端趨近於1,橫座標表示z,隨着z趨向於負無窮,g(z)趨向於0,而當z趨向於正無窮時,g(z)趨近於1。

而如圖所示,g(z)的值在0和1之間,也就說明h(x)一定在0和1之間,有了這個假設函數以後,我們需要做的就是用參數θ擬合我們的數據,所以對於一個給定的訓練集,我們需要給參數θ選定一個值。

在此之前,先對假設函數的模型進行解釋,當假設輸出某個數字時,這個數字代表的就是對於一個輸入值x,y=1的概率估計。例如假如一個病人的腫瘤尺寸大小爲x,假設h(x)的輸出值是0.7,這就表明對於一個特徵爲x的患者,y=1的概率爲0.7,也就是說,很不幸,這個腫瘤有70%或者說是有0.7的可能性是惡性腫瘤。

寫成數學表達式就是,如果你熟悉概率的話,應該能看懂這個方程,如果你不太熟悉概率可以這樣理解這個表達式,“在給定x的條件下y=1的概率”,即病人的特徵爲x(腫瘤尺寸)的情況下,這個概率的參數是θ。

因爲這是一個分類問題,我們知道y必須是0或1這兩個值,因此根據h(x),也可以計算出y等於0的概率,具體地說因爲y必須是0或1,所以y=0的概率與y=1的概率相加就等於1。

如果方程有點複雜,可以想象它沒有x和θ。

1.3 Decision boundary(決策界限)

在此之前,我們先來進一步理解假設函數何時將y預測爲1,什麼時候又會將y預測爲0,並且更好地理解假設函數的形狀,特別是當我們的數據有多個特徵時。

假設我們有一個訓練集和一個假設函數。

具體來說,假設函數輸出的是,給定x和參數θ時,y=1的估計概率。因此,如果我們想預測y=1還是0,我們可以這樣做,只要該假設函數輸出y=1的概率≥0.5,那麼這意味着y更有可能等於1而不是0,所以我們預測y=1。而如果預測y=1的概率小於0.5,那麼我們就預測y=0。在這裏如果h(x)的值等於0.5,可以預測爲正類,也可以預測爲負類。

看這個sigmoid函數的曲線圖,我們會注意到只要z≥0,g(z)就≥0.5,而由於假設函數爲 ,所以只要 ≥ 0,h(x)就大於等於0.5,所以只要 ≥ 0,假設函數就會預測y=1。現在來考慮假設函數預測y=0的情況,類似的,h(x)將會<0.5,只要g(z)<0.5,所以當g(z)<0.5時,假設函數將會預測y=0,又根據,因此只要 <0,就會預測y=0。

總結一下,如果我們要預測y=1還是等於0,取決於估值概率是≥0.5,還是<0.5。這其實就等於說,我們將預測y=1,只要

≥ 0。反之,我們將預測y=0,只要 < 0。

通過這些我們就能更好地理解logistic迴歸的假設函數是如何做出預測的。

 

現在假設我們有一個訓練集和一個假設函數,如下圖所示。

 

目前,我們還不知道如何擬合此模型中的參數,我們將在後面討論這個問題,但是假設我們已經擬合好了參數,如下圖所示。

這樣就有了一個參數選擇,讓我們試着找出假設函數何時將預測y=1,何時又將預測y=0,根據上面所講,我們知道y更有可能是1(或者說是y=1的概率 ≥ 0.5),只要滿足 ≥ 0,也就是說對於任意一個樣本,只要x1、x2滿足 -3+x1+x2≥0,我們的假設函數就會認爲,或者說會預測y=1。

x1+ x2 ≥ 3這個式子將定義一條直線通過(0,3)和(3,0),如下圖所示:

這條直線的右邊對應於x1+ x2 ≥ 3,也就是說假設函數預測y=1的區域就是這部分。與此相對,x1 + x2<3的區域,也就是我們預測y=0的區域就是這條直線的左邊部分。這條直線被稱爲Decision Boundary(決策邊界)。具體地說,x1 + x2 = 3這條直線對應一系列的點,對應着h(x) = 0.5的區域,決策邊界(也就是這條直線),將整個平面分成了兩部分,其中一片區域假設函數預測y=1,而另一片區域,假設函數預測y=0。

注意:決策邊界是假設函數的一個屬性。它包括參數θ0、θ1、θ2,在上面的圖中,畫出了數據集使之可視化,但是即使去掉這個數據集,這條決策邊界以及預測y=1和y=0的區域,它們都是假設函數的屬性,決定於它的參數,它不是數據集的屬性。

之後將會討論如何擬合參數,那將使用數據集來確定參數的取值,但是一旦有了確定的參數取值,即有了確定的θ0、θ1、θ2,就能完全確定決策邊界,這時,實際上並不需要通過繪製訓練集來確定決策邊界。

現在,來看一個更復雜的例子。和之前一樣使用×表示正樣本,表示負樣本,給定一個這樣的訓練集,如下圖所示:

怎樣才能使用logistic迴歸擬合這些數據呢?在之前的多項式迴歸或線性迴歸中時,我們可以在特徵中添加額外的高階多項式項,所以我們也可以對logistic迴歸使用相同的方法。具體地說,假設函數如下圖所示:

已經添加了兩個額外的特徵,x1²和x2²,所以現在有5個參數從θ0到θ4,假設現在已經擬合了參數,θ0爲-1,θ1和θ2都爲0,θ3和θ4都等於1。參數向量如下圖所示:

這意味着假設將預測y=1,只要 -1+x1²+x2² ≥ 0,也就是 ≥ 0,如果將-1放到不等式右側,那麼假設就將預測y=1,x1²+x2² ≥1,如果繪製出x1²+x2² =1的曲線,其實也就是以原點爲圓心,1爲半徑的圓。在這個圓的外面就是y=1的區域,這個圓的裏面就是y=0的區域。

通過在特徵中增加這些複雜的多項式,就可以得到更復雜的決策邊界,而不只是用直線分開正負樣本。

再次強調:決策邊界不是訓練集的屬性,而是假設本身及其參數的屬性,只要給定了參數向量θ,決策邊界也就隨之確定了。

我們不是用訓練集來定義的決策邊界,我們是用訓練集來擬合參數θ,一旦有了參數θ,它就確定了決策邊界。

如果有更高階的多項式,那麼也將得到更復雜的決策邊界,參數不同,決策邊界也會不同。

1.4 Cost Function(代價函數)

下圖是監督學習問題中的logistic迴歸模型的擬合問題:

我們有一個訓練集,裏面有m個訓練樣本,裏面的每個樣本用n+1維的特徵向量表示,同以前一樣x0=1,而且因爲這是一個分類問題,所以所有的標籤y不是0就是1。假設函數的參數是θ,對於這個給定的訓練集,我們應該如何擬合參數θ?

在之前建立線性迴歸模型的時候,我們使用的代價函數如下:

和以前略有不同的地方是,之前是1/2m,而現在將½放到求和符號裏面去了,現在用另一種方法來寫代價函數,如下圖所示:

然後稍微簡化一些這個式子,去掉這些上標,會顯得方便一些。

對這個代價函數的理解是:它是在輸出的預測值是h(x),而實際標籤是y的情況下,我們希望學習算法付出的代價。

這個代價函數在線性迴歸裏很好用,但是現在要用在logistic迴歸裏。如果我們可以最小化函數J裏面的這個代價函數,它就會正常工作,但實際上,如果使用這個代價函數,它會變成參數θ的非凸函數

非凸函數的意思是對於這樣一個代價函數J(θ),對於logistic迴歸來說,這裏的假設函數h(θ)是非線性的,如果用這個sigmoid函數計算Cost函數,再把這個Cost項代入J(θ)的式子中,畫出J(θ)圖像,就會發現J(θ)可能是下圖中的這個形狀,擁有許多局部最優值,這種函數的術語是non convex function(非凸函數)

如果你將梯度下降用在一個這樣的函數上,就無法保證能收斂到全局最小值。因此,我們希望我們的代價函數J(θ)是一個凸函數(弓形函數)。如果對一個凸函數使用梯度下降法,就能保證梯度下降法會收斂到該函數的全局最小值。

但使用這個平方代價函數的問題是,因爲假設函數h(x)是非常非線性的sigmoid函數,如果用平方函數定義它的話,這就導致了J(θ)是一個非凸函數。

所以就需要另外找一個不同的代價函數,它應該是凸函數,才能讓我們使用很好的算法(例如:梯度下降法),而且要保證能找到全局最小值。logistic迴歸的代價函數如下所示:

這似乎是一個很複雜的函數,但我們先來畫出這個函數來直觀地感受一下。假設函數的輸出值是在0和1之間的,所以h(x)的值在0和1之間變化。

理解這個函數爲什麼是這樣的一個方式是,可以先畫出logz的圖像,橫軸爲z,顯然這裏的z就是代表h(x)的角色,-logz就是翻轉一下符號,而我們只需要關心z在0到1之間的那一段。

這個代價函數有一些很好的性質。首先,你會發現如果y=1,而且h(x)=1。(也就是說如果假設函數的預測值是1,而且y剛好等於預測值),那麼這個代價值就等於0,這是我們所希望的,因爲如果我們正確預測了輸出值y,那麼代價值就應該是0。但是同樣注意,h(x)趨於0時,代價值激增,並且趨於正無窮,這樣描述給人這樣一種直觀的感覺,那就是如果假設函數輸出0,相當於我們的假設函數說y=1的概率等於0,這就好比我們對病人說,你有一個惡性腫瘤的概率是0,就是說你的腫瘤完全不可能是惡性的,然而如果病人的腫瘤確實是惡性的(即如果y最終等於1),雖然我們已經告訴了他惡性腫瘤的概率爲0,但結果卻發現我們是錯的,那麼我們就用非常非常大的代價值來懲罰這個學習算法,即這個代價值應該趨於無窮。

再來看看y=0時的代價函數圖像,

這個曲線的特點是,在h(x)趨於1時,激增並趨於正無窮,也就是說如果最後發現y=0,而我們卻非常肯定地預測y=1的概率是1,那麼我們就要付出非常大的代價值。相反,如果h(x)=0,而且y=0,也就是說假設函數預測正確,那麼代價值就應該爲0。

 

1.5 Simplified cost function and gradient descent(簡化代價函數和梯度下降)

由於y是0或1,我們就可以用一個簡單的方式來寫代價函數。具體來說,爲了避免把代價函數分成y=1或y=0兩種情況,我們要用一種方法來把兩個式子合併成一個式子,這將更方便寫出代價函數並推導梯度下降。

將y=1和y=0兩種情況分別代入合併後的Cost項,就會得到分段函數的兩種情況。

驗證結果如下:

這樣就可以寫出logistic迴歸的代價函數如下(將負號提在前面):

那麼爲什麼要把代價函數寫成這種形式?似乎我們也可以選擇別的代價函數,這裏不解釋有關這個問題的細節,但是這個式子是從統計學中的極大似然法得來的,極大似然法是統計學中爲不同的模型快速尋找參數的方法,同時它還有一個很好的性質,這樣的代價函數是一個凸函數,因此這就是大部分人用來擬合logistic迴歸模型的代價函數。

根據這個代價函數,爲了擬合出參數,需要做的是找出讓J(θ)取得最小值的參數θ。如果試着減小J(θ),就將得到某組參數θ。如果又有一個新樣本具有某些特徵x,就可以用擬合訓練樣本的參數θ來做出預測。

所以接下來就需要弄清楚如何最小化關於θ的代價函數J(θ),這樣才能爲訓練集擬合出參數θ。

最小化代價函數的方法是使用梯度下降法:

我們要反覆更新每個參數,就是用它自己減去學習率α乘以導數項,導數項的計算結果如下:

將計算的偏導數項代入原來的式子中,就可以將梯度下降算法寫作如下形式:

所以,如果有n個特徵,就有一個參數向量θ,從θ0一直到θn,那麼就需要用上圖的更新公式來同時更新所有θ的值。

可能你會發現,這個更新規則正是用在線性迴歸上的更新規則。那麼線性迴歸和logistic迴歸是同一個算法嗎?注意logistic迴歸中的假設函數和線性迴歸中的假設函數兩者的定義是不同的。

因此,即使更新參數的規則看起來基本相同,但由於假設的定義發生了變化,所以它跟線性迴歸的梯度下降實際上是兩個完全不同的東西,在線性迴歸中監控梯度下降的方法通常也適用於logistic迴歸中,在線性迴歸中的特徵縮放方法也同樣適用於logistic迴歸。

 

1.6 Advanced optimization(高度優化)

與梯度下降相比,高度優化能大大提高logistic迴歸運行的速度,也使算法更加適合解決大型的機器學習問題。現在,換個角度來看什麼是梯度下降,假設我們有一個代價函數J(θ),而我們想要使它最小化。那麼我們需要編寫代碼,當輸入參數θ時,需要計算出J(θ)以及J等於0、1直到n的偏導數項。假設我們已經完成了實現這兩部分的代碼,那麼梯度下降所做的就是反覆執行這些更新。

對於梯度下降來說,從技術上講其實並不需要編寫代碼來計算代價函數J(θ),只需要編寫代碼來計算導數項,但是如果希望代碼能夠監控J(θ)的收斂性,就需要編寫代碼來計算代價函數和偏導數項。

在寫完計算這兩部分的代碼之後,就可以使用梯度下降了。但梯度下降並不是可以使用的唯一算法,還有一些其他更高級,更復雜的算法。如果我們能計算出J(θ)和導數項的話,那麼下面的這些算法就是優化代價函數的不同方法。共軛梯度法(BFGS和L-BFGS)就是其中一些更高級的算法,這些算法需要有一種方法來計算J(θ),還需要一種計算導數項的方法,然後就可以使用比梯度下降更復雜的算法來最小化代價函數。

這三種算法有許多優點。首先是使用這其中任何一個算法通常都不需要手動選擇學習率α。所以理解這些算法的一種思路是,給出計算導數項和代價函數的方法,你可以認爲這些算法有一個智能內循環,實際上它們確實有一個智能內循環(被稱爲線搜索算法),它可以自動嘗試不同的學習速率α並自動選擇一個好的學習速率,它甚至可以爲每次迭代選擇不同的學習速率,這樣你就不需要自己選擇。這些算法實際上不僅僅選擇一個好的學習速率,而是在做更復雜的事情。所以它們收斂的速度往往遠快於梯度下降。

而這些算法的缺點就是它們比梯度下降算法複雜得多。特別是最好不要自己實現共軛梯度,L-BGFS、BFGS這些算法。Octave有一個非常理想的庫用於實現這些高級的優化算法。這些算法實現得好或不好是有區別的,如果你的機器學習應用使用的是其他語言,比如C、C++、Java等等,可能需要多試幾個庫才能找到一個能很好實現這些算法的庫。因爲在實現共軛梯度或者L-BFGS時,表現的好壞是有差別的。

現在來說明如何使用這個算法,下面舉一個例子,比如說有一個含兩個參數的問題,這兩個參數是θ0和θ1,代價函數J(θ) = (θ1 - 5)² + (θ2 - 5)²,因此通過這個代價函數,如果想將關於θ的函數J(θ)最小化的話,使它最小化的θ1的值是5,θ2的值也是5。對θ1和θ2求偏導如下所示:

所以如果想用應用高級優化算法中的一個算法來最小化代價函數J,如果不知道最小值在5,5時取到,但是想要代價函數找到這個最小值,可以用比如梯度下降這樣的算法,但最好用比它更高級的算法。需要做的就是實現一個如下圖這樣的Octave函數:

那麼實現一個代價函數比如costFunction(theta),這個函數的作用是返回兩個自變量,第一個是jVal,它是計算的代價函數J,所以說 jVal = (θ1 - 5)² + (θ2 - 5)²,函數返回的第二個自變量是gradient,gradient是一個2x1的向量,這個向量的兩個元素對應兩個偏導數項,運行這個costFunction函數後,就可以調用高級的優化函數,這個函數是fminunc,它在Octave中表示無約束最小化函數(minimization unconstrained)。

這個options變量是一個可以存儲你想要的options的數據結構,GradObj和On設置梯度目標參數爲打開,這意味着你現在確實要給這個算法提供一個梯度,然後設置最大迭代次數,比如說100,然後給出一個θ的猜測初始值,它是一個2x1的向量,然後調用fminunc函數,@符號表示指向剛剛定義的costFunction函數的指針。如果調用了這個fminunc函數,它就會使用高級優化算法中的一個,當然也可以把它當成梯度下降,只不過它能自動選擇學習速率α,然後它會嘗試使用這些高級的優化算法(就像加強版的梯度下降法)來找到最合適的θ值。

下面來演示一下如何在Octave中使用:

定義costFunction函數,它計算出代價函數jVal以及梯度gradient,gradient的兩個元素分別是代價函數對於theta(1)和theta(2)這兩個參數的偏導數。

在Octave中輸入剛剛的命令,在優化算法的options設置參數的記號:

接着初始化θ:

然後運行優化算法,就能得到theta的最優值,theta(1)是5,theta(2)也是5,這正是之前我們所希望的。functionVal的值是10的-30次冪,基本上就是0,這也是我們所希望的。exitFlag爲1,說明它已經是收斂了的。eixtFlag可以讓你確定該算法是否已經收斂。

此時的這個costFunction函數已經在當前路徑中了(或者加入在了搜索路徑裏)。

用Octave運行時,參數向量θ的維度必須大於等於2,如果它不是一個二維向量或高於二維的向量,fminunc可能就無法運算。

因此如果有一個一維的函數需要優化,可以查找一下fminunc函數的資料,瞭解更多細節。

以上就是如何優化的一個例子,這個例子是一個簡單的二次代價函數。

在logistic迴歸中,有一個參數向量theta(從θ0到θn),在Octave中向量的標號是從1開始的,所以在Octave裏,θ0實際上寫成theta(1),θ1實際上寫成theta(2)......θn實際上寫成theta(n+1)。

我們需要做的就是寫一個costFunction函數,爲logistic迴歸求得代價函數,這個函數需要返回 jVal(即J(θ)的值),還需要計算出gradient中的每個元素(也就是θ0到θn的偏導數)。

1.7 Multi-class classification:One-vs-all (多元分類:一對多)

先來看一些多類別分類問題的例子。

假如現在需要一個學習算法自動地將郵件歸類到不同的文件夾裏,或者說可以自動地加上標籤。這裏就有了一個包含四個分類的問題分別用數字1、2、3、4來代表。

另一個例子是有關藥物診斷的,假設有個病人因爲鼻塞來到診所,可能的診斷包括:y=1(沒有生病),y=2(着涼了),y=3(得了流感)。

下面是最後一個例子,如果利用機器學習來處理天氣的分類問題,那麼可能就想要區分哪些天是晴天、多雲、雨天或者下雪天。

這上述的所有例子,y都是一些離散值,例如從1到3,1到4等等,以上這些都是多類別分類問題。

對於之前的一個二元分類問題,數據集看起來是這樣的:

對於一個多類別分類問題,數據集看起來是這樣的:

用三種不同的符號來代表三個類別,問題就是給出包含三個類別的數據集,如何得到一個學習算法來進行分類呢?

我們已經知道利用邏輯迴歸解決二元分類問題,利用直線可以將數據集分爲正類和負類。利用一對多的分類思想,同樣可以將其用在多類別分類問題上。

下面介紹一對多分類的原理,有時也稱之爲“一對餘”方法,假設有一個訓練集如下圖所示:

它包含三個類別,三角形表示y=1,矩形表示y=2,叉號表示y=3,我們需要做的就是將這個訓練集轉化爲三個獨立的二元分類問題,也就是將它分成三個獨立的二元分類問題,先從三角形代表的類別1開始。

我們將創建一個新的“僞”訓練集,其中類別2和類別3設定爲負類,類別1設定爲正類,這個新訓練集如下:

我們需要擬合一個分類器,稱其爲 ,這個上標1表示類別1。這裏的三角形是正樣本,而圓形代表負樣本。可以認爲三角形的值爲1,圓形的值爲0。接着來訓練一個標準的邏輯迴歸分類器,這樣就得到一個決策邊界:

對三角形類別1進行了這樣的處理後,接着對類別2進行同樣的處理。將方形樣本設定爲正類別,將其他的樣本,三角形和叉號設置爲負類別,擬合第二個邏輯迴歸分類器,稱爲 ,上標2表示把矩形類別當作正類別,然後就會得到下圖這樣的一個分類器:

最後對第三個類別進行同樣的處理,擬合第三個分類器 ,就可以得出下圖這樣的判定邊界或者說是分類器來分開正負樣本。

總的來說,我們擬合出三個分類器來嘗試估計給定x和θ時,y = i的概率。

總結一下,我們訓練了一個邏輯迴歸分類器預測y類別y = i 的概率。最後,爲了做出預測,我們給出一個新的輸入值x,期望獲得預測,我們要做的就是在比如三個分類器運行輸入x,然後選擇預測值最大的類別,也就是要選擇三個分類器中可信度最高,效果最好的一個分類器。無論i值是多少,我們都能得到一個最高的概率值,我們預測y就是那個值。

2. 過擬合問題(The problem of overfitting)

2.1 線性迴歸中的過擬合問題

在學習算法中,諸如線性迴歸和邏輯迴歸,它們能夠有效地解決很多問題,但是,當將它們運用到某些特定的機器學習應用時,會遇到過度擬合問題的問題,導致它們表現欠佳。

首先來看一個用線性迴歸預測房價的例子,我們通過以住房面積爲自變量的函數來預測房價, 我們可以用一次函數擬合數據,這麼做我們能夠獲得擬合數據的這樣一條直線,但這並不是一個很好的模型。

通過數據可以明顯看出,隨着房屋面積增大,住房價格逐漸穩定,或者說越往右越平緩,這個算法沒有很好地擬合訓練集,我們把這個問題成爲欠擬合(underfitting),另一種說法是這個算法具有高偏差(high bias),這兩種說法都表示這個算法沒有很好地擬合訓練數據,“bias”這個詞是過去傳下來的一個專業名詞,它的意思是,如果擬合一條直線,就好像該算法有一個很強的偏見,或者說非常大的偏差,認爲房子價格和麪積線性相關,而罔顧數據的不符,先入爲主地擬合一條直線,最終導致擬合數據效果很差。

如果給假設函數加入一個二階項,用二次函數來擬合數據集,得到這樣一條曲線。

這個擬合效果很好。

另一個極端情況是,如果我們擬合一個四階多項式,那麼我們有五個參數,\Theta_0\Theta_4,這樣我們可以擬合一條曲線通過全部五個訓練樣本,可能會得到這樣的一條曲線。

一方面,這似乎很好地擬合了訓練集,因爲它通過了所有的數據點,但這是一條扭曲的曲線,它不停地上下波動,事實上,我們並不認爲它是一個預測房價的好模型,這個問題我們稱之爲過度擬合(overfitting),另一種說法是這個算法具有高方差(high variance),高方差是另一個歷史遺留說法,但從第一印象上來說,如果我們擬合一個高階多項式,那麼這個假設函數能擬合幾乎所有的數據。這就面臨可能的函數太過龐大、變量太多的問題,但我們沒有足夠的數據來約束它,來獲得一個好的假設函數。那麼這就是過度擬合。

概括地說,過度擬合的問題將會在變量過多的時候出現,這時訓練出的假設能很好地擬合訓練集,所以,你的代價函數實際上可能非常接近於0,或者就恰好等於0 ,但是你可能會得到上面的那種曲線,它千方百計地擬合訓練集,導致它無法泛化到新的樣本中,無法預測新樣本的價格,在這裏,術語“泛化”指的是一個假設模型應用到新樣本的能力,新樣本數據是指沒有出現在訓練集中的房子。

2.2 邏輯迴歸中的過擬合問題

下面是一個以x_1x_2爲變量的邏輯迴歸的例子。我們可以做的是用一個簡單的假設模型來擬合邏輯迴歸,和之前一樣,用字母g代表S型函數,如果這樣做,就會得到一個假設模型,例如這樣的一條直線來分開正樣本和負樣本。

但這個模型並不能夠很好地擬合數據,所以這又是一個欠擬合的例子。

相比之下,如果再加入一些變量,比如一些二次項,那麼就可以得到像下圖這樣的判定邊界。

這樣就很好地擬合了數據,這很可能是這個訓練集最好的擬合結果。

最後,在另一種極端情況下,如果用高階多項式來擬合數據,例如加入了很多高階項,那麼邏輯迴歸可能會變得扭曲。

它千方百計地找到一個判定邊界來擬合訓練數據,或者說努力地扭曲來符合每一個訓練樣本,而且如果x_1x_2能夠預測癌症,乳腺腫瘤可能是良性的,也可能是惡性的,這確實不是一個用於預測的好的假設模型。因此,同樣地,這又是一個過擬合的例子,是一個有高方差的假設模型,無法做到很好地泛化到新樣本。

2.3 過擬合問題的解決

在前面的例子中,當我們使用一維或二維數據時,我們可以通過繪出假設模型的圖像來研究問題所在,再選擇合適的多項式階數,以之前的房屋價格爲例,我們可以繪製假設模型的圖像。

就能看到能夠通過所有樣本點的模型,其曲線是非常扭曲的,我們可以通過繪製這樣的圖形來選擇合適的多項式階次。

繪製假設模型曲線可以作爲決定多項式階次的一種方法,但是這並不是總是有用的。事實上,更多的時候,我們的學習問題需要有很多變量,並且這不僅僅是選擇多項式階次的問題,事實上,當我們有這麼多的特徵變量時,繪圖變得更難,通過數據的可視化,來決定保留哪些特徵變量也更難。具體地說,如果我們試圖預測房價,有許多特徵變量都可能有關,這些變量看上去都與房價很有關聯。

但是,如果我們有過多的變量,而只有非常少的訓練數據,就會出現過度擬合的問題。

通常有兩個方法來解決過度擬合的問題:

第一個方法是要儘量減少選取變量的數量,具體而言,我們可以人工檢查變量清單,並以此決定,哪些變量更爲重要,哪些變量應該保留,哪些應該捨棄。或者使用模型選擇算法,這種算法可以自動選擇哪些特徵變量保留,哪些捨棄。這種減少特徵變量的方法可以有效減少過擬合的發生,但是其缺點是捨棄一部分特徵變量,也就意味你也捨棄了關於問題的一些信息,例如也許所有的特徵變量對於預測房價都是有用的,我們實際上並不想捨棄一些信息或者這些特徵變量。

第二個方法是正則化

我們將保留所有的特徵變量,但是減少量級,或參數 \Theta_j 的大小,這個方法非常有效,當我們有很多特徵變量時,其中每一個變量都能對預測的y值產生一點影響,正如我們在房價的例子中看到的那樣,我們有很多特徵變量,每一個變量都或多或少是有用的,因此我們不希望把它們舍掉。

2.4 代價函數(Cost function)

在上面的例子中發現,如果我們使用一個二次函數來擬合這些數據,我們會得到一個不錯的擬合效果,然而如果我們用一個階數過高的多項式去擬合數據,會得到這樣一條曲線,它更好地擬合了我們的數據,但實際上這個函數過擬合了,泛化得不好。

我們來想想這是爲什麼?我們不妨在函數中加入懲罰項,使得參數\Theta_3\Theta_4都非常小,這意味着什麼呢?

這是我們的優化目標或者說是優化問題,我們要最小化其均方誤差代價函數,現在我們對這個函數進行一些修改,給它加上1000*\Theta_3^2,再加上1000*\Theta_4^2,1000只是隨便一個比較大的數。

假如我們要最小化這個函數,要使這個修改後的函數儘可能小的方法只有一個,就是\Theta_3\Theta_4要儘可能小,這是因爲\Theta_3項和\Theta_4項的係數爲1000,它會使得整個函數變得很大,當我們最小化這個新函數,我們需要使\Theta_3儘量接近於0,還要使\Theta_4也儘量接近於0,這就好像我們直接去掉了這兩項一樣,那麼,這樣的話,這個函數還是相當於二次函數,最後我們擬合數據的函數實際上是一個二次函數,加上了一些非常小的項,\Theta_3\Theta_4它們都非常接近於0,最後我們得到的還是一個二次函數,這很好,因爲這是一種更好的假設模型。

在這個特定的例子裏,我們看到了加入懲罰,增大兩個參數所帶來的效果,總的來說,這就是正則化背後的思想。

這種思想就是,如果我們的參數值較小,參數值較小意味着一個更簡單的假設模型,在上面的例子中,我們對\Theta_3\Theta_4加入了懲罰項,當他們都接近於0時,我們會得到一個更簡單的假設模型,就相當於一個二次函數,大體上來說,如果將這些參數都加上懲罰項,這麼做就相當於儘量去簡化這個假設模型,因爲這些參數都接近0的時候,比如在這個例子中,它就是一個二次函數,但是一般來說,這些參數的數值越小,我們得到的函數就會越平滑,也越簡單,因此,也更不容易出現過擬合的問題。

再來看一個具體的例子,比如房屋價格的預測

之前提到,可能有100個特徵,x_1代表房屋的尺寸,x_2代表臥室的數量,x_3是房屋的層數,等等,這種特徵可能有100個。和之前多項式的例子不同,我們並不知道\Theta_3\Theta_4是高階項,想象一下,你有一個袋子,袋子裏有100個特徵,我們很難預先挑選出其中的哪個變量是相關度較低的,現在我們有101個參數,我們不知道該選出哪些參數來縮小它們的值,因此在正則化中,我們要做的就是對代價函數進行修改,來縮小所有的參數,因爲我根本不知道,我該選哪些參數去縮小,於是我在代價函數的後面添加一個新的項。

當我在式子的最後加一個額外的正則化項(紅色方框)來縮小每個參數的值,添加的項的作用是縮小每一個參數,從\Theta_1一直到\Theta_1_0_0,順便說一下,按照習慣,求和是從參數\Theta_1開始的,並沒有給\Theta_0增加懲罰項,這實際上是約定俗成,只對從1到n進行求和,而不是從0到n進行求和,但在實踐中,這兩種做法沒什麼差別,無論你是否包括\Theta_0,實際上對結果影響都不大,但一般來說,我們只對\Theta_1\Theta_1_0_0進行正則化。

在正則化代價函數中,紅色方框這一項就是我們的正則化項,而這裏的λ被稱爲正則化參數

這個λ的作用就是控制兩個不同目標之間的取捨,第一個目標與目標函數的第一項(紅色方框內)有關,就是我們想去訓練,想更好地擬合數據,更好地擬合訓練集。

而第二個目標就是我們要保持參數儘量地小,與目標函數第二項有關,與正則化目標有關,這個λ,也就是正則化參數的作用是控制這兩個目標直接的平衡關係,即更好地去擬合訓練集的目標和將參數控制得更小的目標,從而保持假設模型的相對簡單,避免出現過擬合的情況。

比如這個房屋價格預測的例子,如果之前我們用高階多項式來擬合,最後會得到一個圖像非常曲折的函數。

如果你依然想保留所有特徵的高階項,你只要確保利用正則化目標就能得到這樣一個曲線。

這個曲線並不是一個二次函數,但是卻相對更平滑,更簡單,對數據給出了一個更好的假設模型。

在正則化的線性迴歸中,如果正則化參數λ被設得太大的化,其結果就是,如果我們的假設函數是

我們對這些參數還有\Theta_1\Theta_2還有\Theta_3\Theta_4的懲罰程度太大,那麼最後所有這些參數都接近於0,這樣的話,就相當於把假設函數的全部項都忽略掉了,最後假設模型只剩一個\Theta_0,這樣就相當於房屋價格直接等於\Theta_0,這差不多相當於用一條直線去擬合數據。

這就是一個欠擬合的例子,它只是一條水平的直線,並沒有去貼近大多數的訓練數據。換句話說,這個假設模型的偏見性太強或者說偏差太高,簡單地將房屋價格等同於\Theta_0這樣一條水平的直線,顯然與數據的趨勢不符,爲了讓正則化起到應有的效果,需要選擇一個合適的正則化參數λ。

2.5. 線性迴歸的正則化

這是之前提到的正則化線性迴歸的優化目標,前面一部分(紅色方框內)是線性迴歸的一般目標。

剩下的部分就是一個額外添加的正則化項,其中λ是我們的正則化參數。

我們想找到一個參數θ,來最小化代價函數,也就是這個正則化代價函數J(θ)。

之前,我們在沒有正則化項的情況下曾使用梯度下降法來最小化最初的代價函數,也就是下面這種算法:

在沒有正則化項的情況下,進行常規的線性迴歸,我們會用上式反覆去更新參數\Theta_j的值,其中j的值是0到n。

現在單獨寫出j=0時的更新函數。

這樣做的原因是,對於正則化線性迴歸,我們的懲罰對象是參數\Theta_1\Theta_2,...,\Theta_n,我們沒有懲罰\Theta_0,所以當我們修改這個正則化線性迴歸的算法時,在處理\Theta_0的時候,會將它區別對待,具體地,如果我們要用正則化項修改這個算法,我們需要做的就是把下面的這項做如下修改,我們要在式子的後面加上一項。

這樣做的話,就可以對正則化代價函數J(θ)用梯度下降法進行最小化。

如果仔細觀察\Theta_j的更新,會發現一些很有趣的東西。具體地,如果把這些包含\Theta_j的項全都匯合起來,那麼我們可以把這個更新值,等價地寫成如下形式:

這裏的這一項

(1-\alpha \frac{\lambda }{m})是個很有趣的項,它能起到一種很有趣的效果。

具體來說,這一項的值是一個只比1略小一點的數,因爲\alpha\frac{\lambda}{m}是一個正數,通常來說,學習率很小,但m卻很大,所以\alpha\frac{\lambda}{m}就會很小,所以這一項(1-\alpha \frac{\lambda }{m})通常是一個只比1略小的數,例如0.99這樣的數,所以\Theta_j更新的結果就是\Theta_j變成了\Theta_j乘以0.99,也就是把\Theta_j向0的方向縮小了一點點,這使得\Theta_j變小了一點點,說得更正式一點就是\Theta_j的平方範數變小了,即變小了。然後這裏的第二項(下圖)實際上完全與我們在添加正則化項之前的梯度下降更新一樣。

當我們在進行正則化線性迴歸時,我們要做的就是每次迭代時都將\Theta_j乘以一個比1略小的數,我們每次都把參數縮小一點,然後進行和之前一樣的更新操作。當然,這只是從直觀上來理解這個更新做了什麼。從數學的角度來看,我們做的就是對代價函數J(θ)進行梯度下降。

梯度下降只是我們擬合線性迴歸模式時所講的兩種算法的其中一個,而第二種算法是用正規方程來解決。我們的做法就是建立一個設計矩陣X,它的每一行都代表一個單獨的訓練樣本,然後建立一個向量y,向量y是一個m維的向量,它包含了訓練集裏的所有標籤。所以X是一個m x (n+1)維的矩陣,y是一個m維的向量爲。

爲了最小化代價函數J,我們發現一個可行的辦法就是讓θ等於下面這個式子:

這個計算出來的θ可以使得代價函數J(θ)最小化,這時J(θ)是沒有正則化項的,我們現在用正則化來得到想要的最小值,方法就是將對各個參數的偏導數設爲0,然後進行一些數學推導,然後你可以得到上面的這個式子,使得代價函數最小,具體來說,如果你使用正則化,那麼式子就要做如下改變。

這個矩陣除了最左上角的元素是0外,其餘對角線元素都是1,然後其餘的元素都是0,舉個具體的例子,如果設n=2,那麼這個矩陣就是一個3x3的矩陣,即

一般來說,這個矩陣是個(n+1) x (n+1)維矩陣。

如果使用新定義的包含正則化目標的J(θ),那麼這個計算θ的式子,可以得到J(θ)的全局最小值。

最後再談談不可逆的問題,這是比較高等的數學問題。假如說現在m的值,即樣本的總數小於等於特徵的數量n,如果你的樣本數量比特徵數量少,那麼這個矩陣 是不可逆的,或者說是個奇異矩陣還,有一種說法就是這個矩陣是退化的。如果在Octave中用pinv函數運行它,求它的僞逆矩陣時,它看起來好像能給出正確的結果,但最後不會得到很好的假設模型。儘管從數字上來說,Octave的pinv函數會給你一個看起來有意義的解,如果你用不同的語言來運行,如果你只是求它的常規逆矩陣,也就是對應Octave的inv函數,也就是我們對X的轉置乘X取逆矩陣,那麼這種情況下,你會發現X的轉置乘X是個奇異矩陣,是不可逆的,如果你用另一種編程語言,用其它的線性代數庫來試圖計算這個矩陣的逆矩陣,你會發現都沒有結果。因爲這個矩陣不可逆,是奇異矩陣。幸運地是,在正則化中已經考慮到了這個問題。

具體來說,只要正則化參數λ是嚴格大於0的,我們就可以確信X的轉置乘X加上λ乘這個有趣的矩陣一定不是奇異矩陣,因爲它是可逆的。因此,進行正則化還可以解決一些X的轉置乘X出現不可逆的問題。

3. logistic迴歸的正則化

對於邏輯迴歸問題,曾經談到過兩種優化算法,一種是用梯度下降來優化代價函數J(θ),還有一種是更高級的優化算法,這些算法都需要你去想辦法計算代價函數J(θ),想辦法去計算函數的導數。

我們之前看到邏輯迴歸也會出現過擬合的情況,如果你用高階多項式去擬合數據,這個g是一個S型函數,這時候你會得到這樣一個假設模型,其判定邊界看起來非常複雜且扭曲,對於這個訓練集來說,這實在不是個好的假設函數。通常情況下,如果你的邏輯迴歸有很多特徵,有無關緊要的多項式,這些大量的特徵最終會導致過擬合的現象。

這是邏輯迴歸代價函數

爲了使用正則化,我們需要將它做一些修改,我們需要做的就是在後面增加一項:

這一項的作用是懲罰參數\Theta_1\Theta_2直到\Theta_n,防止它們過大,這樣做的話,產生的效果就是,即使當你擬合階數很高且參數很多,只要添加了這個正則化項,保持參數較小,你仍然可以得到這樣一條粉紅色的曲線,顯然這條邊界更能合理地劃分正樣本和負樣本。

因此,使用正則化的話,即使你有很多特徵,正則化都可以幫你避免過擬合的現象,我們究竟該如何實現它呢?對於最初的梯度下降算法,這是我們之前的更新式:

我們通過這個式子反覆更新\Theta_j的值。在這裏,把\Theta_0的更新單獨寫出來。

爲了修改這個算法,使之成爲正則化代價函數,接下來需要做的和對線性迴歸所作的處理很類似,只需將第二個式子修改成下式:

我們再次發現它看起來真的很像我們之前線性迴歸的式子。但當然,它們不是同一個算法,因爲現在假設模型是這樣定義的

,這與之前的正則化線性迴歸並不是同一個算法,因爲它們的假設模型不一樣,儘管這個迭代公式表面上看起來和之前的正則化線性迴歸的梯度下降算法很相像。

簡單地總結一下,在方括號中的這一項是什麼呢?

它是新定義的代價函數J(θ)對\Theta_j的偏導數,這裏的J(θ)是之前所定義的正則化的代價函數。這就是正則化邏輯迴歸的梯度下降算法。

接着來看如何在更高級的優化算法中使用正則化,提醒一下,對於這些高級算法,我們要做的就是,我們需要自己定義一個函數,這個函數以向量θ作爲輸入。

再次說明,在我們寫下的這個等式中,向量下標是從0開始的,也就是從\Theta_0\Theta_n,但是在Octave中,向量的下標一般從1開始,\Theta_0在Octave中寫成theta(1),\Theta_1寫成theta(2),以此類推,一直寫到theta(n+1)。而我們需要做的就是建立一個函數,一個叫costFunction的函數,然後將它賦給,之前講過的fminunc函數中,在括號裏寫上@costFunction,fminunc的意思是函數在無約束條件下的最小值,因此fminunc函數會將costFunction最小化,costFunction函數會返回兩個值,第一個是jVal,所以我們需要寫代碼來計算代價函數J(θ)。我們正在使用正則化邏輯迴歸,代價函數J(θ)也會有所改變,代價函數需要在後面增加一個額外的正則化項,當你在計算J(θ)時,確保你的函數後面有這一項。然後函數的另一個返回值是梯度,所以gradient(1)等於J(θ)對\Theta_0的偏導數,之前已經計算過,對\Theta_0的偏導是,它沒有發生改變,因爲相比未添加正則化項時,\Theta_0的導數並沒有發生改變,但是其它項都發生了改變。舉個具體的例子,比如對\Theta_1的導數,之前也推導過,它等於原本的項加上 \frac{\lambda }{m}\Theta_1,即

當運行costFunction後,對它調用fminunc函數,或者其它類似的高級優化函數,這將最小化新的正則化代價函數J(θ),而函數返回的參數代表的就是正則化邏輯迴歸的解。

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