利用线性回归模型检测异常

利用线性回归模型检测异常

关键思想
真实值与模型预测值之间的差值可以用来衡量这个数据点是多么异常。

检测步骤如下

  1. 将数据集分割为训练集(均为正常点)和测试集(包含异常点)
  2. 利用训练集得到线性回归模型的参数和选择是否判断为异常的阈值。
  3. 将第2步得到的模型和阈值检测测试集。

对于第一点,我们得到的线性回归模型参数一定得是基于正常点的,否则,会出现下图这种情况:
利用线性回归模型检测异常_第1张图片
其中,左侧是基于正常数据的拟合结果,右侧是基于含有异常数据的拟合结果,蓝色是拟合线,绿色是基于正常数据的拟合线。我们可以发现,异常点的存在使拟合线发生了偏移,使“正常值显得有点不正常,异常值显得有点正常”

举一个例子,我们有一个考试成绩y和学习时长x的数据集,实验过程如下:

import numpy as np
import sklearn.linear_model as linear_model
#第一步,得到训练集exam_data1和测试集exam_data2
exam_data1 = np.array([[1, 2, 3, 4, 5],
                    [57, 70, 76, 84, 91]]).T
# One anomaly replaces a normal point
exam_data2 = np.array([[1, 2, 3, 4, 5],
                      [57, 70, 99, 84, 91]]).T

ftrs, tgt = exam_data1[:,0:1], exam_data1[:,1]
#第二步,利用训练集拟合线性回归模型
lr_train = linear_model.LinearRegression().fit(ftrs, tgt)
print(f'Slope: {lr_train.coef_}')#系数项
print(f'Intercept: {lr_train.intercept_:.{3}}')#截距项
#第二步,确定阈值为略高于训练集分数的最大值
#用残差的平方作为异常分数
train_scores = (tgt - lr_train.predict(ftrs))**2 
margin = 0.01
threshold = max(train_scores) + margin
print(f'Threshold: {threshold:.{3}}')
#第三步,计算测试集的异常分数
anom_score = (exam_data2[:,1] - lr_train.predict(exam_data2[:,0:1]))**2
print("测试集的异常分数:",anom_score)
print("超过阈值的异常分数:",anom_score[(anom_score>threshold)])

利用线性回归模型检测异常_第2张图片

你可能感兴趣的:(anomaly,detection,python,逻辑回归)