学习
实践
活动
专区
工具
TVP
写文章
专栏首页ShowMeAI研究中心异常值检测!最佳统计方法实践(代码实现)!⛵
原创

异常值检测!最佳统计方法实践(代码实现)!⛵

数据集中的异常值,对于数据分布、建模等都有影响。本文讲解两大类异常值的检测方法及其Python实现:可视化方法(箱线图&直方图)、统计方法(z分数&四分位距)。


💡 作者:韩信子@ShowMeAI 📘 Python3◉技能提升系列:https://www.showmeai.tech/tutorials/56 📘 数据分析实战系列:https://www.showmeai.tech/tutorials/40 📘 本文地址:https://www.showmeai.tech/article-detail/336 📢 声明:版权所有,转载请联系平台与作者并注明出处 📢 收藏ShowMeAI查看更多精彩内容

💡 异常值 Q&A

异常值是距离其他数据值太远的数据点,也被称为离群点。它可能是自然发生的,也可能是由于测量不准确、拼写错误或系统故障造成的。异常值也可能出现在倾斜数据中,这些类型的异常值被认为是自然异常值。

了解异常值检测与分析的基础知识,请查看 ShowMeAI](https://www.showmeai.tech/) 这篇文章:

图解数据分析 | 数据清洗与预处理

💦 异常值对分布有什么影响?

异常值会影响数据的均值、标准差和四分位数值。如果我们在去除异常值之前和之后计算这些统计数据,可能会有比较大的差异。

💦 异常值对机器学习模型有什么影响?

  • 如果认为异常值是自然的,不是由于测量错误产生的 → 应该将其保留在数据集中,并用『标准化』等数据预处理方式处理。
  • 如果有一个包含少量异常值的大型数据集 → 应该将其保留,不会显著影响结果。
  • 如果确定异常值是由测量误差造成的 → 应该将它们从数据集中删除。

去除异常值会带来数据集规模的减小,而且模型的适用性也会限制在输入值的度量范围内,丢弃自然异常值也可能导致模型不准确。

💡 基于可视化的异常值检测

异常值不容易被『肉眼』检测到,但我们有一些可视化工具可以帮助完成这项任务。最常见的是箱线图和直方图。我们这里用 🏆保险数据来做一个讲解:

🏆 实战数据集下载(百度网盘):公✦众✦号『ShowMeAI研究中心』回复『实战』,或者点击 这获取本文 [29]基于统计方法的异常值检测代码实战 『insurance数据集』

ShowMeAI官方GitHubhttps://github.com/ShowMeAI-Hub

我们首先导入必要的库并加载数据集。

import numpy as np
import pandas as pd
import seaborn as sns
import statistics#Load dataset:
df = pd.read_csv('insurance.csv')
df

我们对变量『年龄』、『体重指数』和『费用』进行异常值检测分析。

第一种方法是使用箱线图 / Box-Plots 来绘制数据分布:

# age, bmi 和 expenses的箱线图绘图
sns.boxplot(y="age", data=df)
sns.boxplot(y="bmi", data=df)
sns.boxplot(y="expenses", data=df)

通过查看箱线图,我们可以看到变量 age 没有异常值,变量 bmi 在上限中有一些异常值,而变量 expense 在上限中有一系列异常值(表明存在偏态分布)。

为了检查偏态分布,我们再使用直方图绘图:

# age, bmi 和 expenses的直方图
sns.histplot(df, x="age", kde=True)
sns.histplot(df, x="bmi", kde=True)
sns.histplot(df, x="expenses", kde=True)

通过直方图,我们可以看到变量『age』是近似均匀分布,『bmi』接近正态分布,而『expense/费用』则呈偏态分布。

对于年龄,我们无需做异常值剔除;对于 bmi,我们将剔除高于 47 的值;对于费用,我们将剔除高于 50000 的值。

#bmi 和 expenses 的异常值处理
df.drop(df[df['bmi'] >= 47].index, inplace = True)
df.drop(df[df['expenses'] >= 50000].index, inplace = True)

现在,如果我们再次检查箱线图和直方图:

💡 基于统计方法的异常值检测

检测异常值有两种主要的统计方法:使用 z 分数和使用四分位距。

💦 使用 z 分数检测异常值

Z 分数是一种数学变换,它根据每个观测值与平均值的距离对其进行分类。z-score 的计算公示为:

我们定义异常检测标准:如果 z-score 小于 -3或 z-score 大于 3。

我们将重新加载数据集,因为我们在前面的示例中对其进行了更改,加载后的数据上我们会把变量转换为 z 分数:

# 重新加载数据
df = pd.read_csv('insurance.csv')

# 为age计算均值和标准差
mean_age = statistics.mean(df['age'])
stdev_age = statistics.stdev(df['age'])

# 计算z值
age_z_score = (df['age']-mean_age)/stdev_age

# 添加z结果到原dataframe
df['age_z_score'] = age_z_score.tolist()

现在我们将检查高于 3SD 或低于 -3SD 的值:

# 检测小于-3SD的值:
df.sort_values(by=['age_z_score'], ascending=True)

我们可以看到 -3SD 以下没有值。我们现在将检查 3SD 以上的值:

# 检测+3SD以上的值:
df.sort_values(by=['age_z_score'], ascending=False)

我们可以看到没有高于 3SD 的值。变量年龄没有异常值。

现在我们将对变量 bmi 执行相同的操作:

# 为bmi计算均值和标准差
mean_bmi = statistics.mean(df['bmi'])
stdev_bmi = statistics.stdev(df['bmi'])

# 为bmi计算z-score
bmi_z_score = (df['bmi']-mean_bmi)/stdev_bmi

# 添加到原始dataframe
df['bmi_z_score'] = bmi_z_score.tolist()

# 检查低于-3SD的值
df.sort_values(by=['bmi_z_score'], ascending=True)

# 检查大于3SD的值
df.sort_values(by=['bmi_z_score'], ascending=False)

这次我们会发现一些高于 3SD 的值:

我们对它进行剔除:

# 异常值处理
df.drop(df[df[‘bmi_z_score’] >= 3].index, inplace = True)

我们将对『expense/费用』应用相同的技术:

# 为expenses计算均值和标准差
mean_expenses = statistics.mean(df['expenses'])
stdev_expenses = statistics.stdev(df['expenses'])

# 计算z-score
expenses_z_score = (df['expenses']-mean_expenses)/stdev_expenses

# 添加到原始dataframe
df['expenses_z_score'] = expenses_z_score.tolist()

# 检查低于-3SD的值
df.sort_values(by=['expenses_z_score'], ascending=True)

# 检查高于3SD的值
df.sort_values(by=['expenses_z_score'], ascending=False)

# 异常值处理
df.drop(df[df[‘expenses_z_score’] >= 3].index, inplace = True)

如果我们再次检查箱线图和直方图,我们将获得:

💦 使用四分位距检测异常值

四分位间距将数据分为四个部分,从低到高排序,如下图所示,每个部分包含相同数量的样本。第一个四分位数(Q1)是边界中数据点的值。这同样适用于 Q2 和 Q3。 四分位距(IQR)是两个中间部分的数据点(代表 50% 的数据)。四分位距包含高于 Q1 和低于 Q3 的所有数据点。如果该点高于 Q3 + (1.5 x IQR),则存在较高的异常值,如果 Q1 - (1.5 x IQR),则存在较低的异常值。

代码实现如下:

# 重新加载数据
df = pd.read_csv('insurance.csv')

# 计算上下四分位数位置
q75_age, q25_age = np.percentile(df['age'], [75 ,25])
iqr_age = q75_age - q25_age
iqr_age

# 计算上下边界以用于异常检测
age_h_bound = q75_age+(1.5*iqr_age)
age_l_bound = q25_age-(1.5*iqr_age)
print(age_h_bound)
print(age_l_bound)

我们计算得到上边界 87 和下边界 -9:

# 排序
df.sort_values(by=['age'], ascending=True)
# 排序
df.sort_values(by=['age'], ascending=False)

我们看到没有异常值。

我们对变量 bmi 执行相同的操作:

# 计算上下四分位数位置
q75_bmi, q25_bmi = np.percentile(df['bmi'], [75 ,25])
iqr_bmi = q75_bmi - q25_bmi
iqr_bmi

# 计算上下边界以用于异常检测
bmi_h_bound = q75_bmi+(1.5*iqr_bmi)
bmi_l_bound = q25_bmi-(1.5*iqr_bmi)
print(bmi_h_bound)
print(bmi_l_bound)

# 排序
df.sort_values(by=['bmi'], ascending=True)
df.sort_values(by=['bmi'], ascending=False)

# 剔除异常值
df.drop(df[df['bmi'] >= 47.3].index, inplace = True)
df.drop(df[df['bmi'] <= 13.7].index, inplace = True)

我们只需要对可变费用做同样的事情,我们将获得以下箱线图和直方图:

参考资料

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

登录 后参与评论
0 条评论

相关文章

  • 农行 DevOps 进行时之最佳实践分享:实现 .net web 单元测试代码覆盖率统计

    单元测试代码覆盖率是软件测试中的一个度量指标,是衡量程序中源代码被测的比例和程度,DevOps 标准中需要项目单元测试代码覆盖率和接口覆盖率达到一定的比例。农行...

    DevOps时代
  • 机器学习实践中应避免的七种常见错误

    用户1737318
  • 独家 | 在Python中使用广义极端学生化偏差(GESD)进行异常检测(附链接)

    异常检测在生活中起着非常重要的作用。通常,异常数据可能与某种问题或罕见事件有关,例如 银行欺诈、医疗问题、结构缺陷、设备故障等。这种联系使得能够挑选出哪些数据点...

    数据派THU
  • 【机器学习】机器学习实践中的7种常见错误

    本文作者是 Codecademy 的分析主管 Cheng-TaoChu,其专长是数据挖掘和机器学习,之前在 Google、LinkedIn和Square就职。 ...

    陆勤_数据人网
  • 使用R语言进行异常检测

    本文结合R语言,展示了异常检测的案例,主要内容如下: (1)单变量的异常检测 (2)使用LOF(local outlier factor,局部异常因子)进行异常...

    小莹莹
  • 一文读懂!异常检测全攻略!从统计方法到机器学习 ⛵

    异常值是偏离数据集中大多数样本点的数据点。出现异常值的原因有很多,例如自然偏差、欺诈活动、人为或系统错误。不过,在我们进行任何统计分析或训练机器学习模型之前,对...

    ShowMeAI
  • 该怎么检测异常值?

    原文作者: Jacob Joseph 原文链接:https://blog.clevertap.com/how-to-detect-outliers-u...

    机器学习AI算法工程
  • 独家 | 每个数据科学家应该知道的五种检测异常值的方法(附Python代码)

    作者:Will Badr 翻译:顾伟嵩校对:欧阳锦 本文约1600字,建议阅读5分钟本文介绍了数据科学家必备的五种检测异常值的方法。

    数据派THU
  • 异常检测的阈值,你怎么选?给你整理好了...

    异常值是指距离其他观测值非常遥远的点,但是我们应该如何度量这个距离的长度呢?同时异常值也可以被视为出现概率非常小的观测值,但是这也面临同样的问题——我们要如何度...

    昱良
  • 机器学习算法原理系列详解-机器学习基础与实践(一)-数据清洗

    作者:Charlotte77 数学系的数据挖掘民工 博客专栏:http://www.cnblogs.com/charlotte77/ 个人公众号:Charlo...

    企鹅号小编
  • 机器学习基础与实践(一)——数据清洗

    想写这个系列很久了,最近刚好项目结束了闲下来有点时间,于是决定把之前学过的东西做个总结。之前看过一些机器学习方面的书,每本书都各有侧重点,机器学习实战和集体智慧...

    CDA数据分析师
  • 四种检测异常值的常用技术简述

    在训练机器学习算法或应用统计技术时,错误值或异常值可能是一个严重的问题,它们通常会造成测量误差或异常系统条件的结果,因此不具有描述底层系统的特征。实际上,最...

    用户3578099
  • 提高机器学习模型准确率的八大可靠方法

    介绍 想要提高模型的性能有时会是一件难度不小的事情。如果你也遇到过类似的情况,相信一定会认同我这一看法。在一一尝试毕生所学的对策和算法之后,依然没能够提高模型的...

    灯塔大数据
  • R语言用ARIMA模型滑动时间窗口识别网络流量时间序列异常值

    最近我们被要求解决时间序列异常检验的问题。有客户在使用大量的时间序列。这些时间序列基本上是每10分钟进行一次的网络测量,其中一些是周期性的(即带宽),而另一些则...

    拓端
  • 线性回归(二)-违背基本假设的情况和处理方法

    由线性回归(一)^1,我们通过数学中的极值原理推导出了一元线性回归的参数估计和多元线性回归的参数估计的拟合方程计算方法。同时为了检验拟合质量,我们引入了两种主要...

    EatRice
  • 智能运维常见时序数据异常点检测技术

    基于数据,构建一个概率分布模型,得出模 型的概率密度函数。通常,异常点的概率是很低的。

    曲奇
  • 特征工程系列:数据清洗

    关于作者:JunLiang,一个热爱挖掘的数据从业者,勤学好问、动手达人,期待与大家一起交流探讨机器学习相关内容~

    木东居士
  • 学会五种常用异常值检测方法,亡羊补牢不如积谷防饥

    在统计学中,是并不属于特定族群的数据点,是与其它值相距甚远的异常观测。离群点是一种与其它结构良好的数据不同的观测值。

    统计学家
  • 深入机器学习系列之异常检测

    今天要给大家介绍的是异常检测(Anomaly Detection), 它是机器学习的一个重要分支,实际应用领域广泛,更与我们的生活息息相关。那么什么是异常检测?...

    数据猿

扫码关注腾讯云开发者

领取腾讯云代金券