异常值检测(1)——箱线图四分位距和3σ

        说白了,异常值就是那些偏离多数样本值过多的值,比如我用机器学习在做房价预测时,获取的沈阳浑南区数据普遍都在11000左右,结果有那么一两个楼盘是20000(管他是不是碧桂园),那么这两个值就是异常值。

        异常值会严重干扰模型的性能,包括降低预测能力、增加过拟合风险、降低模型解释性以及降低计算效率等方面。

箱线图异常值检测

具体步骤:

        这个就是常说的四分位距检测。在本方法中,首先是对数据集从小到大排序,接着定义三个点:

        上四分位数:数据的75%分位点所对应的值(Q3)——75%的数据比他小

        中位数:数据的50%分位点所对应的值(Q2)——同理,一半的数据比他小

        下四分位数:数据的25%分位点所对应的值(Q1),同理。

        异常值被定义为小于Q1-1.5IQR或大于Q3+1.5IQR的值,其中:IQR = Q3 - Q1。

        这种方法对异常值的定义是基于数据分布的,而不需要假设数据服从某种特定分布。

代码实现:
import numpy as np

# 生成模拟数据集
np.random.seed(42)
data = np.random.randint(500, 1000, 95)
# 添加一些异常值
data[10] = 2
data[20] = 8
data[30] = 5500
data[40] = 5200
data[50] = 5100

# 对数据从小到大排序
data.sort()

# 计算四分位数和四分位距
Q1 = np.percentile(data, 25)
Q3 = np.percentile(data, 75)
IQR = Q3 - Q1

# 定义异常值边界
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 标记异常值
outliers = data[(data < lower_bound) | (data > upper_bound)]
normal_data = data[~((data < lower_bound) | (data > upper_bound))]

# 打印结果
print("Outliers:", outliers)
print("Normal Data:", normal_data)
结果解读:

        Outliers数据集中的数就是异常值,下面的数据集是正常值。

 matplotlib实现:

        其实吧,在实际应用中就没这么麻烦了,matplotlib里面有专门的函数:plt.boxplot(data, showfliers=True)。这个函数就是Matplotlib中用于绘制箱线图的函数。它可以很方便地帮我们可视化数据中的异常值。

        data:传入需要绘制箱线图的数据,可以是一个列表、numpy数组或Pandas DataFrame。

        showfliers=True: 这个是可选参数,默认为False。当设置为True时,函数会在箱线图上标记出被识别为异常值的数据点。

代码实现:
import numpy as npimport matplotlib.pyplot as plt

# 生成模拟数据集

np.random.seed(42)

data = np.random.randint(500, 1000, 95)# 添加一些异常值

data[10] = 2

data[20] = 8

data[30] = 5500

data[40] = 5200

data[50] = 5100

# 对数据从小到大排序

data.sort()

# 计算四分位数和四分位距

Q1 = np.percentile(data, 25)

Q3 = np.percentile(data, 75)

IQR = Q3 - Q1

# 定义异常值边界

lower_bound = Q1 - 1.5 * IQR

upper_bound = Q3 + 1.5 * IQR

# 标记异常值

outliers = data[(data < lower_bound) | (data > upper_bound)]

normal_data = data[~((data < lower_bound) | (data > upper_bound))]

# 可视化结果

plt.figure(figsize=(10, 6))

plt.boxplot(data, vert=False)

plt.vlines(lower_bound, 0, 1, colors='r', linestyles='dashed')

plt.vlines(upper_bound, 0, 1, colors='r', linestyles='dashed')

plt.scatter(outliers, [0.5] * len(outliers), color='r', label='Outliers')

plt.scatter(normal_data, [0.5] * len(normal_data), color='b', label='Normal Data')

plt.legend()

plt.title('Outlier Detection using IQR')

plt.xlabel('Data Values')

plt.ylabel('Data Points')

plt.show()
结果解读:

        箱线图(Boxplot)

        1.箱线图的主体部分(长方形箱子),上下沿距离代表数据的四分位距(IQR),即从第25 百分位数(Q1)到第75百分位数(Q3)的范围。

        2.箱子中间的橙色的线代表数据的中位数(Q2)。

        3.上下边界(和箱子连接着的两条单独横线)之间是正常值的范围。

两横线各自距离箱子(也就是小竖线)的长度即是 1.5倍的IQR。

        离群点

        1.白色小圆圈就是小于Q1-1.5IQR或大于Q3+1.5IQR的值,也就是异常值。

3σ异常值检测

        3σ法则是基于正态分布的统计方法,用于检测数据中的异常值。在正态分布中:

        68.27% 的数据会落在均值 μ的 ±1σ内。

        95.45% 的数据会落在均值 μ的 ±2σ内。

        99.73% 的数据会落在均值 μ的 ±3σ内。

        如果一个数据点落在 μ±3σ 的范围之外,只有不到 0.3% 的概率,因此认为是误差。

具体步骤:

        1.计算均值和标准差

        计算数据集的均值(μ)和标准差(σ )

        2.定义异常值范围

        异常值范围定义为小于 均值 - 3 * 标准差 或大于 均值 + 3 * 标准差 的数据点。

        3.标记异常值

        超出上述范围的数据点为异常值。

代码实现:
import numpy as npimport matplotlib.pyplot as plt

# 生成模拟数据集

np.random.seed(42)

data = np.random.randint(500, 1000, 95)# 添加一些异常值

data[10] = 2

data[20] = 8

data[30] = 5500

data[40] = 5200

data[50] = 5100

# 计算均值和标准差

mean = np.mean(data)

std_dev = np.std(data)

# 定义异常值边界

lower_bound = mean - 3 * std_dev

upper_bound = mean + 3 * std_dev

# 标记异常值

outliers = data[(data < lower_bound) | (data > upper_bound)]

normal_data = data[~((data < lower_bound) | (data > upper_bound))]

# 可视化结果

plt.figure(figsize=(12, 6))

plt.plot(data, label='Data', color='b', marker='o')

plt.axhline(y=mean, color='g', linestyle='-', label='Mean')

plt.axhline(y=lower_bound, color='r', linestyle='--', label='Lower Bound (3σ)')

plt.axhline(y=upper_bound, color='r', linestyle='--', label='Upper Bound (3σ)')

plt.scatter(np.where((data < lower_bound) | (data > upper_bound)), outliers, color='r', marker='x', s=100, label='Outliers')


plt.legend()

plt.title('Outlier Detection using 3σ Rule')

plt.xlabel('Index')

plt.ylabel('Data Values')

plt.show()
运行结果:

 

结果解读:

        蓝色实线:表示数据的分布情况。每个数据点用蓝色圆圈标记,并用线连接。这条线展示了数据的波动和趋势。

        绿色实线:表示数据的均值(μ)。

       红色虚线:表示异常值的上下界限(lower bound 和 upper bound),根据 3σ 法则计算得出。

                上界限(Upper Bound):均值 (μ)+ 3 * 标准差(σ)。

                下界限(Lower Bound):均值 (μ)- 3 * 标准差(σ)。

        异常值

                红色 "x" 标记:表示检测到的异常值。这些点超出了上下界限。

注释(适用范围)

        后面还会出什么时候适用这些方法,敬请期待,一见三连,你最好看~

        

  • 32
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值