异常值检测

2019-08-29 11:27:47 浏览数 (1)

异常值

异常值(outlier)是指一组测定值中与平均值的偏差超过两倍标准差的测定值,与平均值的偏差超过三倍标准差的测定值,称为高度异常的异常值。

异常值分析

  • 异常值分析是检验数据是否有录入错误以及含有不合常理的数据;
  • 异常值是指样本中的个别值,其数据明显偏离其余的观测值。异常值也称为离群点,异常值的分析也称为离群点分析。
  • 异常值处理一般分为以下几个步骤:异常值检测、异常值筛选、异常值处理。

环境

  • jupyter notebook

实战演练

现在老板给了我有个任务,说

的数据有几个异常值,搞它出来,顺便 做下预测

???我好像没有老板,全是吹逼,75000行,这怎么找?

思路

我先找出 固定间隔

含量的差值,就是这个数减去上面的数,画下图来看看是否在0的附近

  • 导入包
代码语言:javascript复制
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
  • 读取数据
代码语言:javascript复制
data = pd.read_csv('C0911.csv', header=0)   # C0911.csv, C0904.csv
x = data['H2O'].values
  • 异常检测
代码语言:javascript复制
# 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()是计算最大值与最小值差的函数
代码语言:javascript复制
>>> 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()

效果如图

0 人点赞