Python:异常值检测箱型图(附:正态分布3σ)
????????異常值檢測(cè)的方法有很多,通過(guò)數(shù)據(jù)分布圖型尋找異常值、算法模型(聚類、隨機(jī)森林等),我這里就是記錄一下工作中做初步的數(shù)據(jù)探查時(shí)用到的箱型圖檢測(cè)和正態(tài)分布檢測(cè),這兩種都是根據(jù)數(shù)據(jù)分布情況來(lái)識(shí)別異常值的,沒(méi)有結(jié)合到業(yè)務(wù)的層面,在做初步的探查時(shí)還是高效且適用的。因?yàn)檎龖B(tài)分布3σ的異常值檢測(cè)需要數(shù)據(jù)符合正態(tài)分布,現(xiàn)實(shí)情況中大部分?jǐn)?shù)據(jù)都是雜亂無(wú)章的,因此重點(diǎn)使用的是箱型圖檢測(cè)。
1.箱型圖的優(yōu)勢(shì)
(1)準(zhǔn)確穩(wěn)定地描繪出數(shù)據(jù)的離散分布情況且不需要服從特定的分布形式
箱形圖的繪制依靠實(shí)際數(shù)據(jù),不需要事先假定數(shù)據(jù)服從特定的分布形式,沒(méi)有對(duì)數(shù)據(jù)作任何限制性要求,它只是真實(shí)直觀地表現(xiàn)數(shù)據(jù)形狀的本來(lái)面貌;
(2)異常值不會(huì)影響四分位數(shù)的確定
箱形圖判斷異常值的標(biāo)準(zhǔn)以四分位數(shù)和四分位距為基礎(chǔ),四分位數(shù)具有一定的耐抗性,多達(dá)25%的數(shù)據(jù)可以變得任意遠(yuǎn)而不會(huì)很大地?cái)_動(dòng)四分位數(shù),所以異常值不能對(duì)這個(gè)標(biāo)準(zhǔn)施加影響,箱形圖識(shí)別異常值的結(jié)果比較客觀。
2.箱型圖的示意及符號(hào)說(shuō)明
(圖片來(lái)源于網(wǎng)絡(luò))
Qi所在位置=i(n+1)/4,其中i=1,2,3。n表示序列中包含的項(xiàng)數(shù)。根據(jù)所在位置找到此位置上的數(shù)據(jù)。
下四分位數(shù)Q1:該樣本中所有數(shù)值由小到大排列后第25%的數(shù)字。
中位數(shù)Q2:該樣本中所有數(shù)值由小到大排列后第50%的數(shù)字
上四分位數(shù)Q3:該樣本中所有數(shù)值由小到大排列后第75%的數(shù)字
四分位距IQR:IQR=Q3-Q1
上限:非異常范圍內(nèi)的最大值,上限=Q3+1.5IQR
下限:非異常范圍內(nèi)的最小值,下限=Q1-1.5IQR
3.Python代碼
def OutlierDetection_box(df,con,path):#con代表數(shù)據(jù)列的名稱,path代表文本保存的路徑# 計(jì)算下四分位數(shù)和上四分位Q1 = df.quantile(q=0.25)Q3 = df.quantile(q=0.75)Q2 = df.quantile(q=0.5)# 基于1.5倍的四分位差計(jì)算上下須對(duì)應(yīng)的值low_whisker = Q1 - 1.5 * (Q3 - Q1)up_whisker = Q3 + 1.5 * (Q3 - Q1)# 尋找異常點(diǎn)outliers = df[(df > up_whisker) | (df < low_whisker)]#data1 = pd.DataFrame({'id': kk.index, '異常值': kk})#統(tǒng)計(jì),stat_ll為箱型圖中數(shù)據(jù)分布情況(多個(gè)數(shù)據(jù)列合并最后會(huì)輸出一個(gè)sheet頁(yè)),f最后會(huì)輸出一個(gè)標(biāo)識(shí)具體數(shù)據(jù)點(diǎn)的文本dataQ3=df[(df>Q2) & (df<=Q3)]countQ3=len(dataQ3)dataQ1 = df[(df < Q2) & (df >= Q1)]countQ1 = len(dataQ1)data_max = df[(df <= up_whisker) & (df > Q3)]count_max = len(data_max)data_min = df[(df >= low_whisker) & (df < Q1)]count_min = len(data_min)stat_ll=[con,countQ3,countQ1,count_max,count_min]with open(path+"/box_new.txt", "a",encoding='utf-8') as f:f.write("\n%s的箱型圖分布統(tǒng)計(jì)如下:"%con)f.write("\n箱線圖檢測(cè)到的異常值如下:")f.write(str(outliers.to_dict()))f.write("\n落入中位數(shù)到上四分位距有%d條,具體如下:"%countQ3)f.write(str(dataQ3.to_dict()))f.write("\n落入中位數(shù)到下四分位距有%d條,具體如下:" % countQ1)f.write(str(dataQ1.to_dict()))f.write("\n落入上四分位數(shù)到最大值有%d條,具體如下:" % count_max)f.write(str(data_max.to_dict()))f.write("\n落入下四分位數(shù)到最小值有%d條,具體如下:" % count_min)f.write(str(data_min.to_dict()))return outliers,stat_ll?2.正態(tài)分布
def OutlierDetection_std(df,con,path):# 計(jì)算均值u = df.mean()# 計(jì)算標(biāo)準(zhǔn)差std = df.std()# 計(jì)算P值res = kstest(df, 'norm', (u, std))[1]if res <= 0.05:#判斷是不是符合正態(tài)分布# 定義3σ法則識(shí)別異常值# 識(shí)別異常值error_low = df[np.abs(df - u) > 2 * std]error_high = df[np.abs(df - u) > 3 * std]# 剔除異常值,保留正常的數(shù)據(jù)#data_normal = df[np.abs(df - u) <= 3 * std]with open(path+"/std_outliers.txt", "a", encoding='utf-8') as f:f.write("\n%s符合正態(tài)分布:"%con)f.write("\n2sigma異常值如下:")f.write(str(error_low.to_dict()))f.write("\n3sigma異常值如下:")f.write(str(error_high.to_dict()))return u, std, error_low, error_highelse:logger.info('該數(shù)據(jù)不服從正態(tài)分布-----------')return None3.正態(tài)分布結(jié)合四分位距(網(wǎng)上一篇文章看到的,實(shí)際沒(méi)有使用)
def box_3Sigma(df,sigma):Q1 = df.quantile(q=0.25)Q3 = df.quantile(q=0.75)IQR = Q3 - Q1min = Q1 - 1.5 * IQRmax = Q3 + 1.5 * IQRratio = 0.3low = 3*sigma * ratio + min * (1 - ratio)hight = 3*sigma * ratio + max * (1 - ratio)總結(jié)
以上是生活随笔為你收集整理的Python:异常值检测箱型图(附:正态分布3σ)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python,OpenCV中的光学字符识
- 下一篇: TrOCR:基于Transformer的