如何用機器學習處理二元分類任務?

王樹義發表於2019-03-04
如何用機器學習處理二元分類任務?

影像是貓還是狗?情感是正還是負?貸還是不貸?這些問題,該如何使用合適的機器學習模型來解決呢?

問題

暑假後,又有一批研究生要開題了。這幾天陸續收到他們發來的研究計劃大綱。

其中好幾個,打算使用機器學習做分類。

但是,從他們的文字描述來看,不少人對機器學習進行分類的方法,還是一知半解

考慮到之前分享機器學習處理分類問題的文章,往往針對具體的任務案例。似乎對分類問題的整體步驟與注意事項,還沒有詳細論述過。於是我決定寫這篇文章,幫他們梳理一下。

他們和你一樣,也是我專欄的讀者。

如果你對機器學習感興趣,並且實際遇到了分類任務,那我解答他們遇到的一些疑問,可能對於你同樣有用。

所以,我把這篇文章也分享給你。希望能有一些幫助。

監督

監督式機器學習任務很常見。主要模型,是分類與迴歸。

就分類問題而言,二元分類是典型應用。

例如決策輔助,你利用結構化資料,判定可否貸款給某個客戶;

例如情感分析,你需要通過一段文字,來區分情感的正負極性;

例如影像識別,你得識別出圖片是貓,還是狗。

今天我們們就先介紹一下,二元分類,這個最為簡單和常見的機器學習應用場景。

注意要做分類,你首先得有合適的資料。

什麼是合適的資料呢?

這得回到我們對機器學習的大類劃分。

分類任務,屬於監督式學習。

監督式學習的特點,是要有標記。

例如給你1000張貓的圖片,1000張狗的圖片,扔在一起,沒有打標記。這樣你是做不了分類的。

雖然你可以讓機器學習不同圖片的特徵,讓它把圖片區分開。

但是這叫做聚類,屬於非監督學習

天知道,機器是根據什麼特徵把圖片分開的。

你想得到的結果,是貓放在一類,狗放在另一類。

但是機器抓取特徵的時候,也許更喜歡按照顏色區分。

結果白貓白狗放在了一個類別,黃貓黃狗放在了另一個類別。跟你想要的結果大相徑庭。

如果你對非監督學習感興趣,可以參考《如何用Python從海量文字抽取主題?》一文。

所以,要做分類,就必須有標記才行。

但是標記不是天上掉下來的。

大部分情況下,都是人打上去的。

標記

打標記(Labeling),是個專業化而繁複的勞動。

你可以自己打,可以找人幫忙,也可以利用眾包的力量。

例如亞馬遜的“土耳其機器人”(Amazon Mechanical Turk)專案

如何用機器學習處理二元分類任務?

別被名字唬住,這不是什麼人工智慧專案,而是普通人可以利用業餘時間賺外快的機會。

你可以幫別人做任務拿佣金。任務中很重要的一部分,就是人工分類,打標記。

如何用機器學習處理二元分類任務?

因此如果你有原始資料,但是沒有標記,就可以把資料扔上去。

說明需求,花錢找人幫你標記。

類似的服務,國內也有很多。

建議找知名度比較高的平臺來做,這樣標記的質量會比較靠譜。

如果你還是在校學生,可能會覺得這樣的服務價格太貴,個人難以負擔。

沒關係。假如你的研究是有基金資助專案的一部分,可以正大光明地找導師申請資料採集費用。

但若你的研究屬於個人行為,就得另想辦法了。

不少學生選擇的辦法,是依靠團隊支援。

例如找低年級的研究生幫忙標記。

人家幫了忙,讓你發表了論文,順利畢業。你總得請大家吃一頓好吃的,是吧?

學習

有了標記以後,你就能夠實施監督學習,做分類了。

這裡我們順帶說一下,什麼叫做“機器學習”。

這個名字很時髦。

其實它做的事情,叫做“基於統計的資訊表徵”。

先說資訊表徵(representation)。

你的輸入,可能是結構化的資料,例如某個人的各項生理指標;可能是非結構化資料,例如文字、聲音甚至是影像,但是最終機器學習模型看到的東西,都是一系列的數字。

