自然語言處理實戰(zhàn):機器學習常見工具與技術(shù)
許多自然語言處理都涉及機器學習,所以理解機器學習的一些基本工具和技術(shù)是有益處的。有些工具已經(jīng)在前幾章中討論過,有些還沒有,但這里我們會討論所有這些工具。
D.1 數(shù)據(jù)選擇和避免偏見
數(shù)據(jù)選擇和特征工程會帶來偏見的風險(用人類的話來說)。一旦我們把自己的偏見融入算法中,通過選擇一組特定的特征,模型就會適應(yīng)這些偏見并產(chǎn)生帶有偏差的結(jié)果。如果我們足夠幸運能在投入生產(chǎn)之前發(fā)現(xiàn)這種偏見,那么也需要投入大量的工作來消除這種偏見。例如,必須重新構(gòu)建和重新訓練整個流水線,以便能夠充分利用分詞器的新詞匯表。我們必須重新開始。
一個例子是著名的Word2vec模型的數(shù)據(jù)和特征選擇。Word2vec是針對大量的新聞報道進行訓練的,從這個語料庫中選擇了大約100萬個n-gram作為這個模型的詞匯表(特征)。它產(chǎn)生了一個使數(shù)據(jù)科學家和語言學家興奮的模型,后者能夠?qū)υ~向量(如“king − man + woman = queen”)進行數(shù)學運算。但隨著研究的深入,在模型中也出現(xiàn)了更多有問題的關(guān)系。
例如,對于“醫(yī)生 − 父親 + 母親 = 護士”這個表達式,“護士”的答案并不是人們希望的無偏見和合乎邏輯的結(jié)果。性別偏見在不經(jīng)意間被訓練到模型中。類似的種族、宗教甚至地理區(qū)域偏見在原始的Word2vec模型中普遍存在。谷歌公司的研究人員無意制造這些偏見,偏見存在于數(shù)據(jù)中,即他們訓練Word2vec使用的谷歌新聞?wù)Z料庫中詞使用統(tǒng)計的數(shù)據(jù)。
許多新聞報道只是帶有文化偏見,因為它們是由記者撰寫的,目的是讓讀者開心。這些記者描寫的是一個存在制度偏見和現(xiàn)實生活中人們對待事件的偏見的世界。谷歌新聞中的詞使用統(tǒng)計數(shù)據(jù)僅僅反映的是,在母親當中當護士的數(shù)目要比當醫(yī)生的多得多,同時在父親當中當醫(yī)生的數(shù)目比當護士的多得多。Word2vec模型只是為我們提供了一個窗口,讓我們了解我們創(chuàng)建的世界。
幸運的是,像Word2vec這樣的模型不需要標記訓練數(shù)據(jù)。因此,我們可以自由選擇任何喜歡的文本來訓練模型。我們可以選擇一個更平衡的、更能代表大家希望模型做出的信念和推理的數(shù)據(jù)集。當其他人躲在算法背后說他們只是按照模型做事時,我們可以與他們分享自己的數(shù)據(jù)集,這些數(shù)據(jù)集更公平地代表了一個社會,在這個社會里,我們渴望為每個人提供平等的機會。
當訓練和測試模型時,大家可以依靠自己天生的公正感來幫助決定一個模型何時可以做出影響用戶生活的預(yù)測。如果得到的模型以我們希望的方式對待所有用戶,那么我們可以在晚上睡個好覺。它還可以幫助密切關(guān)注那些與大家不同的用戶的需求,特別是那些通常處于社會不利地位的用戶。如果需要更正式的理由來證明自己的行為,大家還可以學習更多關(guān)于統(tǒng)計學、哲學、倫理學、心理學、行為經(jīng)濟學和人類學的知識,來增強大家在本書中學到的計算機科學技能。
作為一名自然語言處理實踐者和機器學習工程師,大家有機會訓練出比人類做得更好的機器。老板和同事不會告訴大家應(yīng)該在訓練集中添加或刪除哪些文本,大家自己有能力影響塑造整體社區(qū)和社會的機器的行為。
我們已經(jīng)為大家提供了一些關(guān)于如何組裝一個帶有更少偏見和更公平的數(shù)據(jù)集的想法。現(xiàn)在,我們將展示如何使得到的模型與無偏見數(shù)據(jù)相擬合,以便它們在現(xiàn)實世界中精確和有用。
D.2 模型擬合程度
對于所有機器學習模型,一個主要的挑戰(zhàn)是克服模型過度優(yōu)異的表現(xiàn)。什么是“過度優(yōu)異”呢?在處理所有模型中的樣本數(shù)據(jù)時,給定的算法都可以很好地在給定數(shù)據(jù)集中找到模式。但是考慮到我們已經(jīng)知道訓練集中所有給定樣本的標簽(如果不知道其標簽表明它不在訓練集中),因此算法在訓練樣本的上述預(yù)測結(jié)果不會特別有用。我們真正的目的是利用這些訓練樣本來構(gòu)建一個有泛化能力的模型,能夠為一個新樣本打上正確標簽。盡管該樣本與訓練集的樣本類似,但是它是訓練集以外的樣本。在訓練集之外新樣本上的預(yù)測性能就是我們想優(yōu)化的目標。
我們稱能夠完美描述(并預(yù)測)訓練樣本的模型“過擬合”(overfit)(如圖D-1所示)。這樣的模型將很難或沒有能力描述新數(shù)據(jù)。它不是一個通用的模型,當給出一個不在訓練集中的樣本時,很難相信它會做得很好。

圖D-1 訓練樣本上的過擬合現(xiàn)象
相反,如果我們的模型在訓練樣本上做出了許多錯誤的預(yù)測,并且在新樣本上也做得很差,則稱它“欠擬合”(underfit)(如圖D-2所示)。在現(xiàn)實世界中,這兩種模型都對預(yù)測作用不大。因此,下面看看哪些技術(shù)能夠檢測出上述兩種擬合問題,更重要的是,我們還會給出一些避免上述問題的方法。

圖D-2 訓練樣本上的欠擬合現(xiàn)象
D.3 數(shù)據(jù)集劃分
在機器學習實踐中,如果數(shù)據(jù)是黃金,那么標注數(shù)據(jù)就是raritanium(某游戲里的一種珍貴資源)。我們的第一直覺可能是獲取帶標注數(shù)據(jù)并把它們?nèi)總鬟f給模型。更多的訓練數(shù)據(jù)會產(chǎn)生更有彈性的模型,對吧?但這使我們沒有辦法測試這個模型,只能心中希望它在現(xiàn)實世界中能產(chǎn)生好的結(jié)果。這顯然是不切實際的。解決方案是將帶標注的數(shù)據(jù)拆分為兩個數(shù)據(jù)集,有時是3個數(shù)據(jù)集:一個訓練集、一個驗證集,在某些情況下還有一個測試集。
訓練集是顯而易見的。在一輪訓練中,驗證集是我們保留的對模型隱藏的一小部分帶標注數(shù)據(jù)。在驗證集上獲得良好性能是驗證經(jīng)過訓練的模型在訓練集之外的新數(shù)據(jù)上表現(xiàn)良好的第一步。大家經(jīng)常會看到將一個給定的標注數(shù)據(jù)集按照訓練與驗證比80%/20%或70%/30%進行劃分。測試集類似于驗證集,也是帶標注訓練數(shù)據(jù)的子集,用于測試模型并度量性能。但是這個測試集與驗證集有什么不同呢?在組成上,它們其實沒有任何不同,區(qū)別在于使用它們的方法。
在訓練集上對模型進行訓練時,會有若干次迭代,迭代過程中會有不同的超參數(shù)。我們選擇的最終模型將是在驗證集上執(zhí)行得最好的模型。但是這里有一個問題,我們?nèi)绾沃雷约簺]有優(yōu)化一個僅僅是高度擬合驗證集的模型?我們沒有辦法驗證該模型在其他數(shù)據(jù)上的性能是否良好。這就是我們的老板或論文的讀者最感興趣的地方——該模型在他們的數(shù)據(jù)上的效果到底如何?
因此,如果有足夠的數(shù)據(jù),需要將標注數(shù)據(jù)集的第三部分作為測試集。這將使我們的讀者(或老板)更有信心,確信模型在訓練和調(diào)優(yōu)過程中在從未看到的數(shù)據(jù)上也可以獲得很好的效果。一旦根據(jù)驗證集性能選擇了經(jīng)過訓練的模型,并且不再訓練或調(diào)整模型,那么就可以對測試集中的每個樣本進行預(yù)測(推理)。假如模型在第三部分數(shù)據(jù)上表現(xiàn)良好,那么它就有不錯的泛化性。為了得到這種具有高可信度的模型驗證,大家經(jīng)常會看到數(shù)據(jù)集按照60%/20%/20%的訓練/驗證/測試比進行劃分的情形。
提示 在對數(shù)據(jù)集進行訓練集、驗證集和測試集的劃分之前,對數(shù)據(jù)集進行重新排序是非常重要的。我們希望每個數(shù)據(jù)子集都是能代表“真實世界”的樣本,并且它們需要與期望看到的每個標簽的比大致相同。如果訓練集有25%的正向樣本和75%的負向樣本,那么同樣也希望測試集和驗證集也有25%的正向樣本和75%的負向樣本。如果原始數(shù)據(jù)集的前面都是負向樣本,并且在將數(shù)據(jù)集劃分為50%/50%比的訓練集/測試集前沒有打亂數(shù)據(jù),那么在訓練集中將得到100%的負向樣本,而在測試集中將得到50%的負向樣本。這種情況下,模型永遠不能從數(shù)據(jù)集中的正向樣本中學習。
D.4 交叉擬合訓練
另一個劃分訓練集/測試集的方法是交叉驗證或者k折交叉驗證(如圖D-3所示)。交叉驗證背后的概念和我們剛討論過的數(shù)據(jù)劃分非常相似,但是它允許使用所有的帶標記數(shù)據(jù)集進行訓練。這個過程將訓練集劃分為k等分,或者說k折。然后通過將k − 1份數(shù)據(jù)作為訓練集訓練模型并在第k份數(shù)據(jù)上進行驗證。之后將第一次嘗試中用作訓練的k − 1份數(shù)據(jù)中的一份數(shù)據(jù)作為驗證集,剩下的k − 1份數(shù)據(jù)成為新訓練集,進行重新訓練。

