數據准備<1>:數據質量檢查-理論篇


數據行業有一句很經典的話——“垃圾進,垃圾出”(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/)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM