异常检测简介与python实现

异常检测背景介绍

机器学习前期大部分工作都属于特征工程的范畴,我们通过各种方法搜集到最能够表达研究对象的特征,然后选择合适的机器学习算法对特征进行回归、分类等。我们的研究对象是多样的,因此搜集到的特征也是多样的,我们要做的就是根据这些特征进行监测和分类。

异常检测(Anomaly Detection),也叫做离群点检测(Outlier Detection),属于机器学习与现实紧密结合,并且有广泛应用场景的一类问题。顾名思义,异常检测就是用来检测异常情况的,在机器学习中,当出现异常情况的时候,必然会出现离群点。下面对离群点做两个标准界定:

1、离群点数据和样本中的大多数数据差别很大
2、离群点的数量在样本比例中占很少一部分

异常检测使用场景

什么情况下适合使用异常检测呢?
1、在做特征工程的时候对异常数据,譬如噪声等,进行过滤,防止对算法的效果产生影响;
2、在做二分类的时候,其中一类数据的样本数量很小,而另一类数据的样本数量很大,样本比例严重失调,这时可以考虑使用无监督学习的异常检测算法;
3、检测筛选出未标注的异常数据。

异常检测算法分类

一般地,异常检测算法分为三类。
第一种是基于统计学的方法。综合已有研究数据,建立概率模型,将待检测样本数据输入概率模型进行计算,如果概率很低,则判定样本为异常点。
第二种是基于聚类的方法。通过特征对样本进行聚类,形成不同的簇,聚类完成后观察哪些聚类簇离其他聚类簇较远,将这类离群的簇视为异常点。
第三种是基于专门的异常点检测算法。首先训练出检测模型,再将样本点输入模型进行判断,比如Isolation Forest
下面主要对第一种基于统计学的异常检测算法进行介绍。

多元高斯异常检测概率模型

多元高斯概率模型适合特征维度较小的样本集,因为搭建多元高斯模型时要求解协方差矩阵,如果特征维度过高,会导致消耗计算资源过多,有失性价比。多元高斯概率模型注重实际性,因为它的出发点是各个特征之间不是相互独立的,这在现实中也是不可避免的。这样使得多元高斯概率模型表明了各个特征之间的联合分布以及特征之间的相关性。

多元高斯概率模型检测异常步骤
  1. 特征收集以及训练集、验证集测试集分配
    特征工程是后期筛选的保障,选择特征的好坏直接决定了模型的性能。收集到研究对象样本集的特征之后,先观察各个特征是否呈正态分布,如果呈现高斯分布则不予后期处理;若某一个特征不符合高斯分布,则对特征进行相应的数学变换(取对数、开根号、取幂级数等),使得特征大体呈现高斯分布;处理完之后进行训练集、验证集以及测试集的划分,训练集看作无标签,采用K折交叉验证,有助于提高模型精准度。

  2. 模型训练(参数估计)
    第一步整理好的训练集和验证集输入到模型中估计参数(Σ、μ…),其中Σ是特征的协方差矩阵,μ是特征的均值向量。估算出参数之后,得到多元高斯概率模型如下:
    在这里插入图片描述

  3. 模型预测(异常检测)
    采集到的样本输入到上述模型中,观察模型输出的概率值,如果概率值小于设定的阈值,则判断为异常;否则为正常。

注意

模型训练过程中可能会出现特征矩阵为奇异矩阵的情况,这时协方差矩阵的行列式为零,模型失效。导致这种情况的原因可能有一下两点:

  1. 样本数小于特征数
  2. 特征之间存在重复现象(从线性代数的角度来说就是特征之间存在线性相关的关系)

Python实现

# -*- coding: utf-8 -*-
"""
Created on Mon Jun  8 11:12:53 2020

@author: Scientist
"""


import math
import numpy as np
import matplotlib.pyplot as plt


x1 = np.round(np.random.normal(0, 0.5, size=(1, 12)), 2)
x2 = np.round(np.random.normal(0, 1.5, size=(1, 12)), 2)
x3 = np.round(np.random.normal(1, 1.5, size=(1, 12)), 2)

p = np.pi
data = np.concatenate((x1, x2, x3),axis=0)
data_mean = np.mean(data, axis=1).reshape(3, 1)
sigma = np.dot((data-data_mean), (data-data_mean).T)/12
print(sigma)
# sigma = np.cov(data, rowvar=False) # rowvar=True indicate that each row representation a variable
sigma_det = np.linalg.det(sigma)

x = np.random.randn(3, 1)
x = np.matrix(x)
print("x : ", x)
print("sqrt on sigma: ", np.sqrt(sigma_det))
PFront = 1/(2 * p * np.sqrt(sigma_det))
product = np.matmul(np.transpose(x - data_mean), np.linalg.inv(sigma))
product = np.matmul(product, x - data_mean)
PBack = np.exp(-0.5 * product)
P = PFront * PBack
print(P)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值