特徵工程之資料預處理(下)

spearhead_cai發表於2019-02-13

機器學習入門系列(2)--如何構建一個完整的機器學習專案,第四篇!

該系列的前三篇文章:

上篇文章介紹瞭如何處理缺失值和圖片資料擴充的問題,這篇文章會介紹另外兩種情況,處理異常值和類別不平衡的問題。


3.1.3 處理異常值

異常值分析是檢驗資料是否有錄入錯誤以及含有不合常理的資料。忽視異常值的存在是十分危險的,不加剔除地把異常值包括進資料的計算分析過程中,對結果會產生不良影響。

異常值是指樣本中的個別值,其數值明顯偏離其餘的觀測值。異常值也稱為離群點,異常值分析也稱為離群點分析。

異常值檢測
  1. 簡單統計:比如利用pandas庫的describe()方法觀察資料的統計性描述,或者簡單使用散點圖也能觀察到異常值的存在,如下圖所示:

特徵工程之資料預處理(下)

  1. 3∂原則: 這個原則有個條件:資料需要服從正態分佈。在 3∂ 原則下,異常值如超過 3 倍標準差,那麼可以將其視為異常值。正負3∂ 的概率是 99.7%,那麼距離平均值 3∂ 之外的值出現的概率為P(|x-u| > 3∂) <= 0.003,屬於極個別的小概率事件。如果資料不服從正態分佈,也可以用遠離平均值的多少倍標準差來描述。如下圖所示:

特徵工程之資料預處理(下)

  1. 箱型圖

這種方法是利用箱型圖的四分位距(IQR)對異常值進行檢測,也叫Tukey‘s test。箱型圖的定義如下:

特徵工程之資料預處理(下)

四分位距(IQR)就是上四分位與下四分位的差值。而我們通過IQR的1.5倍為標準,規定:超過上四分位+1.5倍IQR距離,或者下四分位-1.5倍IQR距離的點為異常值。下面是Python中的程式碼實現,主要使用了numpypercentile方法。

Percentile = np.percentile(df['length'],[0,25,50,75,100])
IQR = Percentile[3] - Percentile[1]
UpLimit = Percentile[3]+ageIQR*1.5
DownLimit = Percentile[1]-ageIQR*1.5
複製程式碼

也可以使用seaborn的視覺化方法boxplot來實現:

f,ax=plt.subplots(figsize=(10,8))
sns.boxplot(y='length',data=df,ax=ax)
plt.show()
複製程式碼

如下圖所示:

特徵工程之資料預處理(下)

上面三種方法是比較簡單的異常值檢測方法,接下來是一些較複雜的異常值檢測方法,因此這裡簡單介紹下這些方法的基本概念。

  1. 基於模型預測

顧名思義,該方法會構建一個概率分佈模型,並計算物件符合該模型的概率,將低概率的物件視為異常點。

如果模型是簇的組合,則異常點是不在任何簇的物件;如果模型是迴歸,異常點是遠離預測值的物件(就是第一個方法的圖示例子)。

優缺點

  • 有堅實的統計學理論基礎,當存在充分的資料和所用的檢驗型別的知識時,這些檢驗可能非常有效;
  • 對於多後設資料,可用的選擇少一些,並且對於高維資料,這些檢測可能性很差。
  1. 基於近鄰度的離群點檢測

一個物件的離群點得分由到它的 k-最近鄰(KNN)的距離給定

這裡需要注意 k 值的取值會影響離群點得分,如果 k 太小,則少量的鄰近離群點可能會導致較低的離群點得分;如果 k 太大,則點數少於 k 的簇中所有的物件可能都成了離群點。為了增強魯棒性,可以採用 k 個最近鄰的平均距離。

優缺點

  • 簡單;
  • 基於鄰近度的方法需要 O(m2) 時間,大資料集不適用;
  • k 值的取值導致該方法對引數的選擇也是敏感的;
  • 不能處理具有不同密度區域的資料集,因為它使用全域性閾值,不能考慮這種密度的變化。
  1. 基於密度的離群點檢測

一種常用的定義密度的方法是,定義密度為到k個最近鄰的平均距離的倒數。如果該距離小,則密度高,反之亦然。

另一種密度定義是使用 DBSCAN 聚類演算法使用的密度定義,即一個物件周圍的密度等於該物件指定距離 d 內物件的個數。

優缺點:

  • 給出了物件是離群點的定量度量,並且即使資料具有不同的區域也能夠很好的處理;
  • 與基於距離的方法一樣,這些方法必然具有 O(m2) 的時間複雜度。對於低維資料使用特定的資料結構可以達到 O(mlogm)
  • 引數選擇是困難的。雖然 LOF 演算法通過觀察不同的 k 值,然後取得最大離群點得分來處理該問題,但是,仍然需要選擇這些值的上下界。
  1. 基於聚類的離群點檢測

一個物件是基於聚類的離群點,如果該物件不強屬於任何簇,那麼該物件屬於離群點。