圖D-3 k折交叉驗證
該技術(shù)對于分析模型的結(jié)構(gòu)和尋找對各個驗證數(shù)據(jù)性能表現(xiàn)良好的超參數(shù)具有重要價值。一旦選擇了超參數(shù),還需要選擇表現(xiàn)最好的經(jīng)過訓練的模型,因此很容易受到上一節(jié)所表述的偏見的影響,因此,在此過程中仍然建議保留一份測試集。
這種方法還提供了關(guān)于模型可靠性的一些新信息。我們可以計算一個P值,表示模型發(fā)現(xiàn)的輸入特征和輸出預(yù)測之間的關(guān)系的可能性在統(tǒng)計上是顯著的,而不是隨機選擇的結(jié)果。如果訓練集確實是真實世界的代表性樣本,那么這將是一個非常重要的新信息。
這種對模型有額外信心的代價是,需要k倍的訓練時間來進行k折的交叉驗證。所以,如果想要得到關(guān)于問題的90%的答案,通??梢院唵蔚刈?折交叉驗證。這個驗證方法與我們之前做的訓練集/驗證集劃分方法完全相同。我們不會對模型這個對真實世界的動態(tài)描述的可靠性有100%的信心,但是如果它在測試集中表現(xiàn)良好,也可以非常自信地認為它是預(yù)測目標變量的有用模型。所以通過這種實用方法得到的機器學習模型對大多數(shù)商業(yè)應(yīng)用來說都是有意義的。
D.5 抑制模型
在model.fit()中,梯度下降過分熱衷于追求降低模型中可能出現(xiàn)的誤差。這可能導致過擬合,即學到的模型在訓練集上效果很好,但是在新的未見樣本集(測試集)上卻效果很差。因此,我們可能希望“保留”對模型的控制。以下是3種方法:
- 正則化;
- 隨機dropout;
- 批歸一化。
D.5.1 正則化
在所有機器學習模型中,最終都會出現(xiàn)過擬合。幸運的是,有幾種工具可以解決這個問題。第一個是正則化,它是對每個訓練步驟的學習參數(shù)的懲罰。它通常但不總是參數(shù)本身的一個因子。其中,L1范數(shù)和L2范數(shù)是最常見的做法。
L1正則化:

L1是所有參數(shù)(權(quán)重)的絕對值與某個λ(超參數(shù))乘積的和,通常是0到1之間的一個小浮點數(shù)。這個和應(yīng)用于權(quán)重的更新——其思想是,較大的權(quán)重會產(chǎn)生較大的懲罰,因此鼓勵模型使用更多的、均勻的權(quán)重……
L2正則化:

類似地,L2是一種權(quán)重懲罰,但定義略有不同。這種情況下,它是權(quán)重的平方與某個λ乘積的和,這個λ值是一個要在訓練前選擇的單獨超參數(shù)。
D.5.2 dropout
在神經(jīng)網(wǎng)絡(luò)中,dropout是另一個解決過擬合的辦法——乍一看似乎很神奇。dropout的概念是,在神經(jīng)網(wǎng)絡(luò)的任何一層,我們都會在訓練的時候,按一定比例關(guān)閉通過這一層的信號。注意,這只發(fā)生在訓練期間,而不是推理期間。在所有訓練過程中,網(wǎng)絡(luò)層中一部分神經(jīng)元子集都會被“忽略”,這些輸出值被顯式地設(shè)置為零。因為它們對預(yù)測結(jié)果沒有輸入,所以在反向傳播步驟中不會進行權(quán)重更新。在下一個訓練步驟中,將選擇層中不同權(quán)重的子集,并將其他權(quán)重歸零。
一個在任何時間都有20%處于關(guān)閉狀態(tài)的大腦的網(wǎng)絡(luò)該如何學習呢?其思想是,沒有一個特定的權(quán)重路徑可以完全定義數(shù)據(jù)的特定屬性。該模型必須泛化其內(nèi)部結(jié)構(gòu),以便該模型通過神經(jīng)元的多條路徑都能夠處理數(shù)據(jù)。
被關(guān)閉的信號的百分比被定義為超參數(shù),因為它是一個介于0和1之間的浮點數(shù)。在實踐中,從0.1到0.5的dropout通常是最優(yōu)的,當然,這是依賴模型的。在推理過程中,dropout會被忽略,從而充分利用訓練后的權(quán)值對新數(shù)據(jù)進行處理。
Keras提供了一種非常簡單的實現(xiàn)方法,可以在本書的示例和代碼清單D-1中看到。
代碼清單D-1 Keras中的dropout層會減少過擬合
- >>> from keras.models import Sequential
- >>> from keras.layers import Dropout, LSTM, Flatten, Dense
- >>> num_neurons = 20
- >>> maxlen = 100
- >>> embedding_dims = 300
- >>> model = Sequential() >>> model.add(LSTM(num_neurons, return_sequences=True,
- ... input_shape=(maxlen, embedding_dims)))>>> model.add(Dropout(.2))
- >>> model.add(Flatten())
- >>> model.add(Dense(1, activation='sigmoid'))
D.5.3 批歸一化
神經(jīng)網(wǎng)絡(luò)中一個稱為批歸一化的新概念可以幫助對模型進行標準化和泛化。批歸一化的思想是,與輸入數(shù)據(jù)非常相似,每個網(wǎng)絡(luò)層的輸出應(yīng)該歸一化為0到1之間的值。關(guān)于如何、為什么、什么時候這樣做是有益的,以及在什么條件下應(yīng)該使用它,仍然存在一些爭議。我們希望大家自己去對這個研究方向進行探索。
但是Keras的BatchNormalization層提供了一個簡單的實現(xiàn)方法,如代碼清單D-2所示。
代碼清單D-2 歸一化BatchNormalization
- >>> from keras.models import Sequential
- >>> from keras.layers import Activation, Dropout, LSTM, Flatten, Dense
- >>> from keras.layers.normalization import BatchNormalization
- >>> model = Sequential()>>> model.add(Dense(64, input_dim=14))
- >>> model.add(BatchNormalization())
- >>> model.add(Activation('sigmoid'))
- >>> model.add(Dense(64, input_dim=14))
- >>> model.add(BatchNormalization())
- >>> model.add(Activation('sigmoid'))
- >>> model.add(Dense(1, activation='sigmoid'))
D.6 非均衡訓練集
機器學習模型的好壞取決于提供給它們的數(shù)據(jù)。只有當樣本中涵蓋了希望在預(yù)測階段的所有情況時,擁有大量的數(shù)據(jù)才有幫助,并且數(shù)據(jù)集涵蓋每種情況僅僅一次是不夠的。想象一下我們正試圖預(yù)測一副圖像到底是一只狗還是一只貓。這時我們手里有一個訓練集,里面包含20 000張貓的照片,但是狗的照片只有200張。如果要在這個數(shù)據(jù)集中訓練一個模型,那么這個模型很可能只是簡單地學會將任何給定的圖像都預(yù)測為一只貓,而不管輸入是什么。從模型的角度來說,這個結(jié)果還可以接受,對不對?我的意思是,對99%的訓練樣本的預(yù)測結(jié)果都是正確的。當然,這個觀點實際完全站不住腳,這個模型毫無價值。但是,完全超出了特定模型的范圍之外,造成這種失敗的最可能原因是非均衡訓練集。
模型可能會非常關(guān)注訓練集,其原因很簡單,來自標記數(shù)據(jù)中過采樣類的信號會壓倒來自欠采樣類的信號。權(quán)重將更經(jīng)常地由主類信號的誤差進行更新,而來自小類的信號將被忽視。獲得每個類的絕對均勻表示并不重要,因為模型自己能夠克服一些噪聲。這里的目標只是讓類的比例達到均衡水平。
與任何機器學習任務(wù)一樣,第一步是長時間、仔細地查看數(shù)據(jù),了解一些細節(jié),并對數(shù)據(jù)實際表示的內(nèi)容進行一些粗略的統(tǒng)計。不僅要知道有多少數(shù)據(jù),還要知道有多少種類的數(shù)據(jù)。
那么,如果事情從一開始就沒有特別之處,大家會怎么做呢?如果目標是使類的表示均勻(確實如此),則有3個主要方法可供選擇:過采樣、欠采樣和數(shù)據(jù)增強。
D.6.1 過采樣
過采樣是一種重復(fù)采樣來自一個或多個欠表示類的樣本的技術(shù)。我們以先前的狗/貓分類示例為例(只有200只狗,有20 000只貓)。我們可以簡單地重復(fù)100次已有的200張狗的圖像,最終得到40 000個樣本,其中一半是狗,一半是貓。
這是一個極端的例子,因此會導致自身固有的問題。這個網(wǎng)絡(luò)很可能會很好地識別出這200只特定的狗,而不能很好地推廣到其他不在訓練集中的狗。但是,在不那么極端不平衡的情況下,過采樣技術(shù)肯定有助于平衡訓練集。
D.6.2 欠采樣
欠采樣是同一枚硬幣的反面。在這里,就是從過度表示的類中刪除部分樣本。在上面的貓/狗示例中,我們將隨機刪除19 800張貓的圖片,這樣就會剩下400個樣本,其中一半是狗,一半是貓。當然,這樣做本身也有一個突出的問題,就是我們拋棄了絕大多數(shù)的數(shù)據(jù),而只在一個不那么寬泛的數(shù)據(jù)基礎(chǔ)上進行研究。上述例子中這樣的極端做法并不理想,但是如果欠表示類本身包含大量的樣本,那么上述極端做法可能是一個很好的解決方案。當然,擁有這么多數(shù)據(jù)絕對是太奢侈了。
D.6.3 數(shù)據(jù)增強
數(shù)據(jù)增強有點兒棘手,但在適當?shù)那闆r下它可以給我們帶來幫助。增強的意思是生成新的數(shù)據(jù),或者從現(xiàn)有數(shù)據(jù)的擾動中生成,或者重新生成。AffNIST就是這樣一個例子。著名的MNIST數(shù)據(jù)集由一組手寫的0~9數(shù)字組成(如圖D-4所示)。AffNIST在保留原始標簽的同時,以各種方式對每個數(shù)字進行傾斜、旋轉(zhuǎn)和縮放。