這些數字,以某種形式排布。

可能是零維的,叫做標量(scalar);

可能是一維的,叫做向量(vector);

可能是二維的,叫做矩陣(Matrice);

可能是高維的,叫做張量(Tensor)。

如何用機器學習處理二元分類任務?

但是,不論輸入的資料,究竟有多少維度,如果你的目標是做二元分類,那麼經過一個或簡單、或複雜的模型,最後的輸出,一定是個標量數字。

你的模型,會設定一個閾值。例如0.5。

如何用機器學習處理二元分類任務?

超出這個數字的,被分類到一處。

反之,被分類到另一處。

任務完成。

那麼模型究竟在做什麼呢?

它的任務,就是把輸入的資料,表徵成最終的這個標量。

打個不恰當的比方,就如同高考

每一個考生,其實都是獨特的。

每個人都有自己的家庭,自己的夢想,自己的經歷,自己的故事。

但是高考這個模型,不可能完整準確表徵上述全部細節。

它簡單地以考生們的試卷答題紙作為輸入,以一個最終的總成績作為輸出。

然後,劃定一個叫做錄取分數線的東西,作為閾值(判定標準)。

達到或超出了,錄取。

否則,不錄取。

這個分數,就是高考模型對每個考生的資訊表徵

所謂分類模型的優劣,其實就是看模型是否真的達到了預期的分類效果。

什麼是好的分類效果?

大學想招收的人,錄取了(True Positive, TP);

大學不想招收的人,沒被錄取(True Negative, TN)。

什麼是不好的分類效果?

大學想招收的人,沒能被錄取(False Negative, FN);

大學不想招收的人,被錄取了(False Positive, FP)。

如何用機器學習處理二元分類任務?

好的模型,需要盡力增大 TP 和 TN 的比例,降低 FN 和 FP 的比例。

評判的標準,視你的類別資料平衡而定。

資料平衡,例如1000張貓照片,1000張狗照片,可以使用 ROC AUC。

如何用機器學習處理二元分類任務?

資料不平衡,例如有1000張貓的照片,卻只有100張狗的照片,可以使用 Precision 和 Recall ,或者二者相結合的 F1 score。

因為有這樣明確的評估標準,所以二元分類模型不能滿足於“分了類”,而需要向著“更好的分類結果”前進。

辦法就是利用統計結果,不斷改進模型的表徵方法。

所以,模型的引數需要不斷迭代。

恢復高考後的40年,高考的形式、科目、分值、大綱……包括加分政策等,一直都在變化。這也可以看作是一種模型的迭代。

“表徵”+“統計”+“迭代”,這基本上就是所謂的“學習”。

結構化

看到這裡,希望你的頭腦裡已經有了機器學習做二元分類問題的技術路線概貌。

下面我們們針對不同的資料型別,說說具體的操作形式和注意事項。

先說最簡單的結構化資料。

例如《貸還是不貸:如何用Python和機器學習幫你決策?》一文中,我們見到過的客戶資訊。

如何用機器學習處理二元分類任務?

處理這樣的資料,你首先需要關注資料的規模。

如果資料量大,你可以使用複雜的模型。

如果資料量小,你就得使用簡單的模型。

為什麼呢?

因為越複雜的模型,表徵的資訊就越多。

表徵的資訊多,未必是好事。

因為你抓住的,既有可能是訊號,也有可能是噪聲。

如果表徵資訊多,可是學習過的資料不多,它可能就會對不該記住的資訊,形成記憶。

在機器學習領域,這是最恐怖的結果——過擬合(overfitting)。

翻譯成人話,就是見過的資料,分類效果極好;沒見過的資料,表現很糟糕。

如何用機器學習處理二元分類任務?

舉一個我自己的例子。

我上學前班後沒多久,我媽就被請了家長。

因為我漢語拼音默寫,得了0分。

老師嘴上說,是懷疑我不認真完成功課;心裡想的,八成是這孩子智商餘額不足。

其實我挺努力的。

每天老師讓回家默寫的內容,都默了。

但是我默寫的時候,是嚴格按照“a o e i u ……”的順序默的。

因為每天都這樣默寫,所以我記住的東西,不是每個讀音對應的符號,而是它們出現的順序。