離群點對初始聚類的影響:如果通過聚類檢測離群點,則由於離群點影響聚類,存在一個問題:結構是否有效。這也是 k-means 演算法的缺點,對離群點敏感

為了處理該問題,可以使用如下方法:物件聚類,刪除離群點,物件再次聚類(這個不能保證產生最優結果)。

優缺點:

  • 基於線性和接近線性複雜度(k均值)的聚類技術來發現離群點可能是高度有效的;
  • 簇的定義通常是離群點的補集,因此可能同時發現簇和離群點;
  • 產生的離群點集和它們的得分可能非常依賴所用的簇的個數和資料中離群點的存在性;
  • 聚類演算法產生的簇的質量對該演算法產生的離群點的質量影響非常大。
  1. 專門的離群點檢測

除了以上提及的方法,還有兩個專門用於檢測異常點的方法比較常用:One Class SVMIsolation Forest

異常值處理
  • 刪除含有異常值的記錄:直接將含有異常值的記錄刪除;
  • 視為缺失值:將異常值視為缺失值,利用缺失值處理的方法進行處理;
  • 平均值修正:可用前後兩個觀測值的平均值修正該異常值;
  • 不處理:直接在具有異常值的資料集上進行資料探勘;

將含有異常值的記錄直接刪除的方法簡單易行,但缺點也很明顯,在觀測值很少的情況下,這種刪除會造成樣本量不足,可能會改變變數的原有分佈,從而造成分析結果的不準確。視為缺失值處理的好處是可以利用現有變數的資訊,對異常值(缺失值)進行填補。

在很多情況下,要先分析異常值出現的可能原因,在判斷異常值是否應該捨棄,如果是正確的資料,可以直接在具有異常值的資料集上進行挖掘建模。

3.1.4 處理類別不平衡問題

什麼是類別不平衡呢?它是指分類任務中存在某個或者某些類別的樣本數量遠多於其他類別的樣本數量的情況。

比如,一個十分類問題,總共有 10000 個樣本,但是類別 1 到 4 分別包含 2000 個樣本,剩餘 6 個類別的樣本數量加起來剛剛 2000 個,即這六個類別各自包含的樣本平均數量大約是 333 個,相比前四個類別是相差了 6 倍左右的數量。這種情況就是類別不平衡了。

那麼如何解決類別不平衡問題呢?

這裡介紹八大解決辦法。

  1. 擴充資料集

首先應該考慮資料集的擴充,在剛剛圖片資料集擴充一節介紹了多種資料擴充的辦法,而且資料越多,給模型提供的資訊也越大,更有利於訓練出一個效能更好的模型。

如果在增加小類樣本數量的同時,又增加了大類樣本資料,可以考慮放棄部分大類資料(通過對其進行欠取樣方法)。

  1. 嘗試其他評價指標

一般分類任務最常使用的評價指標就是準確度了,但它在類別不平衡的分類任務中並不能反映實際情況,原因就是即便分類器將所有類別都分為大類,準確度也不會差,因為大類包含的數量遠遠多於小類的數量,所以這個評價指標會偏向於大類類別的資料。

其他可以推薦的評價指標有以下幾種

  • 混淆矩陣:實際上這個也是在分類任務會採用的一個指標,可以檢視分類器對每個類別預測的情況,其對角線數值表示預測正確的數量;
  • 精確度(Precision):表示實際預測正確的結果佔所有被預測正確的結果的比例,P=TP / (TP+FP)
  • 召回率(Recall):表示實際預測正確的結果佔所有真正正確的結果的比例,R = TP / (TP+FN)
  • F1 得分(F1 Score):精確度和召回率的加權平均,F1=2PR / (P+R)
  • Kappa (Cohen kappa)
  • ROC 曲線(ROC Curves):常被用於評價一個二值分類器的優劣,而且對於正負樣本分佈變化的時候,ROC 曲線可以保持不變,即不受類別不平衡的影響。

其中 TP、FP、TN、FN 分別表示正確預測的正類、錯誤預測的正類、預測正確的負類以及錯誤預測的負類。圖例如下:

特徵工程之資料預處理(下)

  1. 對資料集進行重取樣

可以使用一些策略該減輕資料的不平衡程度。該策略便是取樣(sampling),主要有兩種取樣方法來降低資料的不平衡性。

  • 對小類的資料樣本進行取樣來增加小類的資料樣本個數,即過取樣(over-sampling ,取樣的個數大於該類樣本的個數)。
  • 對大類的資料樣本進行取樣來減少該類資料樣本的個數,即欠取樣(under-sampling,取樣的次數少於該類樣本的個素)。

取樣演算法往往很容易實現,並且其執行速度快,並且效果也不錯。 一些經驗法則:

  • 考慮對大類下的樣本(超過 1 萬、十萬甚至更多)進行欠取樣,即刪除部分樣本;
  • 考慮對小類下的樣本(不足 1萬甚至更少)進行過取樣,即新增部分樣本的副本;
  • 考慮嘗試隨機取樣與非隨機取樣兩種取樣方法;
  • 考慮對各類別嘗試不同的取樣比例,比一定是 1:1,有時候 1:1 反而不好,因為與現實情況相差甚遠;
  • 考慮同時使用過取樣與欠取樣。
  1. 嘗試人工生成資料樣本

一種簡單的人工樣本資料產生的方法便是,對該類下的所有樣本每個屬性特徵的取值空間中隨機選取一個組成新的樣本,即屬性值隨機取樣

你可以使用基於經驗對屬性值進行隨機取樣而構造新的人工樣本,或者使用類似樸素貝葉斯方法假設各屬性之間互相獨立進行取樣,這樣便可得到更多的資料,但是無法保證屬性之前的線性關係(如果本身是存在的)。

有一個系統的構造人工資料樣本的方法 SMOTE(Synthetic Minority Over-sampling Technique)。SMOTE 是一種過取樣演算法,它構造新的小類樣本而不是產生小類中已有的樣本的副本,即該演算法構造的資料是新樣本,原資料集中不存在的。

它基於距離度量選擇小類別下兩個或者更多的相似樣本,然後選擇其中一個樣本,並隨機選擇一定數量的鄰居樣本,然後對選擇的那個樣本的一個屬性增加噪聲,每次處理一個屬性。這樣就構造了更多的新生資料。

python 實現的 SMOTE 演算法程式碼地址如下,它提供了多種不同實現版本,以及多個重取樣演算法。

github.com/scikit-lear…

  1. 嘗試不同分類演算法

強烈建議不要對待每一個分類都使用自己喜歡而熟悉的分類演算法。應該使用不同的演算法對其進行比較,因為不同的演算法適用於不同的任務與資料。

決策樹往往在類別不均衡資料上表現不錯。它使用基於類變數的劃分規則去建立分類樹,因此可以強制地將不同類別的樣本分開。目前流行的決策樹演算法有:C4.5、C5.0、CART和Random Forest等。

  1. 嘗試對模型進行懲罰

你可以使用相同的分類演算法,但使用一個不同的角度,比如你的分類任務是識別那些小類,那麼可以對分類器的小類樣本資料增加權值,降低大類樣本的權值(這種方法其實是產生了新的資料分佈,即產生了新的資料集),從而使得分類器將重點集中在小類樣本身上。

一個具體做法就是,在訓練分類器時,若分類器將小類樣本分錯時額外增加分類器一個小類樣本分錯代價,這個額外的代價可以使得分類器更加“關心”小類樣本。如 penalized-SVM 和 penalized-LDA 演算法。

如果你鎖定一個具體的演算法時,並且無法通過使用重取樣來解決不均衡性問題而得到較差的分類結果。這樣你便可以使用懲罰模型來解決不平衡性問題。但是,設定懲罰矩陣是一個複雜的事,因此你需要根據你的任務嘗試不同的懲罰矩陣,並選取一個較好的懲罰矩陣。

  1. 嘗試一個新的角度理解問題

從一個新的角度來理解問題,比如我們可以將小類的樣本作為異常點,那麼問題就變成異常點檢測與變化趨勢檢測問題。

  • 異常點檢測:即是對那些罕見事件進行識別。如通過機器的部件的振動識別機器故障,又如通過系統呼叫序列識別惡意程式。這些事件相對於正常情況是很少見的。
  • 變化趨勢檢測:類似於異常點檢測,不同在於其通過檢測不尋常的變化趨勢來識別。如通過觀察使用者模式或銀行交易來檢測使用者行為的不尋常改變。

將小類樣本作為異常點這種思維的轉變,可以幫助考慮新的方法去分離或分類樣本。這兩種方法從不同的角度去思考,讓你嘗試新的方法去解決問題。

  1. 嘗試創新

仔細對問題進行分析和挖掘,是否可以將問題劃分為多個更小的問題,可以嘗試如下方法:

  • 將你的大類壓縮成小類;
  • 使用 One Class 分類器(將小類作為異常點);
  • 使用整合方式,訓練多個分類器,然後聯合這些分類器進行分類;

對於類別不平衡問題,還是需要具體問題具體分析,如果有先驗知識可以快速挑選合適的方法來解決,否則最好就是逐一測試每一種方法,然後挑選最好的演算法。最重要的還是多做專案,多積累經驗,這樣遇到一個新的問題,也可以快速找到合適的解決方法。


小結

本篇文章介紹瞭如何檢測和處理缺失值,以及解決類別不平衡的問題,結合上一篇文章,基本就是常見的資料預處理內容。


參考:


歡迎關注我的微信公眾號--機器學習與計算機視覺,或者掃描下方的二維碼,大家一起交流,學習和進步!

特徵工程之資料預處理(下)

往期精彩推薦

機器學習系列
數學學習筆記
Github專案 & 資源教程推薦

相關文章