**數據質量檢查是在完成寬表數據開發后進行的,主要包括四個方面:重復值檢查、缺失值檢查、數據傾斜檢查、異常值檢查。**數據行業有一句很經典的話——“垃圾進,垃圾出”(Garbage in, Garbage out, GIGO),意思就是,如果使用的基礎數據有問題,那基於這些數據得到的任何產出都是沒有價值的。而對於數據分析挖掘而言,只有一份高質量的基礎數據,才可能得到正確、有用的結論。本文主要介紹數據質量檢查的基本思路和方法,具體包括:從哪些角度檢查數據質量問題、發現數據質量問題后又如何處理兩方面,並提供基於Python的實現方法。
另外,數據質量檢查是數據治理中的一個重要課題,涉及內容廣,由於筆者經驗水平有限,本文不做涉及,只從分析挖掘中的數據質量檢查工作說起。
0. 示例數據集說明
數據集:/labcenter/python/dataset.xlsx
#讀取數據集
import pandas as pd
dataset = pd.read_excel("/labcenter/python/dataset.xlsx")
#打印數據集
dataset
Out[6]:
col1 col2 col3 col4 col5 col6 col7
0 101 38.0 96 aaa 572.0000 0.0017 1
1 102 20.0 13 bbb 174.3333 0.0115 0
2 103 44.0 160 ccc 191.3333 0.0000 1
3 104 NaN 128 aaa 236.0000 0.0000 0
4 105 22.0 10 bbb 0.0000 -0.3000 0
5 106 58.0 16 aaa 0.0000 0.0000 1
6 107 30.0 31 aaa 598.0000 0.0000 0
7 108 25.0 87 aaa 19.6667 0.0000 0
8 109 38.0 221 bbb NaN 0.0000 1
9 110 35.0 115 ccc 425.6667 0.0094 0
##1. 重復值檢查 ###1.1 什么是重復值 重復值的檢查首先要明確一點,即重復值的定義。對於一份二維表形式的數據集來說,什么是重復值?可以從**兩個層次**進行理解: ① 關鍵字段出現相同的記錄,比如主索引字段出現重復; ② 所有字段出現相同的記錄。 第一個層次是否是重復,必須從這份數據的業務含義進行確定,比如在一張表中,從業務上講,一個用戶應該只會有一條記錄,那么如果某個用戶出現了超過一條的記錄,那么這就是重復值。第二個層次,就一定是重復值了。 ###1.2 重復值產生的原因 重復值的產生主要有**兩種原因**,一是上游源數據造成的,二是數據准備腳本中的數據關聯造成的。從數據准備角度來看,首先要檢查數據准備的腳本,判斷使用的源表是否有重復記錄,同時檢查關聯語句的正確性和嚴謹性,比如關聯條件是否合理、是否有限定數據周期等等。 比如:檢查源表數據是否有重復的SQL:
SELECT MON_ID,COUNT(*),COUNT(DISTINCT USER_ID)
FROM TABLE_NAME
GROUP BY MON_ID;
如果是上游源數據出現重復,那么應該及時反映給上游進行修正;如果是腳本關聯造成的,修改腳本,重新生成數據即可。
但在很多時候,用來分析的這份數據集是一份單獨的數據集,並不是在數據倉庫中開發得到的數據,既沒有上游源數據,也不存在生成數據的腳本,比如公開數據集,那么如何處理其中的重復值?一般的處理方式就是直接刪除重復值。
#判斷重復數據
dataset.duplicated() #全部字段重復是重復數據
Out[3]:
0 False
1 False
2 False
3 False
4 False
5 False
6 False
7 False
8 False
9 False
dtype: bool
dataset.duplicated(['col2']) #col2字段重復是重復數據
Out[4]:
0 False
1 False
2 False
3 False
4 False
5 False
6 False
7 False
8 True
9 False
dtype: bool
#刪除重復數據
dataset.drop_duplicates() #全部字段重復是重復數據
Out[5]:
col1 col2 col3 col4 col5 col6 col7
0 101 38.0 96 aaa 572.0000 0.0017 1
1 102 20.0 13 bbb 174.3333 0.0115 0
2 103 44.0 160 ccc 191.3333 0.0000 1
3 104 NaN 128 aaa 236.0000 0.0000 0
4 105 22.0 10 bbb 0.0000 -0.3000 0
5 106 58.0 16 aaa 0.0000 0.0000 1
6 107 30.0 31 aaa 598.0000 0.0000 0
7 108 25.0 87 aaa 19.6667 0.0000 0
8 109 38.0 221 bbb NaN 0.0000 1
9 110 35.0 115 ccc 425.6667 0.0094 0
dataset.drop_duplicates(['col2']) #col2字段重復是重復數據
Out[7]:
col1 col2 col3 col4 col5 col6 col7
0 101 38.0 96 aaa 572.0000 0.0017 1
1 102 20.0 13 bbb 174.3333 0.0115 0
2 103 44.0 160 ccc 191.3333 0.0000 1
3 104 NaN 128 aaa 236.0000 0.0000 0
4 105 22.0 10 bbb 0.0000 -0.3000 0
5 106 58.0 16 aaa 0.0000 0.0000 1
6 107 30.0 31 aaa 598.0000 0.0000 0
7 108 25.0 87 aaa 19.6667 0.0000 0
9 110 35.0 115 ccc 425.6667 0.0094 0
##2. 缺失值檢查 **缺失值主要是指數據集中部分記錄存在部分字段的信息缺失。** ###2.1 缺失值出現的原因 出現缺失值主要有**三種原因**: ① 上游源系統因為技術或者成本原因無法完全獲取到這一信息,比如對用戶手機APP上網記錄的解析,一般來說,解析率相對較低; ② 從業務上講,這一信息本來就不存在,比如一個學生的收入,一個未婚者的配偶姓名; ③ 數據准備腳本開發中出現的錯誤造成的。 第一種原因,短期內無法解決;第二種原因,數據的缺失並不是錯誤,而是一種不能避免的客觀事實;第三種原因,則只需通過查證修改腳本即可。 缺失值的存在代表了某一部分信息的丟失,直接影響了挖掘分析結論的可靠性與穩定性,因此,必須對缺失值進行處理。 **一般來說:** **如果某字段的缺失值記錄數超過了全部記錄數的50%,則應該從數據集中直接剔除掉該字段,同時嘗試從業務上尋找替代字段;** **如果某字段的缺失值記錄數超過了全部記錄數的20%,但沒有超過50%,則應該首先看這個字段在業務上是否有替代字段,如果有,則直接剔除掉該字段,如果沒有,則必須對其進行處理;** **如果某字段的缺失值記錄數沒有超過全部記錄數的20%,不需要剔除該字段,但必須對其進行處理。**
#查看哪些字段有缺失值
dataset.isnull().any() #獲取含有NaN的字段
Out[13]:
col1 False
col2 True
col3 False
col4 False
col5 True
col6 False
col7 False
dtype: bool
#統計各字段的缺失值個數
dataset.isnull().apply(pd.value_counts)
Out[14]:
col1 col2 col3 col4 col5 col6 col7
False 10.0 9 10.0 10.0 9 10.0 10.0
True NaN 1 NaN NaN 1 NaN NaN
#刪除含有缺失值的字段
nan_col = dataset.isnull().any()
dataset.drop(nan_col[nan_col].index,axis=1)
Out[15]:
col1 col3 col4 col6 col7
0 101 96 aaa 0.0017 1
1 102 13 bbb 0.0115 0
2 103 160 ccc 0.0000 1
3 104 128 aaa 0.0000 0
4 105 10 bbb -0.3000 0
5 106 16 aaa 0.0000 1
6 107 31 aaa 0.0000 0
7 108 87 aaa 0.0000 0
8 109 221 bbb 0.0000 1
9 110 115 ccc 0.0094 0
2.2 缺失值的處理
缺失值的處理主要有兩種方式:過濾和填充。
(1)缺失值的過濾
直接刪除含有缺失值的記錄,總體上會影響樣本個數,如果要刪除的樣本過多或者數據集本來就很小時,這種方式並不建議采用。
#刪除含有缺失值的記錄
dataset.dropna()
Out[20]:
col1 col2 col3 col4 col5 col6 col7
0 101 38.0 96 aaa 572.0000 0.0017 1
1 102 20.0 13 bbb 174.3333 0.0115 0
2 103 44.0 160 ccc 191.3333 0.0000 1
4 105 22.0 10 bbb 0.0000 -0.3000 0
5 106 58.0 16 aaa 0.0000 0.0000 1
6 107 30.0 31 aaa 598.0000 0.0000 0
7 108 25.0 87 aaa 19.6667 0.0000 0
9 110 35.0 115 ccc 425.6667 0.0094 0
(2)缺失值的填充
缺失值的填充主要三種方法:
① 方法一:使用特定值填充
使用缺失值字段的平均值、中位數、眾數等統計量填充。
優點:簡單、快速
缺點:容易產生數據傾斜
② 方法二:使用算法預測填充
將缺失值字段作為因變量,將沒有缺失值字段作為自變量,使用決策樹、隨機森林、KNN、回歸等預測算法進行缺失值的預測,用預測結果進行填充。
優點:相對精確
缺點:效率低,如果缺失值字段與其他字段相關性不大,預測效果差
③ 方法三:將缺失值單獨作為一個分組,指定值進行填充
從業務上選擇一個單獨的值進行填充,使缺失值區別於其他值而作為一個分組,從而不影響后續的分析計算。
優點:簡單,實用
缺點:效率低,需要逐一進行填充
##使用Pandas進行特定值填充
#不同字段的缺失值都用0填充
dataset.fillna(0)
Out[16]:
col1 col2 col3 col4 col5 col6 col7
0 101 38.0 96 aaa 572.0000 0.0017 1
1 102 20.0 13 bbb 174.3333 0.0115 0
2 103 44.0 160 ccc 191.3333 0.0000 1
3 104 0.0 128 aaa 236.0000 0.0000 0
4 105 22.0 10 bbb 0.0000 -0.3000 0
5 106 58.0 16 aaa 0.0000 0.0000 1
6 107 30.0 31 aaa 598.0000 0.0000 0
7 108 25.0 87 aaa 19.6667 0.0000 0
8 109 38.0 221 bbb 0.0000 0.0000 1
9 110 35.0 115 ccc 425.6667 0.0094 0
#不同字段使用不同的填充值
dataset.fillna({'col2':20,'col5':0})
Out[17]:
col1 col2 col3 col4 col5 col6 col7
0 101 38.0 96 aaa 572.0000 0.0017 1
1 102 20.0 13 bbb 174.3333 0.0115 0
2 103 44.0 160 ccc 191.3333 0.0000 1
3 104 20.0 128 aaa 236.0000 0.0000 0
4 105 22.0 10 bbb 0.0000 -0.3000 0
5 106 58.0 16 aaa 0.0000 0.0000 1
6 107 30.0 31 aaa 598.0000 0.0000 0
7 108 25.0 87 aaa 19.6667 0.0000 0
8 109 38.0 221 bbb 0.0000 0.0000 1
9 110 35.0 115 ccc 425.6667 0.0094 0
#分別使用各字段的平均值填充
dataset.fillna(dataset.mean())
Out[18]:
col1 col2 col3 col4 col5 col6 col7
0 101 38.000000 96 aaa 572.000000 0.0017 1
1 102 20.000000 13 bbb 174.333300 0.0115 0
2 103 44.000000 160 ccc 191.333300 0.0000 1
3 104 34.444444 128 aaa 236.000000 0.0000 0
4 105 22.000000 10 bbb 0.000000 -0.3000 0
5 106 58.000000 16 aaa 0.000000 0.0000 1
6 107 30.000000 31 aaa 598.000000 0.0000 0
7 108 25.000000 87 aaa 19.666700 0.0000 0
8 109 38.000000 221 bbb 246.333333 0.0000 1
9 110 35.000000 115 ccc 425.666700 0.0094 0
#分別使用各字段的中位數填充
dataset.fillna(dataset.median())
Out[19]:
col1 col2 col3 col4 col5 col6 col7
0 101 38.0 96 aaa 572.0000 0.0017 1
1 102 20.0 13 bbb 174.3333 0.0115 0
2 103 44.0 160 ccc 191.3333 0.0000 1
3 104 35.0 128 aaa 236.0000 0.0000 0
4 105 22.0 10 bbb 0.0000 -0.3000 0
5 106 58.0 16 aaa 0.0000 0.0000 1
6 107 30.0 31 aaa 598.0000 0.0000 0
7 108 25.0 87 aaa 19.6667 0.0000 0
8 109 38.0 221 bbb 191.3333 0.0000 1
9 110 35.0 115 ccc 425.6667 0.0094 0
##使用sklearn中的預處理方法進行缺失值填充(只適用於連續型字段)
from sklearn.preprocessing import Imputer
#刪除非數值型字段
dataset2 = dataset.drop(['col4'],axis=1)
#打印新數據集
dataset2
Out[35]:
col1 col2 col3 col5 col6 col7
0 101 38.0 96 572.0000 0.0017 1
1 102 20.0 13 174.3333 0.0115 0
2 103 44.0 160 191.3333 0.0000 1
3 104 NaN 128 236.0000 0.0000 0
4 105 22.0 10 0.0000 -0.3000 0
5 106 58.0 16 0.0000 0.0000 1
6 107 30.0 31 598.0000 0.0000 0
7 108 25.0 87 19.6667 0.0000 0
8 109 38.0 221 NaN 0.0000 1
9 110 35.0 115 425.6667 0.0094 0
#創建填充規則(平均值填充)
nan_rule1 = Imputer(missing_values='NaN',strategy='mean',axis=0)
#應用規則
pd.DataFrame(nan_rule1.fit_transform(dataset2),columns=dataset2.columns)
Out[36]:
col1 col2 col3 col5 col6 col7
0 101.0 38.000000 96.0 572.000000 0.0017 1.0
1 102.0 20.000000 13.0 174.333300 0.0115 0.0
2 103.0 44.000000 160.0 191.333300 0.0000 1.0
3 104.0 34.444444 128.0 236.000000 0.0000 0.0
4 105.0 22.000000 10.0 0.000000 -0.3000 0.0
5 106.0 58.000000 16.0 0.000000 0.0000 1.0
6 107.0 30.000000 31.0 598.000000 0.0000 0.0
7 108.0 25.000000 87.0 19.666700 0.0000 0.0
8 109.0 38.000000 221.0 246.333333 0.0000 1.0
9 110.0 35.000000 115.0 425.666700 0.0094 0.0
#創建填充規則(中位數填充)
nan_rule2 = Imputer(missing_values='NaN',strategy='median',axis=0)
#應用規則
pd.DataFrame(nan_rule2.fit_transform(dataset2),columns=dataset2.columns)
Out[37]:
col1 col2 col3 col5 col6 col7
0 101.0 38.0 96.0 572.0000 0.0017 1.0
1 102.0 20.0 13.0 174.3333 0.0115 0.0
2 103.0 44.0 160.0 191.3333 0.0000 1.0
3 104.0 35.0 128.0 236.0000 0.0000 0.0
4 105.0 22.0 10.0 0.0000 -0.3000 0.0
5 106.0 58.0 16.0 0.0000 0.0000 1.0
6 107.0 30.0 31.0 598.0000 0.0000 0.0
7 108.0 25.0 87.0 19.6667 0.0000 0.0
8 109.0 38.0 221.0 191.3333 0.0000 1.0
9 110.0 35.0 115.0 425.6667 0.0094 0.0
#創建填充規則(眾數填充)
nan_rule3 = Imputer(missing_values='NaN',strategy='most_frequent',axis=0)
#應用規則
pd.DataFrame(nan_rule3.fit_transform(dataset2),columns=dataset2.columns)
Out[38]:
col1 col2 col3 col5 col6 col7
0 101.0 38.0 96.0 572.0000 0.0017 1.0
1 102.0 20.0 13.0 174.3333 0.0115 0.0
2 103.0 44.0 160.0 191.3333 0.0000 1.0
3 104.0 38.0 128.0 236.0000 0.0000 0.0
4 105.0 22.0 10.0 0.0000 -0.3000 0.0
5 106.0 58.0 16.0 0.0000 0.0000 1.0
6 107.0 30.0 31.0 598.0000 0.0000 0.0
7 108.0 25.0 87.0 19.6667 0.0000 0.0
8 109.0 38.0 221.0 0.0000 0.0000 1.0
9 110.0 35.0 115.0 425.6667 0.0094 0.0
##3. 數據傾斜檢查 **數據傾斜是指字段的取值分布主要集中在某個特定類別或者特定區間。** ###3.1 數據傾斜問題的原因 出現這一問題主要有**三種原因**: ① 上游源數據存在問題; ② 數據准備腳本的問題; ③ 數據本身的分布就是如此。 如果某個字段出現數據傾斜問題,必須首先排查上述第一、二種原因,如果都沒有問題或者無法檢查(如:單獨的數據集),那么就要考慮這個字段對后續的分析建模是否有價值。一般來說,有嚴重的數據傾斜的字段對目標變量的區分能力很弱,對分析建模的價值不大,應該直接剔除掉。 ###3.2 如何衡量數據的傾斜程度 衡量數據的傾斜程度,主要采用頻數分析方法,但因數據類別的不同而有所差異: ① 針對連續型字段,需要首先采用等寬分箱方式進行離散化,然后計算各分箱的記錄數分布; ② 針對離散型字段,直接計算各類別的記錄數分布。 一般來說,如果某個字段90%以上的記錄數,主要集中在某個特定類別或者特定區間,那么這個字段就存在嚴重的數據傾斜問題。
#對於連續型變量進行等寬分箱
pd.value_counts(pd.cut(dataset['col3'],5)) #分成5箱
Out[39]:
(9.789, 52.2] 4
(94.4, 136.6] 3
(178.8, 221] 1
(136.6, 178.8] 1
(52.2, 94.4] 1
Name: col3, dtype: int64
#對於離散型變量進行頻數統計
pd.value_counts(dataset['col4'])
Out[40]:
aaa 5
bbb 3
ccc 2
Name: col4, dtype: int64
##4. 異常值檢查 **異常值是指數據中出現了處於特定分布、范圍或者趨勢之外的數據,這些數據一般會被稱為異常值、離群點、噪聲數據等。** ###4.1 異常值產生的原因 異常值的產生主要有**兩種原因**: ① 數據采集、生成或者傳遞過程中發生的錯誤; ② 業務運營過程出現的一些特殊情況。 將第一種原因產生的異常值稱為**統計上的異常**,這是錯誤帶來的數據問題,需要解決;將第二種原因產生的異常值稱為**業務上的異常**,反映了業務運營過程的某種特殊結果,它不是錯誤,但需要深究,在數據挖掘中的一種典型應用就是異常檢測模型,比如信用卡欺詐,網絡入侵檢測、客戶異動行為識別等等。 ###4.2 異常值的識別方法 異常值的識別方法主要有以下幾種: ####(1)極值檢查 主要檢查字段的取值是否超出了合理的值域范圍。 **① 方法一:最大值最小值** 使用最大值、最小值進行判斷。比如客戶年齡的最大值為199歲,客戶賬單的最小費用為-20,這些都明顯存在異常。 **② 方法二:3σ原則** 如果數據服從正態分布,在3σ原則下,異常值被定義為與平均值的偏差超過了3倍標准差的值。這是因為,在正態分布的假設下,具體平均值3倍標准差之外的值出現的概率低於0.003,屬於極個別的小概率事件。 **③ 方法三:箱線圖分析** 箱線圖提供了識別異常的標准:異常值被定義為小於下四分位-1.5倍的四分位間距,或者大於上四分位+1.5倍的四分位間距的值。 箱線圖分析不要求數據服從任何分布,因此對異常值的識別比較客觀。
#獲取描述性統計量
statDF = dataset2.describe()
#打印統計量
statDF
Out[45]:
col1 col2 col3 col5 col6 col7
count 10.00000 9.000000 10.000000 9.000000 10.000000 10.000000
mean 105.50000 34.444444 87.700000 246.333333 -0.027740 0.400000
std 3.02765 11.959422 71.030588 235.303647 0.095759 0.516398
min 101.00000 20.000000 10.000000 0.000000 -0.300000 0.000000
25% 103.25000 25.000000 19.750000 19.666700 0.000000 0.000000
50% 105.50000 35.000000 91.500000 191.333300 0.000000 0.000000
75% 107.75000 38.000000 124.750000 425.666700 0.001275 1.000000
max 110.00000 58.000000 221.000000 598.000000 0.011500 1.000000
#計算平均值+3倍標准差
statDF.loc['mean+3std'] = statDF.loc['mean'] + 3 * statDF.loc['std']
#計算平均值-3倍標准差
statDF.loc['mean-3std'] = statDF.loc['mean'] - 3 * statDF.loc['std']
#計算上四分位+1.5倍的四分位間距
statDF.loc['75%+1.5dist'] = statDF.loc['75%'] + 1.5 * (statDF.loc['75%'] - statDF.loc['25%'])
#計算下四分位-1.5倍的四分位間距
statDF.loc['25%-1.5dist'] = statDF.loc['25%'] - 1.5 * (statDF.loc['75%'] - statDF.loc['25%'])
#再次打印統計量
statDF
Out[50]:
col1 col2 col3 col5 col6 col7
count 10.000000 9.000000 10.000000 9.000000 10.000000 10.000000
mean 105.500000 34.444444 87.700000 246.333333 -0.027740 0.400000
std 3.027650 11.959422 71.030588 235.303647 0.095759 0.516398
min 101.000000 20.000000 10.000000 0.000000 -0.300000 0.000000
25% 103.250000 25.000000 19.750000 19.666700 0.000000 0.000000
50% 105.500000 35.000000 91.500000 191.333300 0.000000 0.000000
75% 107.750000 38.000000 124.750000 425.666700 0.001275 1.000000
max 110.000000 58.000000 221.000000 598.000000 0.011500 1.000000
mean+3std 114.582951 70.322711 300.791764 952.244274 0.259538 1.949193
mean-3std 96.417049 -1.433822 -125.391764 -459.577607 -0.315018 -1.149193
75%+1.5dist 114.500000 57.500000 282.250000 1034.666700 0.003187 2.500000
25%-1.5dist 96.500000 5.500000 -137.750000 -589.333300 -0.001912 -1.500000
#獲取各字段最大值、最小值
statDF.loc[['max','min']]
Out[51]:
col1 col2 col3 col5 col6 col7
max 110.0 58.0 221.0 598.0 0.0115 1.0
min 101.0 20.0 10.0 0.0 -0.3000 0.0
#判斷取值是否大於平均值+3倍標准差
dataset3 = dataset2 - statDF.loc['mean+3std']
dataset3[dataset3>0]
Out[52]:
col1 col2 col3 col5 col6 col7
0 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN NaN NaN
#判斷取值是否小於平均值-3倍標准差
dataset4 = dataset2 - statDF.loc['mean-3std']
dataset4[dataset4<0]
Out[53]:
col1 col2 col3 col5 col6 col7
0 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN NaN NaN
#判斷取值是否大於上四分位+1.5倍的四分位間距
dataset5 = dataset2 - statDF.loc['75%+1.5dist']
dataset5[dataset5>0]
Out[54]:
col1 col2 col3 col5 col6 col7
0 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN 0.008313 NaN
2 NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN
5 NaN 0.5 NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN 0.006213 NaN
#判斷取值是否大於上四分位-1.5倍的四分位間距
dataset6 = dataset2 - statDF.loc['25%-1.5dist']
dataset6[dataset6<0]
Out[55]:
col1 col2 col3 col5 col6 col7
0 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN -0.298088 NaN
5 NaN NaN NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN NaN NaN
(2)記錄數分布檢查
主要檢查字段的記錄數分布是否超出合理的分布范圍,包括三個指標:零值記錄數、正值記錄數、負值記錄數。
(3)波動檢查
波動檢查主要適用於有監督的數據,用於檢查隨着自變量的變化,因變量是否發生明顯的波動情況。
以上異常值的識別方法主要針對連續型字段,而對於離散型字段的異常識別主要通過檢查類別出現是否出現了合理閾值外的數據,比如蘋果終端型號字段,出現了“P20”的取值。
4.3 異常值的處理
對於統計上的異常值的處理,主要采取兩種方式:剔除或者替換。剔除是指直接將被標記為異常值的記錄從數據集中刪除掉,而替換是指將異常值用一個非異常值進行替換,比如邊界值,或者有監督情況下的目標變量表征相似的某個值。
對於業務上的異常值的處理,原則就是進行深入探索分析,查找出現這一特殊情況的根本原因。
##5.參考與感謝 \[1] [Python數據分析與數據化運營](https://book.douban.com/subject/27608466/) \[2] [Python數據分析與數據挖掘實戰](https://book.douban.com/subject/26677686/)