机器学习(9)-异常检测

异常检测

异常检测,是指在给点数据集中识别出与正常数据不同的数据和与预期行为差异大的数据。异常检测问题通常被归类为非监督学习问题,却具有与监督学习相似的特征。在异常检测中,通常处理的是未标记的数据,即没有明确的标签指示哪些样本是异常的,因此算法需要根据数据本身的特征来确定异常。

异常检测方法

基于统计-基于高斯分布的异常检测

高斯分布

高斯分布(Gaussian Distribution),也称为正态分布(Normal Distribution)。随机变量X服从一个数学期望μ、方差为σ的高斯分布,记作

当μ = 0,σ = 1时的正态分布称为标准正态分布。高斯分布概率密度函数如下

正常的数据点的各个特征应该集中分布在一个区间段内,当数据点出现异常时,它的这些特征数据往往离集中区间较远。那么就是说,当一个数据点的特征数据在集中区间内,那么该数据点是正常数据的概率很大,反之,当一个数据点的特征数据不在集中区间内,那么该数据点是正常数据的概率很低,也就是异常的概率很大。

上述数据分布的特点很像高斯分布,高斯分布图像如下。

基于高斯分布的异常检测的思想是利用异常较少的数据集拟合出一个高斯分布,当要预测一个样本是否为异常时,只需将这个新样本带入高斯分布求出概率,如果概率小于指定的阈值时,就可以认为这个样本是异常的。

基于深度-基于孤立森林的异常检测

孤立森林 (Isolation Forest, iForest)是一个基于Ensemble的快速离群点检测方法,具有线性的时间复杂度和高精准度,由南京大学周志华教授等人于2008年首次提出适用于连续数据(Continuous Numerical Data)的异常检测。

假设我们用一个随机超平面来切割数据空间, 切一次可以生成两个子空间(想象拿刀切蛋糕一分为二)。之后我们再继续用一个随机超平面来切割每个子空间,循环下去,直到每子空间里面只有一个数据点为止。直观上来讲,我们可以发现那些密度很高的簇是可以被切很多次才会停止切割,但是那些密度很低的点很容易很早的就停到一个子空间。

怎么来切这个数据空间是iForest的设计核心思想,由于切割是随机的,所以需要用Ensemble方法来得到一个收敛值(蒙特卡洛方法),即反复从头开始切,然后平均每次切的结果。iForest 由 T 个 iTree 组成,每个 iTree 是一个二叉树结构。该算法大致可以分为两个阶段,第一个阶段我们需要训练出 T 颗孤立树,组成孤立森林。随后我们将每个样本点带入森林中的每棵孤立树,计算平均高度,之后再计算每个样本点的异常值分数。

第一阶段,步骤如下:

  1. 从训练数据中随机选择Ψ个点样本点作为样本子集,放入树的根节点。
  2. 随机指定一个维度(特征),在当前节点数据中随机产生一个切割点 p(切割点产生于当前节点数据中指定维度的最大值和最小值之间)。
  3. 以此切割点生成了一个超平面,然后将当前节点数据空间划分为2个子空间:把指定维度里小于 p 的数据放在当前节点的左子节点,把大于等于 p 的数据放在当前节点的右子节点。
  4. 在子节点中递归步骤(2)和(3),不断构造新的子节点,直到子节点中只有一个数据(无法再继续切割)或子节点已到达限定高度。
  5. 循环步骤(1)至(4),直至生成 T 个孤立树iTree。

第二阶段:

获得T个iTree之后,iForest训练就结束,然后我们可以用生成的iForest来评估测试数据了。对于每一个数据点 x i ,令其遍历每一颗孤立树iTree,计算点 x i 在森林中的平均高度 h ( x i ) ,对所有点的平均高度做归一化处理。

Python实践-异常检测

1.基于高斯分布的异常检测

使用sklearn库的EllipticEnvelope

import numpy as np
import matplotlib.pyplot as plt
from sklearn.covariance import EllipticEnvelope

# 生成训练数据
rng = np.random.RandomState(42)
X_train = 0.3 * rng.randn(100, 2)
X_train = np.r_[X_train + 2, X_train - 2]
X_outliers = rng.uniform(low=-4, high=4, size=(20, 2))

# 拟合EllipticEnvelope模型
clf = EllipticEnvelope(contamination=0.1)
clf.fit(X_train)

# 预测训练数据和异常数据
y_pred_train = clf.predict(X_train)
y_pred_outliers = clf.predict(X_outliers)

# 绘图
plt.figure(figsize=(8, 6))
plt.title("EllipticEnvelope - Anomaly Detection")
plt.scatter(X_train[:, 0], X_train[:, 1], c='blue', label="Training data")
plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='red', label="Outliers")

# 标记正常点和异常点
normal = X_train[y_pred_train == 1]
anomalies = X_train[y_pred_train == -1]
plt.scatter(normal[:, 0], normal[:, 1], c='blue', label="Normal points")
plt.scatter(anomalies[:, 0], anomalies[:, 1], c='green', label="Detected anomalies")

# 添加图例和标签
plt.legend()
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()

2.基于孤立森林(IsolationForest)算法的异常检测

使用sklearn库的IsolationForest

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest

# 生成训练数据
rng = np.random.RandomState(42)
X_train = 0.3 * rng.randn(100, 2)
X_train = np.r_[X_train + 2, X_train - 2]
X_outliers = rng.uniform(low=-4, high=4, size=(20, 2))

# 拟合IsolationForest模型
clf = IsolationForest(contamination=0.1, random_state=rng)
clf.fit(X_train)

# 预测训练数据和异常数据
y_pred_train = clf.predict(X_train)
y_pred_outliers = clf.predict(X_outliers)

# 绘图
plt.figure(figsize=(8, 6))
plt.title("IsolationForest - Anomaly Detection")
plt.scatter(X_train[:, 0], X_train[:, 1], c='blue', label="Training data")
plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='red', label="Outliers")

# 添加图例和标签
plt.legend()
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()

Reference

机器学习(十五)异常检测-CSDN博客

高斯分布-CSDN博客

14-8 使用高斯分布进行异常检测 (momodel.github.io)

【异常检测】孤立森林(Isolation Forest)算法简介 - 郭耀华 - 博客园 (cnblogs.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值