- 深度學習技術圖像處理入門
- 楊培文
- 10447字
- 2019-12-06 14:13:41
2.3 數據挖掘與訓練模型
我們在前面預覽環節中,通過特征兩兩組合展示,以及主成分降維的方法,已經對數據有了初步的認識。但是這種認識,不等于明確的分類標準,真正用于實戰中的模型,還是需要使用監督學習方法。接下來的內容,將介紹監督學習的一個基本流程。
2.3.1 第一步,準備數據
這一部分包括兩部分的內容,一是將所有數據劃分訓練集、驗證集與測試集,二是進行數據的標準化。
首先解釋一些名詞,即什么是訓練集、驗證集與測試集。如同前面提到的,監督學習就是一種唯分數論的應試教育,準確率越高越好,正如學生考試成績越高越好一樣。那么提高應試教育考試成績的方法,同樣也可以用在監督學習上,那就是題海戰術。在題海戰術的過程中,老師會拿一堆卷子給學生做,有的作為家庭作業,有的作為階段性考試,如周考、月考等,最后留一些題目用在期末考試中,參見表2-3。
我們不妨把機器學習模型理解成做題的學生。平時學生做作業時是允許參考題目答案的,這也有助于學生理解解題思路;而有監督的機器學習模型在訓練過程中,同樣需要一份“題目”和“答案”,比如鳶尾花數據集中,150個樣本就相當于150個考題,每個題目給出四個特征,要模型預測分類結果,參考答案這里也一并給出,讓模型在訓練階段中不斷地“對答案”,訓練高分模型。
當然,這樣做有一個問題,學生如果直接抄答案,作業會完成得又快又好,如何讓這部分學生現行?考試,考試題不附有參考答案,抄作業的就現行了,所以老師會不斷地進行小范圍階段性考試,檢驗學生的學習效果;有監督的機器學習也是一樣,會使用驗證集檢驗學生的學習效果,確認模型對于未知數據也有很好的表現。
最后,階段測試考得再好,期末考試或者高考這樣的大型考試沒考好也沒有用。這種大型考試不是給學生來學習的,而是用來排名比較的;機器學習最終的模型好不好,也需要看它在測試集上的表現,拋開其他一切因素,99.95%的準確率就是比99.94%的準確率要好。
表2-3 將機器學習模型理解為做題的學生

通常情況下,數據的所有者在拿到完整數據后會進行第一次劃分,分出初步訓練集以及測試集,將初步訓練集的數據和結果以及測試集的數據交給數據科學家,然后自己留下測試集的分類結果,將用于評價不同數據科學家、不同模型提交的準確率。數據科學家拿到初步訓練集后進行第二次劃分,分出訓練集以及驗證集,用于訓練模型以及對模型進行自我評價。
我們以題海戰術為例,讓大家更容易理解數據劃分的目的,繼而在收集數據、劃分數據時要做到符合以下常識:
(1)題目和答案要有關系。同樣,收集到的數據特征也必須和數據要預測的東西有關系。當然,這里并不要求所有數據都有關系,可以有冗余,也可以有干擾項。確認這一點的一種簡單方法是,將這些數據給這個領域的人類專家,如果他可以對結果做出判斷,那么機器就可以。
(2)合理劃分作業和測試的比例。比如做單選題,如果只選ABCD后對答案,不思考背后的原因,可能做一份卷子和做一百份卷子沒有什么區別,答案對多了還可能會得出“三長一短選最長”這種結論。同樣,只做作業不考試,可能會在學習方法上產生方向性的錯誤。機器學習也一樣,手里拿到一些數據之后,不妨將70%拿來作為訓練集(家庭作業),30%拿來作為驗證集(小測)。題海戰術的題目,要盡量保證不同題型在作業和考試中一致,同樣,不同種類的數據,在訓練集驗證集中的比例也應當保持一致。
(3)避免題目泄露。測試集中的數據不應出現在訓練集和驗證集中。
數據科學性除了需要合理進行數據集的劃分之外,還需要對數據進行標準化操作。具體而言,就是很多樣本通過減平均值、除標準差的方法將數據變成標準正態分布。這種做法的主要原因是,在訓練數據的過程中,模型的參數會不斷調整,而調整過程中,同樣調整100,如果特征A的平均值是1,這個調整幅度就會顯得過大,而對于平均值是10000的特征B而言,這個調整幅度就會顯得過小,模型會浪費大量時間去適應不同特征的分布,從而影響訓練的收斂速度。因此如果這里統一成平均值是0、方差為1的標準正態分布,會減小訓練開銷,得到更好的訓練結果。這一點在深度學習圖像處理中尤為關鍵,因為圖像的像素值大小是0~255,如果直接使用則距離計算機喜歡的標準正態分布有些差距,所以通常會將像素范圍調整在[-1, 1]之間,或者直接處理成標準正態分布。
這里需要注意,在實際處理過程中,初學者容易忽略的一點是對訓練集、驗證集、測試集分別計算不同的平均值與標準差,然后分別減平均值除標準差。這里應該統一減去訓練集的平均值和標準差,因為首先我們可以認為是從訓練集中估計了整體分布的特點,其次這樣做也避免了引入更多驗證數據后平均值標準差變化造成的影響。
最后我們放上sklearn在這一部分的用法:

2.3.2 第二步,挖掘數據特征
特征工程是整個建模過程的重中之重,通常建立一個數學模型,70%以上的時間都是投入在數據挖掘環節中的。
我們挖掘特征的原因是為了讓計算機可以更好地理解數據。要想讓計算機理解數據,數據科學家就需要首先理解數據。這種理解,在實際運用的過程中是離不開具體業務邏輯支持的。例如,醫學領域的統計學家統計了各種療法對降低血糖的效果,希望建立一個推薦高血糖治療方法的模型,最后發現打胰島素見效快、效果好。而在實際的醫學臨床實踐中,打胰島素是最迫不得已的一種治療方法,如果有更好的選擇,醫生絕對不會推薦這種方法。因此,雖然現階段人工智能不斷地在各個領域取得很好的表現,但是如果想要在復雜的應用場景落地,還是需要有人類專家的支持與幫助。
正是由于這一部分內容涉及面太廣,不屬于入門內容,并且我們后文的深度學習部分主要強調的是用深度神經網絡自動挖掘特征,因此這部分內容將用最簡單的例子講一講。
在二維平面上以原點為圓心,在兩個圓環的范圍分別隨機生成與原點距離不同的兩組點。其中里面圓環上的點是第二組,外面圓環的點是第一組。我們看看如何挖出一個簡單的、線性可分的特征來區分這兩組點:


看圖應該更加直觀:

其結果如圖2-10所示。

圖2-10 查看分布點
對特征組合做圖發現,如果使用單一特征的話,二者是混合在一起的。兩個特征直接進行組合的話,二者之間仍然線性不可分——兩個分類被一個圓形隔開了,一條線性的直線切不開兩者。
sns.pairplot(pd_circ, hue="label")
其運行結果如圖2-11所示。

圖2-11 運行結果
這時可以手動進行一些特征工程。簡單試一下加法和乘法(X+Y、X*Y),由于和圓形有關,我們再試下X*X+Y*Y:

其運行結果如圖2-12所示。

圖2-12 X*X+Y*Y的結果
注意右下角的圖會發現,我們挖掘的X*X+Y*Y這個特征,單獨一個特征已經是線性可分的了,這極大地降低了計算機模型將二者分開的難度。
讀者可能會問,難道計算機只認識線性可分、不認識圓形邊界嗎?如果有成百上千個特征,難道數據科學家在成百上千個特征基礎上手動組合各種可能性?實際上計算機當然可以認出圓形的邊界,這里只是很簡單的特征工程例子,計算機同樣可以借助數學模型實現。比如這里圓形邊界的例子,就可以通過計算兩個類群的高斯分布特征,進而借助高斯核函數實現分割:



