Semi-supervised Learning in sklearn 0.24!! 如何利用那些沒有label的data

倢愷 Oscar
17 min readFeb 11, 2021

--

這篇會簡介semi-supervised Learning的概念,然後會先跳過研究進展以及背後原理的深入討論,直接進入sklearn有的3個function,著重說明這3個function的邏輯。

相信大家都清楚supervised跟unsupervised learning的差異了,但是如果今天你得training data中有一些是有label有一些則沒有label你要如何處理呢?這裡就要提到一個在研究界已經紅了很久的概念Semi-supervised Learning,以及目前sklearn支援的2大類方法。

Semi-supervised Learning的概念就是「利用小部分labeled data及大部分unlabeled data來train一個模型

在過去,如果我們發現training dataset裡面有一些data並沒有label,我們大概率就會直接把這些data丟掉,這是以ML學習者的角度出發來思考問題,因為ML的課程、書籍都告訴我們幾乎所有ML演算法都需要大量的data才能夠訓練到好,但是如果反過來,以ML開發者的角度來想,我們在要真的把ML演算法應用到各種場域,我們勢必會遇到labeled data不足的問題,這是一個必須被解決的問題,因此其實在這幾年包含Unsupervised Learning、Semi-supervised Learning、Weakly Supervised Learning、Active Learning等領域在研究界都非常活躍。

為甚麼labeled data會不足?

這個問題在很多人耳中可能聽起來會像廢話,大家可能直覺想「labeled data不足就是因為錢不夠、人力不足,所以沒有辦法label出足夠量的data」,這個理解我認為算是對了一半,但是也遺漏了一半。

先想想我們的labeled data的來源是哪裡?

  1. Human Annotation:也就是請專人來label我們的每一筆,這也是課堂中最常講的情景,大家一聽到labeled data腦中就會浮出一群工人在電腦前面對著一張一張圖片進行label的情景,而這也的確是很普遍的情況,Amazon也依此推出了Amazon Mechanical Turk的online crowd source labeling system。
    而如果Human Annotation的話,的確如果今天沒有錢、找不到人label,是我們拿不到data的一個問題,另外如果這個data label所需的專業度很高,像是醫療圖像的label一般最少也要是醫學院學生,那我們也很難取得大量的label。
  2. Human Behavior:想想看youtube的影片推薦系統,今天不會有一個工人在電腦判斷你會不會點擊某個影片來進行label,影片推薦系統的label就是你自己的behavior(行為),你點擊進入哪一個影片,會變成youtube演算法訓練的label,而基於這個label它會去慢慢越來越清楚要推薦你甚麼。(這邊現在有些研究顯示不一定是推薦越來越準,而是你越來越容易被推薦系統牽著走,但是這不是今天討論的主軸。)而如果是這種Behavior data的話,其實通常都可以取得大量的資料,像是一般的推薦系統、Time Series Forecasting、行為預測系統都是這個類型。

所以這裡先矯正一個大觀念,如果你的labeled data很少,先想想有沒有辦法用某種Human Behavior來當作你的label來源。

如果公司想要開發ML產品的話也建議找有Behavior Data可以當作label的題目。跟AI/ML產品比較相關的議題我也不是專家,找時間再分享我的觀點,這裡的目的只是想先帶大家從產品設計的角度切入labeled data不足這個問題。

那如果今天我們很確定我們的labeled data來源只能是Human Annotation,那是不是資金比較缺乏的公司就沒有機會?

這個問題就是今天主要要介紹的Semi-supervised Learning,能夠提供給大家一個可能可行的方法。

但是大家也可以想想如果反過來,今天是資金充足的大公司難道就沒有這個問題嗎?這個問題我會在3月用一篇文章來說明,後續再把連結補上來。

Semi-Supervised Learning簡介

Wikipedia針對Semi-Supervised Learning的介紹裡面有一張非常有趣的圖片。

wikipedia Semi-Supervised Learning

假設我們今天只有2筆labeled data,那就如圖片的上側,我們可能會隨意的畫出一個decision boundary,但是假設我們除了2筆labeled data以及一大堆unlabeled data,如下圖,那我們可能會依據labeled data跟unlabeled data的關係畫出一條更符合我們data情況的decision boundary。

這就是Semi-Supervised Learning的核心精神!

Semi-Supervised Learning其實就是在data與data間的關聯性,就如clustering一樣,如果我們能夠發現某些data的feature、representation(表徵)有某種一致性,那我們就能利用這個資訊來 improve我們的supervised model。

Semi-supervised Learning in Sklearn

這篇我先跳過介紹semi-supervised learning背後的假設、理論,直接介紹sklearn裡面3個semi-supervised learning的function。詳細理論會另開一篇詳解目前semi-supervised learning的研究進度。