圖D-4 最左側(cè)列中的條目是原始MNIST中的樣本,其他列都是經(jīng)仿射
轉(zhuǎn)換后包含在affNIST中的數(shù)據(jù)(圖片經(jīng)“affNIST”授權(quán))
這種特別的做法的目的并不是平衡訓練集,而是使像卷積神經(jīng)網(wǎng)絡(luò)一樣的網(wǎng)絡(luò)對以其他方式編寫的新數(shù)據(jù)更具彈性,但這里數(shù)據(jù)增強的概念仍然適用。
不過,大家必須小心,添加不能真正代表待建模型數(shù)據(jù)的數(shù)據(jù)有可能弊大于利。假設(shè)數(shù)據(jù)集是之前的200只狗和20 000只貓組成的圖片集。我們進一步假設(shè)這些圖像都是在理想條件下拍攝的高分辨率彩色圖像?,F(xiàn)在,給19 000名幼兒園教師一盒蠟筆并不一定能得到想要的增強數(shù)據(jù)。因此,考慮一下增強的數(shù)據(jù)會對模型產(chǎn)生什么樣的影響。答案并不是在任何時候都清晰無比,所以如果一定要沿著這條路徑走下去的話,在驗證模型時請記住模型的影響這一點,并努力圍繞其邊緣進行測試,以確保沒有無意中引入意外的行為。
最后,再說一件可能價值最小的事情,但這的確是事實:如果數(shù)據(jù)集“不完整”,那么首先應(yīng)該考慮回到原來的數(shù)據(jù)源中尋找額外的數(shù)據(jù)。這種做法并不總是可行,但至少應(yīng)該把它當作一種選擇。
D.7 性能指標
任何機器學習流水線中最重要的部分都是性能指標。如果不知道學到的機器學習模型運行得有多好,就無法讓它變得更好。當啟動機器學習流水線時,要做的第一件事是在任何sklearn機器學習模型上設(shè)置一個性能度量方法,例如“.score()”。然后我們構(gòu)建一個完全隨機的分類/回歸流水線,并在最后計算性能分數(shù)。這使我們能夠?qū)α魉€進行增量式改進,從而逐步提高分數(shù),以便更接近最終的目標。這也是讓老板和同事確信大家走在正確的軌道上的好方法。
D.7.1 分類的衡量指標
對分類器而言,我們希望它做對兩件事:一是用類標簽標記真正屬于該類的對象,二是不用這個標簽去標記不屬于此類的對象。這兩件事對應(yīng)得到的正確計數(shù)值分別稱為真陽(true positive)和真陰(true negative)。如果有一個numpy數(shù)組包含模型分類或預(yù)測的所有結(jié)果,那么就可以計算出正確的預(yù)測結(jié)果,如代碼清單D-3所示。

