说白了,异常值就是那些偏离多数样本值过多的值,比如我用机器学习在做房价预测时,获取的沈阳浑南区数据普遍都在11000左右,结果有那么一两个楼盘是20000(管他是不是碧桂园),那么这两个值就是异常值。
异常值会严重干扰模型的性能,包括降低预测能力、增加过拟合风险、降低模型解释性以及降低计算效率等方面。
箱线图异常值检测
具体步骤:
这个就是常说的四分位距检测。在本方法中,首先是对数据集从小到大排序,接着定义三个点:
上四分位数:数据的75%分位点所对应的值(Q3)——75%的数据比他小;
中位数:数据的50%分位点所对应的值(Q2)——同理,一半的数据比他小;
下四分位数:数据的25%分位点所对应的值(Q1),同理。
异常值被定义为小于Q1-1.5IQR或大于Q3+1.5IQR的值,其中:IQR = Q3 - Q1。
这种方法对异常值的定义是基于数据分布的,而不需要假设数据服从某种特定分布。它能较好地识别数据中的离群点,是一种简单有效的异常值检测方法。
python代码实现:
import numpy as np
import 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.正常数据点用蓝色标识,位于正常值的范围内。
2.红色标记点就是小于Q1-1.5IQR或大于Q3+1.5IQR的值,也就是异常值。
matplotlib实现:
其实吧,在实际应用中就没这么麻烦了,matplotlib里面有专门的函数:plt.boxplot(data, showfliers=True)。这个函数就是Matplotlib中用于绘制箱线图的函数。它可以很方便地帮我们可视化数据中的异常值。
data:传入需要绘制箱线图的数据,可以是一个列表、numpy数组或Pandas DataFrame。
showfliers=True: 这个是可选参数,默认为False。当设置为True时,函数会在箱线图上标记出被识别为异常值的数据点。
3σ异常值检测
3σ法则是基于正态分布的统计方法,用于检测数据中的异常值。在正态分布中:
68.27% 的数据会落在均值 μ的 ±1σ内。
95.45% 的数据会落在均值 μ的 ±2σ内。
99.73% 的数据会落在均值 μ的 ±3σ内。
如果一个数据点落在 μ±3σ 的范围之外,只有不到 0.3% 的概率,因此认为是误差。
具体步骤:
1.计算均值和标准差:
计算数据集的均值(μ)和标准差(σ )
2.定义异常值范围:
异常值范围定义为小于 均值 - 3 * 标准差 或大于 均值 + 3 * 标准差 的数据点。
3.标记异常值:
超出上述范围的数据点为异常值。
Python代码实现:
import numpy as np
import 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" 标记:表示检测到的异常值。这些点超出了上下界限。
注释(适用范围)
后面还会出什么时候适用这些方法,敬请期待,一见三连,你最好看~
标签:线图,plt,数据,异常,bound,IQR,四分,位距,data From: https://blog.csdn.net/weixin_52040570/article/details/139867178