結果上課的時候,老師是這樣唸的“a b c d e ……”

我毫無懸念沒跟下來。

我的悲劇,源於自己的心智模型,實際上只反覆學習了一條資料“a o e i u ……”。每天重複,導致過擬合,符號出現在順序中,才能辨識和記憶。

因此,見到了新的組合方式,就無能為力了。

看,過擬合很糟糕吧。

確定了模型的複雜度以後,你依然需要根據特徵多少,選擇合適的分類模型。

如何用機器學習處理二元分類任務?

上圖來自於 Scikit-learn ,我擷取了其中“分類”模型部分,你可以做參考。

注意模型的效果,實際上是有等級劃分的。

例如根據 Kaggle 資料科學競賽多年的實踐結果來看,Gradient Boosting Machine 優於隨機森林,隨機森林優於決策樹。

這麼比有些不厚道,因為三者的出現,也是有時間順序的。

讓爺爺跟孫子一起賽跑,公平性有待商榷。

因此,你不宜在論文中,將不同的分類模型,分別調包跑一遍,然後來個橫向對比大測評

許多情況下,這是沒有意義的。

雖然顯得工作量很大。

但假如你發現在你自己的資料集上面,決策樹的效果就是明顯優於 Gradient Boosting Machine ,那你倒是很有必要通過論文做出彙報。

儘管大部分審稿人都會認為,一定是你算錯了

另一個需要注意的事項,是特徵工程(feature engineering)。

什麼叫特徵工程呢?

就是手動挑選特徵,或者對特徵(組合)進行轉化。

例如《如何用Python和深度神經網路鎖定即將流失的客戶?》一文中,我們就對特徵進行了甄別。其中三列資料,我們直接剔除掉了:

  • RowNumber:行號,這個肯定沒用,刪除
  • CustomerID:使用者編號,這個是順序發放的,刪除
  • Surname:使用者姓名,對流失沒有影響,刪除

正式學習之前,你需要把手頭掌握的全部資料分成3類:

  • 訓練集
  • 驗證集
  • 測試集

我在給期刊審稿的時候,發現許多使用機器學習模型的作者,無論中外,都似乎不能精確理解這些集合的用途。

訓練集讓你的模型學習,如何利用當前的超引數(例如神經網路的層數、每一層的神經元個數等)組合,儘可能把表徵擬合標記結果。

就像那個笑話說的一樣:

Machine Learning in a Nutshell:

Interviewer: what`s you biggest strength?

Me: I`m a quick learner.

Interviewer: What`s 11*11?

Me: 65.

Interviewer: Not even close. It`s 121.