在sklearn裡面semi-supervised的方法主要分為兩類

  1. Label Propagation:由不同data之前的similarity來找到labeled data跟unlabeled data之間的關係,把每個unlabeled data填入一個跟它最相近的labeled data的label。
  2. Self Training:用model去找出labeled data跟unlabeled data之間的關聯性,先從labeled data學出最初步的classifier,再用這個model去predict unlabeled data,並把model有最高confidence的幾筆unlabeled data填入model的prediction。

這兩個方法的侷限性其實都還是很大,label propagation要先找到好的similarity function,如果今天用錯誤的similarity來衡量你的data,那它也有可能完全填錯label,導致最終model學出更錯誤的decision boundary,而self training最大的限制就是初步的classifier可能就學不起來

Label Propagation

label propagation在sklearn裡面主要有兩個function:LabelPropagationLabelSpreading,我先著重講LabelPropagation的流程,再簡單講LabelSpreading的差別。

LabelPropagation

這邊我只會做概念型的介紹,因為使用上大家比較還是直接比performance,詳細Label Propagation流程可以參考https://www.youtube.com/watch?v=OI0Jo-5d190

Sklearn有一個LabelPropagation的Demo圖片

sklearn Labelpropagation demo: https://scikit-learn.org/stable/auto_examples/semi_supervised/plot_label_propagation_structure.html

原本橘色的點在LabelPropagation後被填入了他們可能的Label。

LabelPropagation的流程是

  1. 先決定一個kernel function,假設這裡使用最基本的KNN,並且K=1,這個kernel function會幫你建立點與點之間的關係。
  2. 把所有data的1-NN全部算出來,也就是說如果我們有N個點,那我們就會有一個N*N的connectivity matrix(我們也會稱為affinity diagram),如果「跟第i個點最靠近」的是第j個點,那在i row, j col的地方就會被標為1,而i row的其他col就會都被標為0,這會是一個非常sparse的matrix,所以sklearn底層會轉換成sparse matrix處理。
  3. 基於這個connectivity matrix,我們去propagate所有的labeled data,也就是說把所有跟labeled data最近的點都標入該label,Ex : 如果第2筆data有label,而label是’cat’,而跟第2筆data最近的是第15筆data,那我們就把第15筆data也填入’cat’,這時我們有一部份unlabeled data就晉升成為labeled data了。
  4. 確認目前還有沒有unlabeled data,如果有的話再次執行2~4。

從上面的流程大家應該可以看出來,以LabelPropagation而言,最重要的是kernel function,今天用KNN來算,我們就是預設「兩點的Euclidean距離會表示這兩點的相似程度,距離越近越相似」。

而在sklearn的LabelPropagation最重要的function parameter也是kernel。

LabelPropagation Parameters:

  1. kernel:在目前的版本只有KNN跟rbf kernel兩種,兩者都是基於距離的kernel,不過rbf通常更容易畫出non linear boundary,我習慣上都是使用rbf kernel。
  2. gamma:rbf kernel的gamma parameter,這個要花時間tune,gamma越小代表每個點的影響範圍越大,gamma越大代表每個點影響範圍越小,類似於KNN裡面的n_neighbors,如果n_neighbors越大代表看的點越多所以會參考越大的範圍,一般gamma都要花一段時間tune才能得到好的結果。
  3. n_neighbors:就是KNN的n_neighbors,一樣要花時間tune。

這邊特別提醒一下,因為LabelPropagtion的kernel目前都只有基於distance function,所以我們data的scaling就非常重要,如果今天feature 1的scale是-10000~10000,而feature 2的scale是-1~1,那今天我們distance function就會幾乎忽略feature 2,以feature 1的距離為主,所以我在做LabelPropagation前都會做StandardScaler

LabelSpreading

LabelSpreading背後的數學難很多,簡單來講他做了兩個改變,讓自己更robust,不容易被noise data影響到,所以這邊小結論就是我基本上都用LabelSpreading為主,很少會使用LabelPropagation,具體細節可以參考論文

在parameter上LabelSpreading多了一個alpha要調,這很重要!!

alpha這裡是所謂的Clamping factor,Clamping的動作是,當我們每次要為unlabeled data填入label的時候,我們讓其中一部份的labeled data的label也可以被改變。

也就是說我們默認「Label是有可能是錯的」,不論這個Label是過程中才被填入的還是一開始就有的。

這邊要先引入Label distribution的概念,在Label Propagation跟Label Spreading裡,我們每個labeled data其實都有一個Label distribution,也就是說這個data是各個label的可能性,也就是說一張圖片可能0.8的機率是貓、0.15的機率是狗、0.05的機率是熊。unlabeled data是沒有Label distribution的。

