正態曲線呈鍾型,兩頭低,中間高,左右對稱因其曲線呈鐘形,因此人們又經常稱之爲鐘形曲線。
使用K-S檢驗一個數列是否服從正態分佈、兩個數列是否服從相同的分佈。
下面介紹 Python 中常用的幾種正態性檢驗方法:
scipy.stats.kstest
異常值是指樣本中的個別值,其數值明顯偏離其餘的觀測值。異常值也稱離羣點,異常值的分析也稱爲離羣點的分析。
在進行機器學習過程中,需要對數據集進行異常值剔除或者修正,以便後續更好地進行信息挖掘。
對於異常值的處理,3σ原則是最常使用的一種處理數據異常值的方法。那麼,什麼叫3σ原則呢?
3σ原則,又叫拉依達原則,它是指假設一組檢測數據中只含有隨機誤差,需要對其進行計算得到標準偏差,按一定概率確定一個區間,對於超過這個區間的誤差,就不屬於隨機誤差而是粗大誤差,需要將含有該誤差的數據進行剔除。
其侷限性:僅侷限於對正態或近似正態分佈的樣本數據處理,它是以測量次數充分大爲前提(樣本>10),當測量次數少的情形用準則剔除粗大誤差是不夠可靠的。在測量次數較少的情況下,最好不要選用該準則。
3σ原則:
數值分佈在(μ-σ,μ+σ)中的概率爲0.6827
數值分佈在(μ-2σ,μ+2σ)中的概率爲0.9545
數值分佈在(μ-3σ,μ+3σ)中的概率爲0.9973
其中,μ爲平均值,σ爲標準差。
一般可以認爲,數據Y的取值幾乎全部集中在(μ-3σ,μ+3σ)區間內,超出這個範圍的可能性僅佔不到0.3%,這些超出該範圍的數據可以認爲是異常值。
具體步驟如下:
- 首先需要保證數據列大致上服從正態分佈;
- 計算需要檢驗的數據列的平均值和標準差;
- 比較數據列的每個值與平均值的偏差是否超過3倍,如果超過3倍,則爲異常值;
- 剔除異常值,得到規範的數據。
方法一、KS檢驗3σ異常點檢測:
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from scipy.stats import kstest
def KsNormDetect(df):
# 計算均值
u = df['value'].mean()
# 計算標準差
std = df['value'].std()
# 計算P值
res=kstest(df, 'norm', (u, std))[1]
# 判斷p值是否服從正態分佈,p<=0.05 則服從正態分佈,否則不服從。
if res<=0.05:
print('該列數據服從正態分佈------------')
print('均值爲:%.3f,標準差爲:%.3f' % (u, std))
print('------------------------------')
return 1
else:
return 0
def OutlierDetection(df,ks_res):
# 計算均值
u = df['value'].mean()
# 計算標準差
std = df['value'].std()
if ks_res==1:
# 定義3σ法則識別異常值
# 識別異常值
error = df[np.abs(df['value'] - u) > 3 * std]
# 剔除異常值,保留正常的數據
data_c = df[np.abs(df['value'] - u) <= 3 * std]
# 輸出異常數據
# print(error)
return error
else:
print('請先檢測數據是否服從正態分佈-----------')
return None
if __name__ == '__main__':
# 創建數據
data = [1222, 87, 77, 92, 68, 80, 78, 84, 77, 81, 80, 80, 77, 92, 86, 76, 80, 81, 75, 77, 72, 81, 72, 84, 86, 80,
68, 77, 87, 76, 77, 78, 92, 75, 80, 78, 123, 3, 1223, 1232]
df = pd.DataFrame(data, columns=['value'])
ks_res=KsNormDetect(df)
result=OutlierDetection(df, ks_res)
print(result)
該列數據服從正態分佈------------
均值爲:164.850,標準差爲:306.289
------------------------------
value
0 1222
38 1223
39 1232
方法二、箱線圖發現異常值:
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
def OutlierDetection(df):
# 計算下四分位數和上四分位
Q1 = df.quantile(q=0.25)
Q3 = df.quantile(q=0.75)
# 基於1.5倍的四分位差計算上下須對應的值
low_whisker = Q1 - 1.5 * (Q3 - Q1)
up_whisker = Q3 + 1.5 * (Q3 - Q1)
# 尋找異常點
kk = df[(df > up_whisker) | (df < low_whisker)]
data1 = pd.DataFrame({'id': kk.index, '異常值': kk})
return data1
if __name__ == '__main__':
# 創建數據
data = [1222, 87, 77, 92, 68, 80, 78, 84, 77, 81, 80, 80, 77, 92, 86, 76, 80, 81, 75, 77, 72, 81, 72, 84, 86, 80,
68, 77, 87, 76, 77, 78, 92, 75, 80, 78, 123, 3, 1223, 1232]
df = pd.DataFrame(data, columns=['value'])
df=df.iloc[:,0]
result=OutlierDetection(df)
print('箱線圖檢測到的異常值如下---------------------')
print(result)
箱線圖檢測到的異常值如下---------------------
id 異常值
0 0 1222
36 36 123
37 37 3
38 38 1223
39 39 1232