当前位置:   article > 正文

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

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

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

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

箱线图异常值检测

具体步骤:

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

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

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

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

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

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

代码实现:
  1. import numpy as np
  2. # 生成模拟数据集
  3. np.random.seed(42)
  4. data = np.random.randint(500, 1000, 95)
  5. # 添加一些异常值
  6. data[10] = 2
  7. data[20] = 8
  8. data[30] = 5500
  9. data[40] = 5200
  10. data[50] = 5100
  11. # 对数据从小到大排序
  12. data.sort()
  13. # 计算四分位数和四分位距
  14. Q1 = np.percentile(data, 25)
  15. Q3 = np.percentile(data, 75)
  16. IQR = Q3 - Q1
  17. # 定义异常值边界
  18. lower_bound = Q1 - 1.5 * IQR
  19. upper_bound = Q3 + 1.5 * IQR
  20. # 标记异常值
  21. outliers = data[(data < lower_bound) | (data > upper_bound)]
  22. normal_data = data[~((data < lower_bound) | (data > upper_bound))]
  23. # 打印结果
  24. print("Outliers:", outliers)
  25. print("Normal Data:", normal_data)
结果解读:

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

 matplotlib实现:

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

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

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

代码实现:
  1. import numpy as npimport matplotlib.pyplot as plt
  2. # 生成模拟数据集
  3. np.random.seed(42)
  4. data = np.random.randint(500, 1000, 95)# 添加一些异常值
  5. data[10] = 2
  6. data[20] = 8
  7. data[30] = 5500
  8. data[40] = 5200
  9. data[50] = 5100
  10. # 对数据从小到大排序
  11. data.sort()
  12. # 计算四分位数和四分位距
  13. Q1 = np.percentile(data, 25)
  14. Q3 = np.percentile(data, 75)
  15. IQR = Q3 - Q1
  16. # 定义异常值边界
  17. lower_bound = Q1 - 1.5 * IQR
  18. upper_bound = Q3 + 1.5 * IQR
  19. # 标记异常值
  20. outliers = data[(data < lower_bound) | (data > upper_bound)]
  21. normal_data = data[~((data < lower_bound) | (data > upper_bound))]
  22. # 可视化结果
  23. plt.figure(figsize=(10, 6))
  24. plt.boxplot(data, vert=False)
  25. plt.vlines(lower_bound, 0, 1, colors='r', linestyles='dashed')
  26. plt.vlines(upper_bound, 0, 1, colors='r', linestyles='dashed')
  27. plt.scatter(outliers, [0.5] * len(outliers), color='r', label='Outliers')
  28. plt.scatter(normal_data, [0.5] * len(normal_data), color='b', label='Normal Data')
  29. plt.legend()
  30. plt.title('Outlier Detection using IQR')
  31. plt.xlabel('Data Values')
  32. plt.ylabel('Data Points')
  33. 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.标记异常值

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

代码实现:
  1. import numpy as npimport matplotlib.pyplot as plt
  2. # 生成模拟数据集
  3. np.random.seed(42)
  4. data = np.random.randint(500, 1000, 95)# 添加一些异常值
  5. data[10] = 2
  6. data[20] = 8
  7. data[30] = 5500
  8. data[40] = 5200
  9. data[50] = 5100
  10. # 计算均值和标准差
  11. mean = np.mean(data)
  12. std_dev = np.std(data)
  13. # 定义异常值边界
  14. lower_bound = mean - 3 * std_dev
  15. upper_bound = mean + 3 * std_dev
  16. # 标记异常值
  17. outliers = data[(data < lower_bound) | (data > upper_bound)]
  18. normal_data = data[~((data < lower_bound) | (data > upper_bound))]
  19. # 可视化结果
  20. plt.figure(figsize=(12, 6))
  21. plt.plot(data, label='Data', color='b', marker='o')
  22. plt.axhline(y=mean, color='g', linestyle='-', label='Mean')
  23. plt.axhline(y=lower_bound, color='r', linestyle='--', label='Lower Bound (3σ)')
  24. plt.axhline(y=upper_bound, color='r', linestyle='--', label='Upper Bound (3σ)')
  25. plt.scatter(np.where((data < lower_bound) | (data > upper_bound)), outliers, color='r', marker='x', s=100, label='Outliers')
  26. plt.legend()
  27. plt.title('Outlier Detection using 3σ Rule')
  28. plt.xlabel('Index')
  29. plt.ylabel('Data Values')
  30. plt.show()
运行结果:

 

结果解读:

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

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

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

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

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

        异常值

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

注释(适用范围)

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

        

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/759995
推荐阅读
相关标签
  

闽ICP备14008679号