而alpha的值可以是0~1,指的是我們要丟掉多少原本的label distribution,如果是alpha = 0的話,那我們把原本的label distribution全部保留下來,所有labeled data完全忽視這次的更新,而如果alpha = 1,那我們就不顧原本的label distribution,labeled data也以每一輪新得到的label distribution為主,如果alpha = 0.2那代表我們原本的label distribution保留0.8而使用新的label distribution*0.2。

所以alpha如果調得過大可能會讓你的LabelSpreading收斂不了,而alpha太小可能讓一些不好的點過早確定而沒有反悔的機會,進而影響到其他點,一般我會控在0.2~0.5之間,可以稍微tune一下。

這邊有一個小trick,不論是使用LabelSpreading還是LabelPropagation,必須先做好feature engineering跟feature selection以及remove outlier再來做!!甚至可以用一些Deep的model抽出high level feature,像是autoencoder,使用raw data直接做大部分時候是會直接爛掉。

Self Training

上面講的都是在sklearn 0.22就更新的Label Propagation系列方法,而這次sklearn 0.24.1其中一個重點就是更新的self training這種semi-supervised Learning method。

Self-Training的概念非常非常簡單XD

Self-Training步驟:

  1. 拿labeled data先train一個model
  2. 讓model predict在unlabeled data上
  3. 把model confidence最高幾個的unlabeled data標入model的prediction label,這些unlabeled data晉升成為labeled data。
  4. 確定現在還有沒有unlabeled data,如果有的話回到第一步,如果超過max_iteration則把剩餘所有unlabeled data填完就結束。

這邊有一個重點,就是confidence是怎麼來的?而這裡我們的邏輯就是,看model prediction的probability,如果probability越高,代表越confidence。Ex: 如果今天有兩張圖片A、B,A圖片model prediction是0.8機率是貓、0.15機率是狗、0.05機率是熊,而B圖片model prediction是0.95機率是貓、0.03機率是狗、0.02機率是熊,那我們認為B的confidence比較高。
也就是說我們只看每個data得到最高機率的那個class,然後比較probability,看哪個data得到的最高probability比較高,依此選出confidence比較高的data。

但是也因為這個算confidence的方法,我們的model必須要有predict_proba這個function。

具體那些model有predict_proba可以藉由下面這段code檢查

from sklearn.utils.testing import all_estimators

estimators = all_estimators()

for name, class_ in estimators:
if hasattr(class_, 'predict_proba'):
print(name)

SelfTrainingClassifier in sklearn 0.24.1

parameters:

  1. base_estimator:你要用來train的model
  2. criterion: {‘threshold’, ‘k_best’}:每次要挑哪些unlabeled data填入predict label的依據,threshold代表只要最大機率大於一個定值就都填入,k_best代表選前k個擁有最大的最大機率的model填入。
  3. threshold:你要設定的threshold,一定要在0~1之間,一般會比較靠近1
  4. k_best:你要選前幾大的填入,k是20代表選前20大。

剛剛有提到,因為confidence的算法牽扯到predict_proba,所以要選那些有predict_proba的model。

但是這邊更重要要理解的是下面這個問題:

哪些model的output具有機率性質???

像是Naive Bayes本身就是以Bayesian rule設計的model,他就完全有機率性質,logistic regression因為output在0~1之間並且總和為1所以也可以使用,但是像是SVM、random forest本身就沒有機率性質,但是卻會發現在sklearn裡面SVM跟random forest都有predict_proba

SVM跟random forest的predict_proba都是後來設計出來的,所以像是random forest的機率性質就很糟糕,很常會over estimated一個prediction的probability,也就是說random forest動輒就predict出>0.95的機率。

所以即便有些model具有predict_proba,使用它們來做self training時還是要非常小心,而有些model甚至沒有predict_proba,遇到這種情況的時候我們可以做Callibration。

Callibration可以讓不具備機率性值的model變成有predict_proba,或是讓原本predict_proba比較不精準的model變得有更精準的機率預測。

具體可以參考CalibratedClassifierCV,詳細內容我之後再開另外一篇來討論XD(一直亂開清單哈哈

如果喜歡這篇文章可以幫我多拍手幾次XD,或是對於哪個類型文章有興趣都可以在留言區跟我講~ 後續會以中難度的ML/DS/AI知識為主,以及AI/HCI研究相關知識。

references:

ZhuЃ, Xiaojin, and Zoubin GhahramaniЃн. “Learning from labeled and unlabeled data with label propagation.” (2002).

Zhou, Dengyong, et al. “Learning with local and global consistency.” Advances in neural information processing systems 16.16 (2004): 321–328.

--

--

倢愷 Oscar

我是倢愷,CTO at TeraThinker an AI Adaptive Learning System Company。AI/HCI研究者,超過100場的ML、DL演講、workshop經驗。主要學習如何將AI落地於業界。 有家教、演講合作,可以email跟我聯絡:axk51013@gmail.com