Me: It`s 121.

而驗證集的存在,就是為了讓你對比不同的超引數選擇,哪一組更適合當前任務。它必須用訓練集沒有用過的資料。

驗證集幫你選擇了合適的超引數後,它的歷史任務也就結束了。

這時候,你可以把訓練集、驗證集合並在一起,用最終確定的超引數組合進行訓練,獲得最優模型。

這個模型表現怎麼樣?

你當然需要其他的資料來評判。這就是為什麼你還要劃分出另外的測試集。

影像

François Chollet 在自己的書中舉過一個例子,我覺得很有啟發,一併分享給你。

假如你看到了這樣的原始資料:

如何用機器學習處理二元分類任務?

你該怎麼做分類?

有的同學一看是影像,立刻決定,上卷積神經網路

別忙,想想看,真的需要“直接上大錘”嗎?

別的不說,那一圈的刻度,就對我們的模型毫無意義。

你可以利用特徵工程,將其表達為這樣的座標點:

如何用機器學習處理二元分類任務?

你看,這樣處理之後,你立刻就擁有了結構化資料。

注意這個轉換過程,並不需要人工完成,完全可以自動化。

但是舉一反三的你,估計已經想到了“更好的”解決方案:

如何用機器學習處理二元分類任務?

對,這樣一來,表達鐘錶時間的資料,就從原先的4個數字,變成了只需要2個。

一個本來需要用複雜模型解決的問題,就是因為簡單的特徵工程轉化,複雜度和難度顯著下降。

其實,曾經人們進行圖片分類,全都得用特徵工程的方法。

那個時候,圖片分類問題極其繁瑣、成本很高,而且效果還不理想。

手動提取的特徵,也往往不具備良好的可擴充套件性和可遷移性。

於是,深度卷積神經網路就登場了。

如果你的圖片資料量足夠多的話,你就可以採用“端到端”的學習方式。

所謂“端到端”,是指不進行任何的特徵工程,構造一個規模合適的神經網路模型,扔圖片進去就可以了。

但是,現實往往是殘酷的。

你最需要了解的,是圖片不夠多的時候,怎麼辦。

這時候,很容易出現過擬合。

因為深度神經網路,屬於典型的複雜模型。

如何用機器學習處理二元分類任務?

這個時候,可以嘗試以下幾個不同的方法:

首先,如果有可能,蒐集更多的帶標註圖片。這是最簡單的辦法,如果成本可以接受,你應該優先採用。

其次,使用資料增強(Data Augmentation)。名字聽起來很強大,其實無非是把原始的資料進行映象、剪裁、旋轉、扭曲等處理。這樣“新的”圖片與老圖片的標註肯定還是一樣的。但是圖片內容發生的變化,可以有效防止模型記住過多噪聲。

如何用機器學習處理二元分類任務?

第三,使用遷移學習。

所謂遷移學習,就是利用別人訓練好的模型,保留其中從輸入開始的大多數層次(凍結保留其層次數量、神經元數量等網路結構,以及權重數值),只把最後的幾層敲掉,換上自己的幾層神經網路,對小規模資料做訓練。

如何用機器學習處理二元分類任務?

上圖同樣來自於 François Chollet 的著作。

這種做法,用時少,成本低,效果還特別好。如果重新訓練,圖片數少,就很容易過擬合。但是用了遷移學習,過擬合的可能性就大大降低。

其原理其實很容易理解。

卷積神經網路的層次,越是靠近輸入位置,表達的特徵就越是細節;越到後面,就越巨集觀。

如何用機器學習處理二元分類任務?

識別貓和狗,要從形狀邊緣開始;識別哆啦a夢和瓦力,也一樣要從形狀邊緣開始。因此模型的底層,可以被拿來使用。

你訓練的,只是最後幾層表徵方式。結構簡單,當然也就不需要這麼多資料了。

第四,引入 Dropout, Regularization 和 Early Stopping 等常規方法。注意這些方法不僅適用於影像資料。

如何用機器學習處理二元分類任務?

以 Dropout 為例。假如一個模型因為複雜,所以記住了很多噪聲,那麼訓練的時候,每次都隨機將一定比例的神經元“扔掉”(設定權重為0),那麼模型的複雜度降低。而且因為隨機,又比降低層數與神經元個數的固化模型適用性更高。

文字

前面說過了,機器不認得文字,只認得數字。

所以,要對文字做二元分類,你需要把文字轉換成為數字。

這個過程,叫做向量化。

向量化的方式,有好幾種。大致上可以分成兩類:

第一類,是無意義轉換。也就是轉換的數字,只是個編號而已,本身並不攜帶其他語義資訊。

這一類問題,我們在《如何用Python和機器學習訓練中文文字情感分類模型?》中,已經非常詳細地介紹過了。

你需要做的,包括分詞(如果是中文)、向量化、去除停用詞,然後丟進一個分類模型(例如樸素貝葉斯,或者神經網路),直接獲取結果,加以評估。

但是,這個過程,顯然有大量的語義和順序資訊被丟棄了。

第二類,是有意義轉換。這時候,每個語言單元(例如單詞)轉換出來的數字,往往是個高維向量。

如何用機器學習處理二元分類任務?

這個向量,你可以自己通過訓練來產生。

但是這種訓練,需要對海量語料進行建模。

建模的過程,成本很高,佔用龐大儲存空間,運算量極大。

因此更常見的做法,是使用別人通過大規模語料訓練後的結果。也就是我們曾經介紹過的詞嵌入預訓練模型。

具體內容,請參見《如何用Python處理自然語言?(Spacy與Word Embedding)》和《如何用 Python 和 gensim 呼叫中文詞嵌入預訓練模型?》。

注意如果你有多個預訓練模型可以選擇,那麼儘量選擇與你要解決任務的文字更為接近的那種。

畢竟預訓練模型來自於統計結果。兩種差別很大的語料,詞語在上下文中的含義也會有顯著差異,導致語義的刻畫不夠準確。

如果你需要在分類的過程中,同時考慮語義和語言單元順序等資訊,那麼你可以這樣做:

第一步,利用詞嵌入預訓練模型,把你的輸入語句轉化為張量,這解決了詞語的語義問題;

第二步,採用一維卷積神經網路(Conv1D)模型,或者迴圈神經網路模型(例如 LSTM),構造分類器。

注意這一步中,雖然兩種不同的神經網路結構,都可以應用。但是一般而言,處理二元分類問題,前者(卷積神經網路)表現更好。

如何用機器學習處理二元分類任務?

因為卷積神經網路實際上已經充分考慮了詞語的順序問題;而迴圈神經網路用在此處,有些“大炮轟蚊子”。很容易發生過擬合,導致模型效果下降。

實施

如果你瞭解二元分類問題的整體流程,並且做好了模型的選擇,那麼實際的機器學習過程,是很簡單的。

對於大部分的普通機器學習問題,你都可以用 Scikit-learn 來呼叫模型。

注意其實每一個模型,都有引數設定的需要。但是對於很多問題來說,預設初始引數,就能帶來很不錯的執行結果。

如何用機器學習處理二元分類任務?

Scikit-learn 雖好,可惜一直不能很好支援深度學習任務。

因而不論是影像還是文字分類問題,你都需要挑選一個好用的深度學習框架。

注意,目前主流的深度學習框架,很難說有好壞之分。

如何用機器學習處理二元分類任務?

畢竟,在深度學習領域如此動盪激烈的競爭環境中,“壞”框架(例如功能不完善、效能低下)會很快被淘汰出局。

然而,從易用性上來說,框架之間確實有很大區別。

易用到了一種極致,便是蘋果的 Turi Create 。

從《如何用Python和深度神經網路識別影像?》和《如何用Python和深度神經網路尋找近似圖片?》這兩篇文章中,你應該有體會,Turi Create 在影像識別和相似度查詢問題上,已經易用到你自己都不知道究竟發生了什麼,任務就解決了。

但是,如果你需要對於神經網路的結構進行深度設定,那麼 Turi Create 就顯得不大夠用了。

畢竟,其開發的目標,是給蘋果移動裝置開發者賦能,讓他們更好地使用深度學習技術。

如何用機器學習處理二元分類任務?

對於更通用的科研和實踐深度學習任務,我推薦你用 Keras 。

它已經可以把 Theano, Tensorflow 和 CNTK 作為後端。

對比上面那張深度學習框架全家福,你應該看到,Keras 覆蓋了 Google 和 微軟自家框架,幾乎佔領了深度學習框架界的半壁江山。

照這勢頭髮展下去,一統江湖也說不定哦。

為什麼 Keras 那麼厲害?

因為簡單易學。

簡單易學到,顯著拉低了深度學習的門檻。

就連 Tensorflow 的主力開發人員 Josh Gordon,也已經認為你根本沒必要去學習曾經的 Tensorflow 繁複語法了。

如何用機器學習處理二元分類任務?

直接學 Keras ,用它完成任務,結束。

另外,使用深度學習,你可能需要 GPU 硬體裝置的支援。這東西比較貴。建議你採用租用的方式。

如何用雲端 GPU 為你的 Python 深度學習加速?》提到的 FloydHub,租賃一個小時,大概需要1美元左右。註冊賬號就贈送你2個小時;

如何用機器學習處理二元分類任務?

至於《如何免費雲端執行Python深度學習框架?》中提到的 Google Colab ,就更慷慨了——到目前為止,一直是免費試用。

喜歡請點贊。還可以微信關注和置頂我的公眾號“玉樹芝蘭”(nkwangshuyi)

如果你對資料科學感興趣,不妨閱讀我的系列教程索引貼《如何高效入門資料科學?》,裡面還有更多的有趣問題及解法。

相關文章