#分享 四個資料科學家常用的離群值檢測與處理方式
國立臺灣大學
《從離群值探索資料科學》
◆什麼是離群值(Outlier)?
有接觸過統計,或是機器學習的各位對於這個名詞一定不陌生。以機器學習來說,建立模型的基礎通常是來自資料集,若在收集資料的過程中,因某些狀況導致資料集中有部分資料的性質和內容與整體樣本差異很大,我們就會稱這些資料為離群值或者異常值。
◆為什麼離群值需要被關注?
離群值的發生通常是因為資料輸入時發生誤植、筆誤,也有可能是某個群體內的少數特例。在這樣的情況下,離群值的存在會破壞整個樣本的一致性,就像是壞了一鍋粥的那粒老鼠屎一樣,它會影響機器學習的效果還有預測的準確性,導致分析後的結果難以解釋。
離群值除了會影響到預測的準確性之外,它在某些特殊的應用場景其實扮演了非常重要的角色,例如疾病預測,如果一個人身上有些特殊的指標產生異常,或是一群人中有一小群人發生了異常生理現象(好比目前Covid19的疫情初期),這類的離群值就是一個非常重要的起點。
這類的情況也常用在網路詐騙、信用卡盜刷、網路攻擊等情況,整體來說,就是有一小群特別的資料,但會對整個群體產生重大影響的異常資料,所以離群值的偵測和處理,無論在統計或資料科學,都是一個重要的議題。
◆如何檢測離群值?
既然離群值會對我們的預測結果帶來重大的影響,找出他們也就變得相當重要。一般離群值的偵測方法會視資料集的特性進行選擇,有基於統計的原理、密度或聚類(clustering)的方式,以下將介紹4個在實務上經常使用的方法,希望可以幫助大家未來遇到類似的問題時能夠順利的解決。
(一)3∂法 ( ∂=standard deviation) / 3倍標準差法
如果資料集符合常態分布,那就可以用3∂ (3倍標準差法),因為常態分布的資料落在3倍標準差的機率是99.7%左右,如果跑到3倍標準差外的那些資料屬於小機率事件,這種資料可以歸為離群值。當然如果資料不符合常態分布,那你也可以自行設定遠離平均值外多少倍的標準差當作你認定的離群值。
相關程式碼歡迎到我的github:
(二)Boxplots法
這種方法是利用箱型圖(Boxplot)的四分位距(IQR)對離群值進行檢測,其中箱型圖的概念如下: 
四分位距(IQR)就是上四分位與下四分位的差值。而我們通過IQR的1.5倍為標準,規定:超過上四分位+1.5倍IQR距離,或者下四分位-1.5倍IQR距離的點為離群值,以下用python表示:
對於詳細的程式碼有興趣歡迎到我的 github:
(三)DBScan Clustering
DBScan是一種Cluster base的算法,它基於數據間的密度進行分群,可以處理多維度的資料進,其它Cluster Base的算法如k-means也可以分群。
DBScan有3個重要的points
・Core Point(核心點)
・Board Point (邊界點)
・Noise Point (離群點)
先用一張示意圖表示:
上面這些點是分佈在樣本空間的所有樣本,我們的目標是把這些在樣本空間中距離相近的歸類成一群。我們發現A點附近的點密度較大,黑色的圓圈根據一定的規則在這裡滾啊滾,最終收納了A附近的5個點,標記為黑色也就是定為同一個群(Cluster)。其它沒有被收納的根據一樣的規則成Cluster。
實務上我們在眾多樣本點中隨機選中一個點,圍繞這個被選中的樣本點畫一個圓,規定這個圓的半徑以及圓內最少包含的樣本點,如果在指定半徑內有足夠多的樣本點在內,那麼這個圓圈的圓心就轉移到這個內部樣本點,繼續去圈附近其它的樣本點,不斷滾來滾去的圈地,直到發現所圈住的樣本點數量少於預先指定的值,就停止了。那麼我們稱最開始那個點為核心點,如A,停下來的那個點為邊界點,如B、C,而最後沒圈到的那些點就是離群點,如N。
附上 python 程式碼給大家參考:
對於詳細的程式碼有興趣歡迎到我的 github:
除此之外,我也整理了一些關於DBScan的優缺點,讓大家對於這個方法有更進一步的認識。
優點:
1.可以對任意形狀的稠密數據集進行分群,相對的,K-Means之類的算法一般只適用於凸數據集。
2.可以在分群的同時發現異常點,對數據集中的異常點不敏感。
3.分群結果沒有偏倚,相對的,K-Means之類的算法,初始值對分群結果有很大影響。
缺點:
1.如果資料集的密度不均勻、分群間距差相差很大時,分群質量較差,這時不太適合用DBSCAN分群。
2.如果資料集較大時,Cluster收斂時間較長
3.調參相對於傳統的K-Means之類的分群算法稍復雜,主要需要對距離閾值eps,鄰域樣本數閾值Min-points聯合調參,不同的參數組合對最後的分群效果有較大影響。
(四)孤立森林 (Isolation Forest)
孤立森林是一種非監督是學習的演算法,屬於集成學習的決策樹家族。此方法與前述所提到的方法較不相同,直觀來說,我們可以將離群值理解為分佈稀疏且離密度高的群體較遠的點。用統計學來解釋,在資料空間裡面,分佈稀疏的區域表示資料發生在此區域的機率很低,因而可以認為落在這些區域裡的資料是異常的。
以下圖為例,於A資料而言,與它相近的資料很多,而就B資料而言,在它附近的資料很少,
也就是說 「在A周圍區域"發現資料"的機率比較高」,在B周圍區域"發現資料"的機率比較低。
接下來我們把資料的屬性擴展到二維向量,它的資料分布可能會長的像下圖
那更多的資料屬性就可以理解成更高的維度,以此類推。 
了解了上述的概念之後,我們來看孤立森林 (Isolation Forest) 演算法,首先森林是由樹所組成的, 我們定義一下何謂Isolation Tree(簡稱iTree)?
iTree是一種隨機二元樹,每個節點有兩個子節點。給定資料集D,這裡D的所有屬性都是連續型的變量,iTree的構成過程如下:
・隨機選擇一個屬性Attr;
・隨機選擇該屬性的值Value;
・根據Attr對每條記錄進行分類,把Attr小於Value的記錄放在左子節點,把大於等於Value的記錄放在右子節點。
・遞回執行,直到滿足以下條件
。傳入數據集只剩一個或都相同
。樹的高度達到我們設定的上限
我們可以直觀的理解,如果是A資料,那由A構成的iTree高度應該會比B來的高。當然在實務上,一筆資料應該會有多個屬性,所以要決定資料是否屬於離群值,我們不會只比一個欄位。如上所述,一個屬性產生一個iTree,那多個屬性就會有多個iTree,那多個Tree進行ensemble的比較後,我們就可以預測那些資料可能是離群值。
以下附上程式碼給大家參考:
執行的結果如下圖所示:
對於詳細的程式碼有興趣歡迎到我的 github:
◆面對這些離群值,我們該怎麼處理?
前面提到關於離群值的檢測方法,你一定很好奇接下來該怎麼處理這些離群值。離群值的出現固然會對資料產生影響,但在處理時必須小心謹慎,結合專業知識與統計的方法,不能貿然的對資料進行隨意的變動,以下整理四個常見的處理方法:
1.直接刪除:確認過離群值對於資料集來說並無存在特殊意義,直接將該值刪除。
2.視為遺失值:將異常值視為遺失值,後續利用處理缺失值的方法進行。
3.用平均值調整:利用前後兩個資料點的平均值修正該異常值。
4.不處理:忽視異常值,直接對資料集進行後續分析。
總結來說,異常值的處理要根據實際的情況作考慮,有一些模型對於異常值不太敏感,即使資料集存在異常值也不影響模型效果。但是,像是邏輯斯回歸(Logistic regression) 這類模型對於異常值非常敏感,若是不處理可能會產生過度擬合( overfitting )的結果。









