使用Python實現(xiàn)檢測并刪除離群值
離群值是一個數(shù)據(jù)項/對象,它明顯偏離其余的(所謂的正常)對象。它們可能由測量或執(zhí)行錯誤引起。離群點檢測的分析被稱為離群點挖掘。檢測離群值的方法有很多,刪除過程與從pandas的數(shù)據(jù)框中刪除數(shù)據(jù)項相同。
離群值檢測和刪除
在這里,pandas數(shù)據(jù)框架用于更現(xiàn)實的方法,因為現(xiàn)實世界的項目需要檢測數(shù)據(jù)分析步驟中出現(xiàn)的離群值,相同的方法可以用于列表和序列類型的對象。
# Importing import sklearn from sklearn.datasets import load_diabetes import pandas as pd import matplotlib.pyplot as plt # Load the dataset diabetics = load_diabetes() # Create the dataframe column_name = diabetics.feature_names df_diabetics = pd.DataFrame(diabetics.data) df_diabetics.columns = column_name df_diabetics.head()
離群值可以使用可視化、在數(shù)據(jù)集上實現(xiàn)數(shù)學(xué)公式或使用統(tǒng)計方法來檢測。下文將討論所有這些問題。
離群值可視化
使用箱形圖可視化離群值
它只需要一個簡單的框和須就可以有效地捕獲數(shù)據(jù)摘要。箱形圖使用第25次、第50次和第75次采樣總結(jié)了樣本數(shù)據(jù)。人們可以通過查看數(shù)據(jù)集的箱形圖來了解數(shù)據(jù)集(四分位數(shù),中位數(shù)和離群值)。
# Box Plot import seaborn as sns sns.boxplot(df_diabetics['bmi'])
在上圖中,可以清楚地看到,高于10的值是離群值。
# Position of the Outlier import numpy as np print(np.where(df_diabetics['bmi']>0.12))
輸出
(array([ 32, 145, 256, 262, 366, 367, 405]),)
使用散點圖可視化離群值
當(dāng)您有成對的數(shù)值數(shù)據(jù),并且因變量對每個閱讀自變量有多個值時,或者當(dāng)嘗試確定兩個變量之間的關(guān)系時,使用該方法。在利用散點圖的過程中,也可以將其用于離群值檢測。
要繪制散點圖,需要兩個變量以某種方式彼此相關(guān)。因此,這里使用的是“每個城鎮(zhèn)的非零售業(yè)務(wù)面積比例”和“每10,000美元的全額財產(chǎn)稅稅率”,其列名分別為“INDUS”和“TAX”。
# Scatter plot fig, ax = plt.subplots(figsize=(6, 4)) ax.scatter(df_diabetics['bmi'], df_diabetics['bp']) # x-axis label ax.set_xlabel('(body mass index of people)') # y-axis label ax.set_ylabel('(bp of the people )') plt.show()
查看圖表可以總結(jié)出大多數(shù)數(shù)據(jù)點都在圖表的左下角,但很少有點正好相反,即圖表的右上角。右上角的那些點可以被視為離群值。
使用近似可以說所有那些x>20和y>600的數(shù)據(jù)點都是離群值。下面的代碼可以獲取滿足這些條件的所有點的精確位置。
BMI和BP列合并的離群值
在這里,NumPy的np.where()函數(shù)用于在DataFrame df_diabetics中查找條件(df_diabetics[‘bmi’] > 0.12) & (df_diabetics[‘bp’] < 0.8) 為真的位置(索引)。該條件檢查bmi大于0.12且bp小于0.8的離群值。輸出提供DataFrame中離群值位置的行和列索引。
# Position of the Outlier print(np.where((df_diabetics['bmi'] > 0.12) & (df_diabetics['bp'] < 0.8)))
輸出
(array([ 32, 145, 256, 262, 366, 367, 405]),)
Z-score
Z-score也稱為標(biāo)準(zhǔn)分?jǐn)?shù)。該值/分?jǐn)?shù)有助于理解數(shù)據(jù)點距離平均值有多遠(yuǎn)。并且在設(shè)置閾值之后,可以利用數(shù)據(jù)點的z得分值來定義離群值。
Zscore = (data_point -mean) / std. deviation
在本例中,我們使用SciPy stats模塊中的zscore函數(shù)計算DataFrame df_diabetics中“age”列的Z分?jǐn)?shù)。生成的數(shù)組z包含“age”列中每個數(shù)據(jù)點的絕對Z分?jǐn)?shù),指示每個值與平均值的標(biāo)準(zhǔn)差。
# Z score from scipy import stats import numpy as np z = np.abs(stats.zscore(df_diabetics['age'])) print(z)
輸出
[0.80050009 0.03956713 1.79330681 1.87244107 0.11317236 1.94881082
0.9560041 1.33508832 0.87686984 1.49059233 2.02518057 0.57139085
0.34228161 0.11317236 0.95323959 1.1087436 0.11593688 1.48782782
0.80326461 0.57415536 1.03237385 1.79607132 1.79607132 0.95323959
1.33785284 1.41422259 2.25428981 0.49778562 1.10597908 1.41145807
1.26148309 0.49778562 0.72413034 0.6477606 0.34228161 1.02960933
0.26591186 0.19230663 0.03956713 0.03956713 0.11317236 2.10155031
1.26148309 0.41865135 0.95323959 0.57139085 1.18511334 1.64333183
1.41145807 0.87963435 0.72413034 1.25871858 1.1087436 0.19230663
1.03237385 0.87963435 0.87963435 0.57415536 0.87686984 1.33508832
1.49059233 0.87963435 0.57415536 0.72689486 1.41145807 0.9560041
0.19230663 0.87686984 0.80050009 0.34228161 0.03956713 0.03956713
1.33508832 0.26591186 0.26591186 0.19230663 0.65052511 2.02518057
0.11317236 2.17792006 1.48782782 0.26591186 0.34504612 0.80326461
0.03680262 0.95323959 1.49059233 0.95323959 1.1087436 0.9560041
0.26591186 0.95323959 0.42141587 1.03237385 1.64333183 1.49059233
1.18234883 0.57415536 0.03680262 0.03956713 0.34228161 0.34228161]
上面的輸出只是部分?jǐn)?shù)據(jù)的快照;列表的實際長度(z)是506,即行數(shù)。它打印列的每個數(shù)據(jù)項的z得分值
現(xiàn)在,為了定義離群值,選擇通常為3.0的閾值。由于99.7%的數(shù)據(jù)點位于+/- 3標(biāo)準(zhǔn)差之間(使用高斯分布方法)。
Z值大于2的情況下
在這個例子中,我們設(shè)置了一個閾值2,然后使用NumPy的np.where()來標(biāo)識Z分?jǐn)?shù)數(shù)組z中絕對Z分?jǐn)?shù)大于指定閾值(2)的位置(索引)。它根據(jù)Z分?jǐn)?shù)標(biāo)準(zhǔn)在“年齡”列中打印離群值的位置。
threshold = 2 # Position of the outlier print(np.where(z > 2))
輸出
(array([ 10, 26, 41, 77, 79, 106, 131, 204, 223, 226, 242, 311, 321,344, 374, 402]),)
IQR(四分位數(shù)間距)
四分位數(shù)間距(IQR)是研究領(lǐng)域中最常用和最可信的離群值發(fā)現(xiàn)方法。
IQR = Quartile3 - Quartile1
語法: numpy.percentile(arr, n, axis=None, out=None)
主要參數(shù):
arr:輸入數(shù)組。 n:百分位數(shù)值。
在本例中,我們計算DataFrame df_diabetics中“bmi”列的四分位距(IQR)。它首先使用中點法計算第一四分位數(shù)(Q1)和第三四分位數(shù)(Q3),然后計算IQR作為Q3和Q1之間的差值,提供“bmi”列中中間50%數(shù)據(jù)的分布度量。
# IQR Q1 = np.percentile(df_diabetics['bmi'], 25, method='midpoint') Q3 = np.percentile(df_diabetics['bmi'], 75, method='midpoint') IQR = Q3 - Q1 print(IQR)
輸出
0.06520763046978838
為了定義離群值基礎(chǔ)值定義為高于和低于數(shù)據(jù)集的正常范圍,即上限和下限,定義上限和下限(考慮1.5*IQR值):
upper = Q3 +1.5*IQR
lower = Q1 – 1.5*IQR
在上述公式中,根據(jù)統(tǒng)計學(xué),采用IQR的0.5比例放大(new_IQR = IQR + 0.5*IQR),以考慮高斯分布中2.7標(biāo)準(zhǔn)差之間的所有數(shù)據(jù)。
# Above Upper bound upper = Q3+1.5*IQR upper_array = np.array(df_diabetics['bmi'] >= upper) print("Upper Bound:", upper) print(upper_array.sum()) # Below Lower bound lower = Q1-1.5*IQR lower_array = np.array(df_diabetics['bmi'] <= lower) print("Lower Bound:", lower) print(lower_array.sum())
輸出
Upper Bound: 0.12879000811776306
3
Lower Bound: -0.13204051376139045
0
去除離群值
為了移除離群值,必須遵循使用其在數(shù)據(jù)集中的確切位置從數(shù)據(jù)集中移除條目的相同過程,因為在檢測離群值的所有上述方法中,最終結(jié)果是根據(jù)所使用的方法滿足離群值定義的所有那些數(shù)據(jù)項的列表。
dataframe.drop(row index,inplace=True)
上面的語法可以用來從數(shù)據(jù)集中刪除一行,給定要刪除的row_indexes。Inplace =True用于告訴Python在原始數(shù)據(jù)集中進行所需的更改。row_index只能是一個值或值列表或NumPy數(shù)組,但必須是一維的。
例:
df_diabetics.drop(lists[0],inplace = True)
基于IQR的離群點檢測與刪除
在這個例子中,我們使用四分位距(IQR)方法來檢測和刪除糖尿病數(shù)據(jù)集的“bmi”列中的離群值。它基于IQR計算上限和下限,使用布爾數(shù)組識別離群值索引,然后從DataFrame中刪除相應(yīng)的行,從而生成排除離群值的新DataFrame。打印DataFrame的前后形狀以進行比較。
# Importing import sklearn from sklearn.datasets import load_diabetes import pandas as pd # Load the dataset diabetes = load_diabetes() # Create the dataframe column_name = diabetes.feature_names df_diabetes = pd.DataFrame(diabetes.data) df_diabetes .columns = column_name df_diabetes .head() print("Old Shape: ", df_diabetes.shape) ''' Detection ''' # IQR # Calculate the upper and lower limits Q1 = df_diabetes['bmi'].quantile(0.25) Q3 = df_diabetes['bmi'].quantile(0.75) IQR = Q3 - Q1 lower = Q1 - 1.5*IQR upper = Q3 + 1.5*IQR # Create arrays of Boolean values indicating the outlier rows upper_array = np.where(df_diabetes['bmi'] >= upper)[0] lower_array = np.where(df_diabetes['bmi'] <= lower)[0] # Removing the outliers df_diabetes.drop(index=upper_array, inplace=True) df_diabetes.drop(index=lower_array, inplace=True) # Print the new shape of the DataFrame print("New Shape: ", df_diabetes.shape)
輸出
Old Shape: (442, 10)
New Shape: (439, 10)
到此這篇關(guān)于使用Python實現(xiàn)檢測并刪除離群值的文章就介紹到這了,更多相關(guān)Python離群值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python GUI庫圖形界面開發(fā)之PyQt5下拉列表框控件QComboBox詳細(xì)使用方法與實例
這篇文章主要介紹了python GUI庫圖形界面開發(fā)之PyQt5下拉列表框控件QComboBox詳細(xì)使用方法與實例,需要的朋友可以參考下2020-02-02Python與xlwings黃金組合處理Excel各種數(shù)據(jù)和自動化任務(wù)
這篇文章主要為大家介紹了Python與xlwings黃金組合處理Excel各種數(shù)據(jù)和自動化任務(wù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪<BR>2023-12-12淺談python opencv對圖像顏色通道進行加減操作溢出
這篇文章主要介紹了淺談python opencv對圖像顏色通道進行加減操作溢出,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06關(guān)于python pycharm中輸出的內(nèi)容不全的解決辦法
這篇文章主要介紹了關(guān)于python pycharm中輸出的內(nèi)容不全的解決辦法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01