以高斯分布來擬和各個類群XY的分布,繼而通過高斯分布給出的概率得出的分類結果是pred列,而pred列中給出的結果與實際結果是基本符合的。可見借助算法模型,計算機可以實現多個特征的組合。但是這種組合往往缺乏針對性,如果人類專家能在此手動挖掘幾個關鍵特征,“提示”計算機一下,將更加可能得到好的結果。比如計算機并不直接認識文本、年月日、經緯度、人物關系等,需要人類專家在現有數據基礎上,根據需要做一些基本轉換,這些信息才可以被有效利用。
最后說兩點在實際特征工程進行中入門者需要注意的事項:
(1)對于離散特征,使用one-hot編碼。
例如,對于這種輸入:

我們想用數字來表示職業。很多初學者會用這種錯誤的方法來表示:

這種方法錯誤的原因是,如果用連續的數字來表示不同職業,計算機會認為這些數字存在大小關系,由于1<2<3,因此工人<農民<軍人,這種觀點當然是錯誤的,所以這里相當于是給了模型一個經過錯誤處理的輸入數據。對于這種情況,我們使用one-hot編碼來表示。如果用one-hot,這里正確的表示方法就是某個人是不是工人、是不是農民、是不是軍人:


(2)特征工程其實是個頭腦風暴的過程。在開始階段,特征要盡可能多,到了后期,則要盡可能地選擇最重要的特征用于模型訓練。這種選擇可以通過在模型中引入正則化來完成,至于多保留特征還是多舍棄特征,這里可以通過調整正則化常數來實現,調整結果的好壞可以進一步在驗證集中的表現來確認。
初學者可能會忽略這一點,看見模型預測準確率在訓練集中很高,一看準確率99%就以為訓練成功,忘記在驗證集中確認模型的表現。如果此時驗證集的表現并不好,數據就發生了過擬合現象。我們用應試教育的例子來類比的話,一個學生平時作業準確率很高,他的學習方法就是“背答案”,而且背得很準,見過的題目全部都知道答案,但是題目稍微變一下,就不會做題了,于是考試時拿到新題目,準確率就下來了。這種現象歸根結底是無法很好地適應未知情況。
同樣,用監督學習的名詞來替換應試教育,見過的數據都能預測對,沒見過的準確率大幅降低,這種情況也是由于數據不能合理地適應未知情況。這種模型并不是我們需要的結果。
最后,過擬合的前提是,學生平時成績很好,考試沒發揮好。如果平時成績就不好,考試也沒考好,這種情況屬于欠擬合。如果發生欠擬合,引入正則化就不是那么緊迫了,我們應該更多關注關鍵特征是否被正確挖掘、模型是否合理、數據是否充足等。我們舉一個多項式回歸的例子,圖中是在用多項式擬合加入噪聲的cos曲線的一部分,左圖是一次多項式擬合,顯然由于一次多項式是線性的,擬合曲線肯定不夠合理,于是發生了欠擬合;中間的使用4次多項式,看起來不錯;而右邊的十次多項式擬合十個點,結果看起來誤差更小、更完美。但是假如再從cos函數中抽取若干點,這條線擬合的效果就會差很多,因此屬于過擬合的情況,需要用正則化減少多項式的次數。有關正則化具體如何實現,下一部分講解使用模型時將進一步介紹。

其運行結果如圖2-13所示。正則化系數過高(左)、過低(右)都會影響擬合的效果。