代碼清單D-4 計算模型得到的錯誤結(jié)果

有時,這4個數(shù)合并成一個4 × 4矩陣,稱為誤差矩陣或混淆矩陣。代碼清單D-5給出了混淆矩陣中預(yù)測值和真實值的樣子。
代碼清單D-5 混淆矩陣
- >>> confusion = [[true_positives, false_positives],
- ... [false_negatives, true_negatives]]>>> confusion[[4, 3], [1, 2]]
- >>> import pandas as pd
- >>> confusion = pd.DataFrame(confusion, columns=[1, 0], index=[1, 0])
- >>> confusion.index.name = r'pred \ truth'
- >>> confusion 1 0
- pred \ truth 1 4 1
- 0 3 2
在混淆矩陣中,我們希望對角線(左上角和右下角)上的數(shù)字較大,希望對角線外的數(shù)字(左上角和左下角)較小。然而,正向類和負向類的順序是任意的,所以有時可能會看到這個表的數(shù)字被調(diào)換了位置。請始終標記好混淆矩陣的列和下標。有時可能會聽到統(tǒng)計學家把這個矩陣稱為分類器列聯(lián)表,但如果堅持使用“混淆矩陣”這個名字的話,就可以避免混淆。
對于機器學習分類問題,有兩種有用的方法可以將這4種計數(shù)值中的一些指標組合成一個性能指標:正確率(precision)和召回率(recall)。信息檢索(搜索引擎)和語義搜索就是此分類問題的例子,因為那里的目標是將文檔分為(和輸入查詢)匹配或不匹配兩類。第2章中,我們學習過詞干還原和詞形歸并如何能夠提高召回率,但同時降低了正確率。
正確率度量的是模型在檢測所感興趣類的所有對象(稱為正向類)的能力,因此它也被稱為正向預(yù)測值(positive predictive value)。由于真陽是預(yù)測正確的正向類樣本數(shù)目,而假陽是錯誤地標記為正向類的負向類樣本數(shù)目,因此可以按照代碼清單D-6所示來計算正確率。
代碼清單D-6 正確率
- >>> precision = true_positives / (true_positives + false_positives)
- >>> precision0.571...
上述例子中的混淆矩陣給出了約57%的正確率,因為在所有預(yù)測為正向類的樣本中有約57%是正確的。
召回率和正確率類似,它也被稱為靈敏度、真陽率或查全率。因為數(shù)據(jù)集中的樣本總數(shù)是真陽(true positive)和假陰(false negative)的和,所以可以計算召回率,即檢測到的預(yù)測正確的正向類樣本占所有樣本的百分比,代碼如代碼清單D-7所示。
代碼清單D-7 召回率
- >>> recall = true_positives / (true_positives + false_negatives)
- >>> recall0.8
這就是說上面例子中得到的模型檢測到了數(shù)據(jù)集中80%的正向類樣本。
D.7.2 回歸的衡量指標
用于機器學習回歸問題的兩個最常見的性能評價指標是均方根誤差(RMSE)和皮爾遜相關(guān)系數(shù)(R2)。事實證明,分類問題背后實際上是回歸問題。因此,如果類標簽已經(jīng)轉(zhuǎn)換為數(shù)字(就像我們在上一節(jié)中所做的那樣),就可以在其上使用回歸度量方法。下面的代碼示例將復(fù)用上一節(jié)的那些預(yù)測值和真實值。RMSE對于大多數(shù)問題是最有用的,因為它給出的是預(yù)測值與真實值可能的相差程度。RMSE給出的是誤差的標準偏差,如代碼清單D-8所示。
代碼清單D-8 均方根誤差(RMSE)
- >>> y_true = np.array([0, 0, 0, 1, 1, 1, 1, 1, 1, 1])
- >>> y_pred = np.array([0, 0, 1, 1, 1, 1, 1, 0, 0, 0])
- >>> rmse = np.sqrt((y_true - y_pred) ** 2) / len(y_true))
- >>> rmse
- 0.632...
皮爾遜相關(guān)系數(shù)是回歸函數(shù)的另一個常見性能指標。sklearn模塊默認將其作為.score()函數(shù)附加到大多數(shù)模型上。如果大家不清楚這些指標如何計算的話,那么應(yīng)該手動計算一下找找感覺。相關(guān)系數(shù)的計算參見代碼清單D-9。
代碼清單D-9 相關(guān)系數(shù)
- >>> corr = pd.DataFrame([y_true, y_pred]).T.corr()
- >>> corr[0][1]
- 0.218...>>> np.mean((y_pred - np.mean(y_pred)) * (y_true - np.mean(y_true))) /
- ... np.std(y_pred) / np.std(y_true)
- 0.218...
由此可見我們的樣本預(yù)測值與真實值的相關(guān)度只有28%。
D.8 專業(yè)技巧
一旦掌握了基本知識,那么下面這些簡單的技巧將有助于更快地建立良好的模型:
- 使用數(shù)據(jù)集中的一個小的隨機樣本子集來發(fā)現(xiàn)流水線的可能缺陷;.
- 當準備將模型部署到生產(chǎn)環(huán)境中時,請使用所有的數(shù)據(jù)來訓練模型;
- 首先應(yīng)該嘗試自己最了解的方法,這個技巧也適用于特征提取和模型本身;
- 在低維特征和目標上使用散點圖和散點矩陣,以確保沒有遺漏一些明顯的模式;
- 繪制高維數(shù)據(jù)作為原始圖像,以發(fā)現(xiàn)特征的轉(zhuǎn)移**;
- 當希望最大化向量對之間的差異時,可以嘗試對高維數(shù)據(jù)使用PCA(對NLP數(shù)據(jù)使用LSA);
- 當希望在低維空間中進行回歸或者尋找匹配的向量對時,可以使用非線性降維,如t-SNE;
- 構(gòu)建一個sklearn.Pipeline對象,以提高模型和特性提取器的可維護性和可復(fù)用性;
- 使超參數(shù)的調(diào)優(yōu)實現(xiàn)自動化,這樣模型就可以了解數(shù)據(jù),大家就可以花時間學習機器學習。
超參數(shù)調(diào)優(yōu) 超參數(shù)是所有那些確定流水線性能的值,包括模型類型及其配置方式等。超參數(shù)還可以是神經(jīng)網(wǎng)絡(luò)中包含的神經(jīng)元數(shù)和層數(shù),或者是sklearn.linear_model.Ridge嶺回歸模型中的alpha值。超參數(shù)還包括控制所有預(yù)處理步驟的值,例如分詞類型、所有忽略的詞列表、TF-IDF詞匯表的最小和最大文檔頻率、是否使用詞形歸并、TF-IDF歸一化方法等。
超參數(shù)調(diào)優(yōu)可能是一個十分緩慢的過程,因為每個實驗都需要訓練和驗證一個新模型。因此,在搜索范圍廣泛的超參數(shù)時,我們需要將數(shù)據(jù)集減小到具有代表性的最小樣本集。當搜索接近滿足需求的最終模型時,可以增加數(shù)據(jù)集的大小,以使用盡可能多的所需數(shù)據(jù)。
優(yōu)化流水線的超參數(shù)是提高模型性能的方法。實現(xiàn)超參數(shù)調(diào)優(yōu)自動化可以節(jié)省更多的時間來閱讀本書這樣的書籍,或者可視化和分析最后的結(jié)果。當然大家仍然可以通過直覺設(shè)置要嘗試的超參數(shù)范圍來指導調(diào)優(yōu)。
提示 超參數(shù)調(diào)優(yōu)最有效的算法是(從最好到最差):
(1)貝葉斯搜索;
(2)遺傳算法;
(3)隨機搜索;
(4)多分辨率網(wǎng)格搜索;
(5)網(wǎng)格搜索。
但是無論如何,在大家進入夢鄉(xiāng)時工作的所有計算機搜索算法,都比手動猜測一個個新參數(shù)好。
本文摘自《自然語言處理實戰(zhàn) 利用Python理解、分析和生成文》