1. 程式人生 > >資料分析:異常值檢測--箱型圖

資料分析:異常值檢測--箱型圖

在做資料分析時,我們免不了要檢查資料中的異常值,但是什麼樣的資料算作異常呢。有人說很大或者很小的值,那到底多大多小的值算異常。箱型圖就可以很好的解決這個問題。我們都知道折線圖、柱狀圖等,但很少使用過箱型圖。關於箱型圖,百度百科的解釋為:

箱形圖(Box-plot)又稱為盒須圖、盒式圖或箱線圖,是一種用作顯示一組資料分散情況資料的統計圖。因形狀如箱子而得名。在各種領域也經常被使用,常見於品質管理。它主要用於反映原始資料分佈的特徵,還可以進行多組資料分佈特徵的比 較。箱線圖的繪製方法是:先找出一組資料的最大值、最小值、中位數和兩個四分位數;然後, 連線兩個四分位數畫出箱子;再將最大值和最小值與箱子相連線,中位數在箱子中間。

通過定義可以看出,箱型圖可以很好的展示資料的基本分佈情況,而且可以很方便的檢測出資料中的異常值。

我們先介紹兩種箱型圖的實現方式,再詳解箱型圖含義,最後結合Kaggle資料集看看如何使用。

1.pandas實現

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df = np.random.randn(3,4)
df = pd.DataFrame(df)
df.boxplot()

這裡用的pandas自帶的繪圖方法,其實就是matplotlib。df的資料內容為:

	    0            1	        2	        3
0	-0.803730	2.666505	1.668437	-2.542154
1	0.996711	0.532948	1.484964	-0.452487
2	-1.036156	0.127020	-0.381138	-0.688037

得到的箱型圖如下:

2.matplotlib實現

import matplotlib.pyplot as plt
import numpy as np
 
all_data = [np.random.normal(0, std, 100) for std in range(1, 4)]
 
fig = plt.figure(figsize=(8,6))
 
plt.boxplot(all_data,
            notch=False, # 是否用盒子形狀
            sym='rs',    # 用紅色矩形展示異常值
            showmeans=True,#展示均值點
            patch_artist=False,#是否要填充色
            meanline=False,#展示均值線
            widths=0.5,#設定箱盒寬度
            vert=True)   #垂直展示圖形
 
plt.xticks([y+1 for y in range(len(all_data))], ['x1', 'x2', 'x3'])
plt.xlabel('measurement x')
t = plt.title('Box plot')
plt.show()

圖形如下:

t

水平展示的效果如下:

f

3.圖形詳解

我們結合例子來講解圖形所代表的意思,例子來源於MBA智庫百科,連結在文末。我們有如下資料:

2710 2755 2850 | 2880 2880 2890 | 2920 2940 2950 | 3050 3130 3325  

計算Q1,Q2,Q3,

Q1 = (2850 + 2880) / 2 = 2865 

Q2 = (2890 + 2920) / 2 = 2905

Q3 = (2950 + 3050) / 2 = 3000

也就是說,中位數是2905,第一個四分位數(也叫下四分位數)Q1 = 2865,第三個四分位數(也叫上四分位數)Q3 = 3000。有了四分位數Q1和Q3,可以算出四分位數全距IQR = Q3 − Q1。從而得到下限和上限。在上下限之外的點就是異常點。如下圖所示:

 

f

4.實際應用

我們通過箱型圖來檢測Kaggle資料集Give Me Some Credits中的異常值。先看程式碼:

import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv('/dataset/cs-training.csv')
#檢視資料集中的如下幾列資料
data = data[['NumberOfTime30-59DaysPastDueNotWorse','NumberOfTimes90DaysLate','NumberOfTime60-89DaysPastDueNotWorse','age']]

#使用pandas繪製
plt.figure(figsize=(10,5))
data.boxplot(sym='r*',vert=False,patch_artist=True,meanline=False,showmeans=True)
plt.show()

得到圖形:

e

我們可以看出,age的取值有一個明顯的異常點0。另外三列也有明顯的異常點,97和98。對於這樣的異常值直接刪除即可。是不是很方便、很直觀。箱型圖簡直就是資料分析中的異常值檢測的神器。

 

參考資料:

https://matplotlib.org/gallery/pyplots/boxplot_demo_pyplot.html#sphx-glr-gallery-pyplots-boxplot-demo-pyplot-py

http://blog.topspeedsnail.com/archives/737

https://wiki.mbalib.com/wiki/%E7%AE%B1%E7%BA%BF%E5%9B%BE