圖2-13 多項式曲線擬合過程中引入正則化
2.3.3 第三步,使用模型
這一步就是大家通常所說的“調(diao)包”以及“調(tiao)參”了,即調用算法包中的現有模型,通過調整模型參數,使模型在數據集中得到較好的表現。本書主要介紹的深度神經網絡也是一種模型,后文將會詳細介紹這一點。
經常有人說機器學習從業人員就是在調包和調參,這個觀點其實是值得商榷的。因為首先如上文所述,有經驗的數據科學家在拿到數據后,主要的精力是放在數據挖掘上,再進一步說,如果考慮數據的收集環節,那么數據科學家大部分精力并不是放在模型上,而是放在數據的收集、整理、清洗環節上。
給這種現象再深挖一層原因,這個問題其實出在監督學習有明確的評價標準上。由于標準明確,因此機器學習就有了套路,然后這個套路就被理解成了調包、調參。這個標準就是模型給出的結果和實際結果是否一致。這是一個很好理解的標準,比如老師要培養學生的個人品質、人生觀、價值觀,可能并不是一件容易的事情,如何培養一句話說不清楚;如果老師要提高學生考試成績,就相對容易了許多,因為考試有明確的范圍以及評價標準,只需要關注這部分內容對癥下藥即可,如同機器學習從業人員為了提高模型表現,使用不同模型、調整不同參數一樣,雖然不好做,終歸還是有套路的;如果要讓模型打游戲,模型就需要對游戲中各種行為的收益做一個衡量,此時模型也沒有公認明確的量化指標,而是上升到“人生觀、價值觀”的層面了,評價模型就如同評價學生個人品質一樣,同樣也是一句話說不清楚的。
這里將從評價標準講起,從后往前簡單說一下這部分內容。首先簡單介紹邏輯回歸的公式,進而根據評價標準講一下模型的損失函數問題,最后說一下上一步的正則化如何影響這里的損失函數。由于本書的入門性質,我們仍然選擇簡單的講,這里主要介紹邏輯回歸模型。
1.邏輯回歸的公式表達
雖然名字帶了回歸,但事實上,這里邏輯回歸是一個有監督的分類問題。我們具體看一下邏輯回歸做了什么。
接下來,本書將推出一些公式。初學者可能最怕的就是滿篇的公式,為了方便讀者理解,這里從高中課本開始說起。高中課本中有一個“一元二次回歸”,形式如下:

注意,高中課本上的x和y是一個數字,而實際上這里的x可以是一個長度是m的向量(vector)。背后的數學意義是,之前預測y只考慮一個因素,這里考慮m個因素,而這里的m個因素就可以是鳶尾花數據集中的四個特征(m = 4):

這里的公式用向量的形式重新定義:

其中

注意,向量通常是豎著寫的,這里用了轉置將其變成橫向,讀者或許有點懵,簡單講一下。首先,這里為了簡化,向量ω里面多了一位b,x里面多了一位1,這樣就可以把常數項放進來,使公式更加簡潔。其次,這里使用了線性代數中矩陣的乘法,由于我們的結果y只有一個數字,不妨認為它就是一個1×1的矩陣。根據矩陣乘法的原則,兩個矩陣相乘,前面一個的行數定義結果有多少行,后面一個的列數定義結果就有多少列,所以m+1行1列的ω要變成1行m+1列的形式
,這樣結果才會是1×1的結果。
邏輯回歸做的就是對這個結果進一步變化:

我們關注f(x) = sigmoid(x)的形式:

