异常值
异常值(outlier)是指一组测定值中与平均值的偏差超过两倍标准差的测定值,与平均值的偏差超过三倍标准差的测定值,称为高度异常的异常值。
异常值分析
- 异常值分析是检验数据是否有录入错误以及含有不合常理的数据;
- 异常值是指样本中的个别值,其数据明显偏离其余的观测值。异常值也称为离群点,异常值的分析也称为离群点分析。
- 异常值处理一般分为以下几个步骤:异常值检测、异常值筛选、异常值处理。
环境
- jupyter notebook
实战演练
现在老板给了我有个任务,说
的数据有几个异常值,搞它出来,顺便 做下预测
???我好像没有老板,全是吹逼,75000行,这怎么找?
思路
我先找出 固定间隔
含量的差值,就是这个数减去上面的数,画下图来看看是否在0的附近
- 导入包
import numpy as np
import matplotlib as mpl
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import BaggingRegressor
mpl.rcParams['font.sans-serif'] = ['simHei']
mpl.rcParams['axes.unicode_minus'] = False
- 读取数据
data = pd.read_csv('C0911.csv', header=0) # C0911.csv, C0904.csv
x = data['H2O'].values
- 异常检测
# 75000个太多了
width = 500
# 步长
delta = 10
# 设置阈值
eps = 0.15
N = len(x) # 75000多
p = []
# 存放不正常的数据
abnormal = []
# i = 0 ,10,20……
for i in np.arange(0, N-width, delta):
s = x[i:i width]
p.append(np.ptp(s))
if np.ptp(s) > eps:
abnormal.append(list(range(i, i width)))
abnormal = np.unique(abnormal)
plt.figure(facecolor='w')
plt.plot(p, lw=1)
plt.grid(b=True, ls=':', color='#404040')
plt.title('固定间隔$H_2O$含量的差值', fontsize=16)
plt.xlabel('时间', fontsize=15)
plt.xlabel('差值', fontsize=15)
plt.show()
print(abnormal)
abnormal.shape
# [ 3740 3741 3742 ... 68207 68208 68209]
# (6530,)
说明ptp()函数
- ptp()是计算最大值与最小值差的函数
>>> x = np.arange(4).reshape((2,2))
>>> x
array([[0, 1],
[2, 3]])
>>> np.ptp(x, axis=0)
array([2, 2])
>>> np.ptp(x, axis=1)
array([1, 1])
根据图中很容易看出数据的分布,上面的代码就是为了找出abnormal
- 预测正确的数据
采用的集成决策树的方法
代码语言:javascript复制plt.figure(figsize=(11, 5), facecolor='w')
plt.subplot(131)
plt.plot(x, 'r-', lw=1, label='原始数据')
plt.title('实际排放数据', fontsize=16)
plt.legend(loc='upper right')
plt.grid(b=True, ls=':', color='#404040')
plt.subplot(132)
t = np.arange(N)
plt.plot(t, x, 'r-', lw=1, label='原始数据')
plt.plot(abnormal, x[abnormal], 'go', markeredgecolor='g', ms=2, label='异常值')
plt.legend(loc='upper right')
# 异常校正(预测)
plt.subplot(133)
select = np.ones(N, dtype=np.bool)
select[abnormal] = False
t = np.arange(N)
# 决策树
dtr = DecisionTreeRegressor(criterion='mse', max_depth=10)
# 10个决策树
br = BaggingRegressor(dtr, n_estimators=10, max_samples=0.3)
br.fit(t[select].reshape(-1, 1), x[select])
y = br.predict(np.arange(N).reshape(-1, 1))
y[select] = x[select]
plt.plot(x, 'g--', lw=1, label='原始值') # 原始值
plt.plot(y, 'r-', lw=1, label='校正值') # 校正值
plt.legend(loc='upper right')
plt.title('异常值校正', fontsize=16)
plt.grid(b=True, ls=':', color='#404040')
plt.tight_layout(1.5, rect=(0, 0, 1, 0.95))
plt.suptitle('排污数据的异常值检测与校正', fontsize=18)
plt.show()
效果如图