【特徵工程】一種異常值檢測方法、原理、代碼實現 (基於箱線圖)

先介紹使用到的方法原理,也就是一種異常檢測的方法。
首先要先了解箱線圖。

箱線圖

箱線圖(Boxplot)也稱箱須圖(Box-whisker Plot),是利用數據中的五個統計量:最小值、第一四分位數、中位數、第三四分位數與最大值來描述數據的一種方法,它也可以粗略地看出數據是否具有有對稱性,分佈的分散程度等信息,特別可以用於對幾個樣本的比較。 ——MBAlib 箱線圖

先看一下什麼是箱線圖,下面這個是常見的箱線圖樣子。

箱線圖1

具體含義如下,首先計算出第一四分位數(Q1)、中位數、第三四分位數(Q3)
中位數我們都知道,就是將一組數字按從小到大的順序排序後,處於中間位置(也就是50%位置)的數字。
同理,第一四分位數、第三四分位數是按從小到大的順序排序後,處於25%、75%的數字。

IQR=Q3Q1IQR=Q3-Q1 ,那麼 Q3+1.5(IQR)Q3+1.5(IQR)Q11.5(IQR)Q1-1.5(IQR) 之間的值就是可接受範圍內的數值,這兩個值之外的數認爲是異常值。

Q31.5IQRQ3+1.5IQR(四分位距)和 Q11.5IQRQ1-1.5IQR 處畫兩條與中位線一樣的線段,這兩條線段爲異常值截斷點,稱其爲內限;在 Q33IQRQ3+3IQRQ13IQRQ1-3IQR 處畫兩條線段,稱其爲外限
處於內限以外位置的點表示的數據都是異常值,其中在內限與外限之間的異常值爲溫和的異常值(mild outliers),在外限以外的爲極端的異常值(li)的異常值extreme outliers。這種異常值的檢測方法叫做Tukey’s method

從矩形盒兩端邊向外各畫一條線段直到不是異常值的最遠點 表示該批數據正常值的分佈區間點,示該批數據正常值的分佈區間。
一般用“〇”標出溫和的異常值,用“*”標出極端的異常值。

箱線圖含義

python 代碼分享

這段檢測異常值的代碼是從kaggle上看到的,很簡單也很有用。
代碼原地址:https://www.kaggle.com/yassineghouzam/titanic-top-4-with-ensemble-modeling/notebook

通過上面對箱線圖的介紹,相信同時也清楚了異常值檢測的方法。
假設我們現在已經有了一份pandas.DataFrame讀取後的數據df,其中需要進行檢測的列保存在features列表中,每個樣本能忍受的最大異常值數量爲n。

# Outlier detection 
import pandas as pd
import numpy as np
from collections import Counter

def detect_outliers(df,n,features):

    outlier_indices = []
    
    # iterate over features(columns)
    for col in features:
        # 1st quartile (25%)
        Q1 = np.percentile(df[col], 25)
        # 3rd quartile (75%)
        Q3 = np.percentile(df[col],75)
        # Interquartile range (IQR)
        IQR = Q3 - Q1
        
        # outlier step
        outlier_step = 1.5 * IQR
        
        # Determine a list of indices of outliers for feature col
        outlier_list_col = df[(df[col] < Q1 - outlier_step) | (df[col] > Q3 + outlier_step )].index
        
        # append the found outlier indices for col to the list of outlier indices 
        outlier_indices.extend(outlier_list_col)
        
    # select observations containing more than 2 outliers
    outlier_indices = Counter(outlier_indices)        
    multiple_outliers = list( k for k, v in outlier_indices.items() if v > n )
    
    return multiple_outliers   
# detect outliers from "Col1","Col2","Col3","Col4"
df = pd.read_csv("data.csv")
Outliers_to_drop = detect_outliers(df,2,["Col1","Col2","Col3","Col4"])
# Drop outliers
df = df.drop(Outliers_to_drop, axis = 0).reset_index(drop=True)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章