其實對于絕大多數的輸入x(絕對值大于5),sigmoid函數都會返回一個非常接近0或者1的結果,只有x取值范圍在[-5, 5]之間時才會是其他值。正是由于這種特性,我們可以近似認為sigmoid函數的返回值就是0或者1,這種離散化就是邏輯回歸“名曰回歸,實則分類”的原因——我們就可以認為,這里的y代表了某個樣本是否屬于某個分類的概率,例如鳶尾花分類問題,對一個樣本,我們可以對四個特征先進行線性回歸,算出一個數,再進一步進行邏輯回歸,判斷這個樣本屬于某一分類的概率。注意,這里真實的y是一個非0即1的數字。我們預測的結果?則是邏輯回歸函數的縱坐標——取值范圍[0,1]的一個概率值。
此時,讀者心里可能會有一個疑問:邏輯回歸函數中的ω是怎么算出來的?可以猜嗎?這里確實需要猜一下,其中的算法大概是這樣的:
(1)隨機初始化一組ω,比如可以全部設為0,當然實際上不推薦這樣。
(2)在訓練集中,向邏輯回歸函數里輸入特征x,計算,得到預測結果
。
(3)計算全部訓練集中邏輯回歸的結果和實際y的差別。
(4)根據上一步的差別更新ω。
(5)重復(2)~(4)若干次(iterations)。
2.損失函數——如何表示預測?和實際y之間的差別
回顧一下我們現在會做什么。首先,猜一組數字,當然會做(當然第5章講述卷積層時還會介紹深度神經網絡中隨機初始化需要注意的事項)。其次,乘法、加法和sigmoid函數也會寫,關鍵是第三步和第四步,如何表示預測和實際y之間的差別,邏輯回歸這里引入了交叉熵的概念。
關于交叉熵的相關概念,首先這里的熵指的是信息熵。信息熵是對不確定性的衡量,具體而言,這里引用吳軍老師《數學之美》一書中的一段描述:
當我錯過了上一屆世界杯的比賽,而想知道誰奪得冠軍時,我詢問一個知道比賽結果的觀眾。但是他并不愿意直接告訴我,而是讓我猜測,每猜一次他要收費1元來告訴我,我的猜測是否正確。那么我要花多少錢才能知道誰是冠軍呢?
我可以把球隊編號,1到32號(當然大家都知道世界杯是32支球隊,然而過幾年變成48支的時候我會回來修改的)然后我提問:“是在1到16號中嗎?”。如果他告訴我猜對了,我會繼續問:“是在1到8號中嗎?”。這種詢問方式大家都懂,因此這樣詢問下去,只需要5次,也就是只需要5元錢就可以知道哪支球隊是冠軍。
因此,世界杯冠軍這條消息的信息量可以看作是5元錢。我們回到數學上的問題,使用比特來代替錢的概念(計算機中,一個比特是一位二進制數,一個字節就是8個比特),這條信息的信息量是5比特。如果有64支隊伍,就要多猜一次,也就是6比特。
可見這里參賽球隊越多,冠軍歸屬這條消息的信息熵就越高。同時也要注意,這里信息熵的求法,背后的假設是各球隊奪冠的概率相等,而實際情況并非如此,雖然64支隊伍參賽,但具備奪冠實力的球隊只是個位數,因此實際的信息熵是低于這個數字的。
解釋完信息熵,我們再來談一談什么是交叉熵。交叉熵用來衡量兩個正函數是否相似,對于兩個完全相同的函數,它們的交叉熵等于零。如果是考慮分類問題中預測的概率?和實際概率y之間的差別,當預測的概率與實際情況一致時,交叉熵即為0。具體對某個樣本而言,定義其交叉熵為:

這里的K代表K個最終分類,如鳶尾花數據集中最終對三種花分類,則K=3。
如果是二分類的情形,此時K=2,就有:

我們簡單地預覽一下二分類情況下交叉熵的性質,如果真實的分類結果是y=0,我們看看不同的?下交叉熵的取值:
y = 0 np_yhat = np.linspace(0, 1, 101) np_h = -(y*np.log(np_yhat) + (1-y)*np.log(1-np_yhat)) plt.plot(np_yhat, np_h)

可見我們預測的?和真實的y越接近,即預測得越準確,交叉熵將會越接近0。相反,如果預測值?和真實的y完全相反,實際不是這種分類情況(y = 0),預測時卻100%判斷是1(? = 1),交叉熵的值就會接近正無窮大。
以上內容只是考慮一個樣本的情況。當考慮多個樣本時,每個樣本都可以計算一個交叉熵,此時就可以用全部樣本的平均交叉熵作為損失函數(Loss function)來衡量模型預測的準確程度:

簡單回憶一下,最右邊的式子中總共有N個樣本K個分類,在鳶尾花數據集中,就是N=150、K=3。yik是第i個樣本第k個分類,如果這個樣本屬于第0個分類,那么yi,k=0=1,yi,k=1,2=0。ω一共有K組,每組都是長度為M+1(M是特征數,如鳶尾花數據集M=4)的向量。在實際計算中,ω真正需要K-1組即可,比如二分類的話,預測一類后另一類的概率也就知道了,由于只預測一類,因此使用一組ω即可。
可能讀者被這里的數學公式給嚇到了,再用通俗一點的語言簡單進行總結。其實這里需要交叉熵回答的問題是對于每個樣本的分類結果,模型給出的預測與實際情況有多大的區別。所以我們可以將交叉熵理解成機器學習模型的KPI、GPA這樣的可量化考勤指標,模型每預測一次,就用交叉熵來考勤一次。如果模型的考勤結果不好怎么辦?如何改進下一步的工作?請看下一部分內容。
3.如何根據預測?和實際y之間的差別更新參數ω
此時,我們就得到了第三步中“計算全部訓練集中,邏輯回歸的結果?和實際y差別”。我們可以基于這種差別,進一步更新ω的值:

其中,t代表迭代次數,因為這里更新值并不是一步完成的,可能迭代了上百次;α是學習率,用來控制迭代的步長,這里需要根據數據進行一定調整,過小會導致訓練緩慢,過大則會造成結果精度不足。
剩下的問題就是求偏導數了。這里引入鏈式求導法則。為了簡化操作,這里只考慮K=2,即二分類情況,有:

進一步化簡,將yi進行向量化、將xi進行矩陣化以消除求和項:

進行簡單的化簡,令:

利用導數的定義以及鏈式求導法則,則有:

根據:

帶回公式,化簡得到:

這里繼續來拯救被公式嚇懵的讀者。前面說到交叉熵損失函數實際就是KPI、GPA這樣的量化考勤指標,如果想提高得分,應該怎么辦?最簡單的方法就是看看指標中哪一項得分低——比如考試分數,數學考了99分、英語60分,我們就可以認為數學成績相比100分滿分的差距()是1、英語是40,那么想提高考試成績的話,下一階段就需要將主要的時間精力放在英語上。我們也不能在下一階段學英語學得太猛而影響總體成績,所以需要乘以一個學習率α。
4.幾點思考
至此,我們完成了邏輯回歸的主要理論部分。如果讀者沒有被公式繞暈、堅持到了這里,就從邏輯回歸的理論出發,簡單談談其他的監督學習公式。首先回顧一下邏輯回歸的步驟:
(1)隨機初始化一組ω,比如可以全設為0,當然實際上不推薦這樣。
(2)訓練集中,在邏輯回歸函數里輸入特征x,計算,得到預測結果?。
(3)計算全部訓練集中,邏輯回歸的結果?和實際y差別。
(4)根據上一步的差別更新ω。
(5)重復(2)~(4)若干次(iterations)。
現在的問題是,如果要改動這幾個步驟變成一個新算法,可以怎么改?我們注意到,實際上可以改動的地方主要是第二、三步,也就是說,可以有這些思路:
- 預測結果時,把邏輯回歸sigmoid函數換成一個其他的函數。
- 計算損失時,換成一個損失函數。
這兩個步驟通常是同時變換的,在算法層面二者共同推導得到。如支持向量機,就是把邏輯回歸的sigmoid函數換成核函數,損失函數由平均交叉熵換成了不同分類的距離間隔。又如樸素貝葉斯,預測結果基于概率判斷,損失函數同樣基于概率判斷。本書不再重點討論這部分內容。
本書后面內容將詳細介紹的深度學習算法則基本沿襲了邏輯回歸的思路,只改了步驟(2),將原本一個邏輯回歸函數變成幾十個函數的嵌套,然后利用鏈式求導法則對嵌套的幾十個函數進行反向求導,得出損失函數。然后對其他步驟做了一些工程創新,使其可以適應更大規模數據。
5.正則化
前面提到,過多的參數會導致過擬合,因此可以在規定損失函數的時候,將這一點考慮進來:
Loss =正則化系數(C) ×分類準確率罰分項+過多參數罰分項
在上一步中其實也注意到,邏輯回歸隨機了一個初始化的系數ω后,接著借助求導進行梯度下降,就可以得到最終解,需要的額外參數只有α。而實際工程運用中,借助libfgs sag等梯度下降求解工具,我們甚至也不需要提供α值。因此似乎邏輯回歸不需要提供額外的超參數。實際上,如果考慮正則化,就需要關注正則化系數C的影響。因此,邏輯回歸調參主要調的就是這里的C值,過小的C會過度強調罰分項的損失而非對模型預測結果的關注,造成欠擬合,而過大的C則會過分強調結果,可能會造成參數數目過多,進而造成過擬合。
這里的過多參數罰分項有兩種比較常見。
一種是各項系數的絕對值相加,即L1正則化:

另一種是使用L2正則化:

此時,求導的話,導數將會分別變成:


這里sgn(ω)代表ω正負號。
繼續拯救被公式繞暈的讀者們,我們知道KPI、GPA的考核指標雖然是越多越全面越好,但如果搞出幾百項考核指標來,首先這些指標的內容就不好理解,讓人無法根據結果得分做下一階段的規劃;其次這些考核指標是否全部合理也是問題。因此考核指標需要簡化,機器學習中就使用了正則化策略來簡化考核指標的復雜性。最后,再解釋一下L1正則化與L2正則化的區別。相比L2正則化,加入L1正則化后,優化得到的ω向量,會具有更高的稀疏性,即向量的很多參數會是0。而L2正則化后,優化得到的向量參數則會是一個接近0的、很小的參數。具體原因是在L2正則化中,損失函數對ω的偏導數會隨著ω的值減小而不斷減小,梯度下降速度越來越慢,因此最后結果接近但不等于0。而L1正則化的梯度,則只和ω的正負有關,與其本身值大小無關,因此梯度下降速度始終會保持一個最小值,保證最終結果的稀疏性。
本書在5.4節會結合深度神經網絡,再次討論利用正則化、防止過擬合的問題,請讀者留意。
2.3.4 第四步,代碼實戰
本節將根據之前講述的部分造一個輪子以方便大家理解,然后給出sklearn的代碼,用于實戰時使用。

運行結果:
# out: array([[-16.8213461 ], [-39.77445862], [ 62.60998404], [ 30.07176958], [ -8.52757522]])
預覽結果:
plt.plot( 1 / (1+np.exp(-X.dot(omega))))

結果中前50個樣本被預測為分類0,即setosa,其他的被預測為非setosa,與預期相同,造輪子完成。
實戰使用時,我們可以直接調用sklearn的相關包,發現結果同樣準確:
from sklearn.linear_model import LogisticRegression model = LogisticRegression(C=1) model. fit(X, y) plt.plot(model.predict(X))

1.K折交叉與網格搜索
之前的代碼其實存在一些問題,我們前面強調過,但是在代碼中并沒有體現,大家應該也注意到了:
(1)訓練集和測試集要隔離,而上一部分代碼測試用的數據完全就是訓練集,這樣很容易過擬合。
(2)正則化系數是相當重要的參數,這里直接用C=1是否合理?
因此,為了解決問題1,我們引入K折交叉,將數據平均分成K份,K-1份拿來訓練,1份看結果,然后重復K次,用這種方法實現訓練集和測試集的隔離;為了解決問題(2),我們引入參數的網格搜索(Grid Search),嘗試不同參數的選擇,尋找最優的一種。


由此可見,這里不存在過擬合問題,10折交叉驗證自動生成的訓練集、驗證集預測準確率高度重合。C=0.0001, 0.001時會由于C過小、對預測結果的關注不足造成欠擬合問題。我們之前用的C=1其實是碰巧用了合適的參數。
更多內容,讀者可以參考作者博客文章https://zhuanlan.zhihu.com/p/25637642。
2.評價不平衡樣本分類結果
之前根據準確率優化模型,如果數據分布不平均,單純地使用錯誤率作為標準會產生很大的問題。比如某一種罕見疾病的發病率是萬分之一(0.01%),這時如果一個模型什么都不管,直接認為這個人沒有病,也能拿到一個99.99%正確的模型。這種情況下,模型預測準確率是很高,但卻沒有什么實際價值。那么,應該如何正確衡量準確率的這個問題呢?如果是經典的二分類問題,這種情況下需要綜合考慮不同標準下的靈敏度以及假陽性率。
理解這兩個概念之前,我們要明確一點,就是與醫生直接判斷某一患者是否有病相比,模型給出的是否有病推論,是一個概率,這時可以選擇一個判斷有病的閾值,比如1%,即1%可能有病的情況下即判斷為有病,和真實情況對比后得到如下的二聯表:

在此基礎上有:
真陽性率TPR:在所有實際為陽性的樣本中,被正確地判斷為陽性的比率。

假陽性率FPR:在所有實際為陰性的樣本中,被錯誤地判斷為陽性的比率。

然后在從0%到100%區間取多個閾值,得到不同的FPR/TPR值,以FPR為x軸、TPR為y軸,就可以得到一條ROC曲線,繼而計算ROC圍成的面積——AUC值。這種情況下可以認為,AUC值越高越好,最高可以是1。如果AUC值接近0.5,則分類器等于隨機猜測。遇到特別的情況,如果AUC接近0,則很可能預測與真實情況完全反了,當然這種情況基本很少出現。
注意這里AUC越高越好和最小化損失函數這兩個概念。可能某個模型的損失函數已經最小化了,但是AUC卻不高,造成模型在實際使用時會引入很多錯誤——一個較低的AUC值,可能會在追求高靈敏度時引入大量的假陽性,其后果就是醫生通知了十個患者有患癌風險,最終可能只有一個真有問題,其他九人虛驚一場。這種情況就是模型并未被很好地訓練,可能存在著欠擬合的問題。同時,也可能損失函數最小化以后,測試數據AUC也很高,但是實際運用在真實案例中卻又有大量的錯誤,就是所謂的過擬合了。
如果損失函數無法滿足我們的評價標準(高AUC值),此時需要做的一件事就是調整損失函數,比如給數量較少類別的樣本賦予更高的權重等。那么為什么不直接用AUC值作為優化目標呢?原因很簡單,損失函數和整個模型的結構是偶聯的,AUC值雖然作為評價指標很好,但是計算步驟相對要麻煩很多,也不利于向模型中傳播誤差梯度,所以一般不直接優化AUC值,而是用均方誤差(MSE)、交叉熵(Cross Entropy)等更容易計算的指標進行優化。
使用sklearn計算閾值的方法:


- Learning SQL Server 2008 Reporting Services
- Joomla! 1.5 Site Blueprints
- vtiger CRM Beginner's Guide
- 架構之美
- Moldflow模流分析與工程應用
- Building Websites with Joomla! 1.5
- Object/Oriented JavaScript
- UG NX 9中文版從入門到精通
- 中文版Maya 2016實用教程
- Adobe創意大學InDesign CS5 產品專家認證標準教材
- SVG動畫
- 從零開始:Illustrator CC中文版基礎培訓教程
- UG NX12中文版實用教程
- 中文版Photoshop CS5基礎培訓教程(移動學習版)
- Cinema 4D R20完全學習手冊