乐趣区

关于机器学习:使用孤立森林进行无监督的离群检测

孤立森林是 一种无监督算法的异样检测,能够疾速检测数据集中的异样值。

孤立森林是一种简略但十分无效的算法,可能十分疾速地发现数据集中的异样值。了解这个算法对于解决表格数据的数据科学家来说是必须的,所以在本文中将简要介绍算法背地的实践及其实现。

因为其算法十分的简略并且高效,所以 Scitkit Learn 曾经将其进行了高效的实现,咱们能够间接调用应用。但在间接进入示例之前,还是须要介绍其背地的实践,这样才能够深刻的理解该算法的。

一些实践

1、什么是异样?

异样(异样值)能够形容为数据集中与其余数据或察看后果显著不同的数据点。产生这种状况的起因有几个:

  • 异样值可能示意谬误数据不正确或试验可能未正确运行。
  • 异样值可能是因为随机变动或可能表明某些迷信上乏味的货色。

2、为什么要进行异样检测?

咱们之所以想要找出和深入研究异样,是因为这些数据点要么会节约的工夫和精力,要么能够让咱们辨认出有意义的货色。

在简略线性回归的状况下,谬误的异样值会减少模型的方差,并进一步升高模型对数据的把握能力。异样值导致回归模型(尤其是线性模型)学习对异样值的偏差了解。

孤立森林如何工作

其余的办法始终在尝试构建失常数据的配置文件(散布、法则等),而后进一步将哪些不合乎配置文件的数据点辨认为异样。

而孤立森林的亮点在于它能够应用“孤立”规定来间接检测异样(一个数据点与其余数据的间隔)。这意味着该算法能够像其余与间隔相干的模型(例如 K-Nearest Neighbors)一样以线性工夫复杂度运行。

该算法是通过以异样值最显著的特点为核心来进行工作:

  • 只会有几个异样值
  • 有异样值必定与其余值不同

孤立森林通过引入(一组)二叉树来实现,该二叉树通过随机抉择一个特色而后随机抉择该特色的宰割值来递归地生成分区。分区过程将始终继续,直到它将所有数据点与其余样本离开。

因为每棵树的实例中只抉择一个特色。能够说决策树的最大深度实际上是一,所以孤立森林的根本预计器实际上是一个具备各种数据子集的极其随机的决策树(ExtraTrees)。

孤立森林中的一棵树的示例如下:

上图异样值的属性,能够察看到与失常样本相比异样值均匀须要更少的分叉就能将它们隔离。每个数据点将在 X 轮之后依据它们被隔离的容易水平取得分数,有异样分数的数据点将被标记为异样。

通过随机抉择属性 q 和宰割值 p(在属性 q 的最小最大值内) 递归地宰割每个数据实例,直到它们齐全隔离。而后算法将提供一个排名,依据门路长度反映每个数据实例的异样水平。排名或分数称为异样分数,其计算方法如下:

  • H(x): 数据实例 x 齐全隔离之前的步骤数。
  • E[H(x)]: 隔离树汇合中 H(x) 的平均值。

这些度量是有意义的,但一个问题:树的最大可能步长为 n 阶,而均匀步长仅为 log n 阶。这将导致步骤不能间接比拟,所以须要引入一个由 n 变动的标准化常数 c(n),被称作门路长度归一化常数,公式如下:

其中 H (i) 是能够通过 ln (i) + 0.5772156649(欧拉常数)预计的谐波数。

异样分数的残缺公式为:

因而,如果通过孤立森林运行整个数据集,就能够取得异样分数。应用异样分数 s,只有有异样分数十分靠近 1 的实例,咱们就能够推断存在在异样。或者说任何低于 0.5 的分数都将被辨认为失常实例。

另外须要阐明的是:在 sklearn 的实现中,异样分数与原始论文中定义的异样分数相同。它会减去常数 0.5。这是为了轻松辨认异样(负分数与异样一起辨认),具体能够参考 sklearn 文档

孤立森林示例

首先,咱们疾速导入一些有用包,并应用 make_blob () 函数生成具备随机数据点的数据集。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs

data, _ = make_blobs(n_samples=500, centers=1, cluster_std=2, center_box=(0, 0))
plt.scatter(data[:, 0], data[:, 1])
plt.show()

上图能够很容易地察看到一些异样值。这里咱们应用二维用例是为疾速证实算法有效性。该算法能够毫无问题地用于具备多维特色的数据集。

上面通过调用 IsolationForest() 来初始化一个孤立森林对象。

这里应用的超参数都是最默认的,也是原始论文举荐的。

树的数量管制集成的大小。门路长度通常会在 t = 100 之前收敛。除非另有阐明,否则咱们将在试验中应用 t = 100 作为默认值。

子集样本设置为 256 通常能够提供足够的细节来在宽泛的数据中执行异样检测

N_estimators 代表树的数量,最大样本代表每轮应用的子集样本。

Max_samples = ‘auto’ 将子集大小设置为 min (256, num_samples)。

这里的 contamination 代表数据集中异样值的比例。默认状况下,异样分数阈值将遵循原始论文中的内容。然而,如果咱们有任何先验常识,则能够手动设置数据中异样值的比例。本文中将其设置为 0.03。

拟合并预测整个数据集后会返回一个由 [-1 或 1] 组成的数组,其中 -1 代表异样,1 代表失常实例。

iforest = IsolationForest(n_estimators = 100, contamination = 0.03, max_samples ='auto)
prediction = iforest.fit_predict(data)

print(prediction[:20])
print("Number of outliers detected: {}".format(prediction[prediction < 0].sum()))
print("Number of normal samples detected: {}".format(prediction[prediction > 0].sum()))

而后咱们将绘制隔检测到的异样值。

normal_data = data[np.where(prediction > 0)]
outliers = data[np.where(prediction < 0)]
plt.scatter(normal_data[:, 0], normal_data[:, 1])
plt.scatter(outliers[:, 0], outliers[:, 1])
plt.title("Random data points with outliers identified.")
plt.show()

能够看到它工作得很好,能够辨认边缘四周的数据点。

也能够调用 decision_function() 来计算每个数据点的异样分数。这样咱们就能够理解哪些数据点比拟异样。

score = iforest.decision_function(data)
data_scores = pd.DataFrame(list(zip(data[:, 0],data[:, 1],score)),columns = ['X','Y','Anomaly Score'])

display(data_scores.head())

抉择异样分数前 5 的异样值,而后再次绘制它。

top_5_outliers = data_scores.sort_values(by = ['Anomaly Score']).head()
plt.scatter(data[:, 0], data[:, 1])
plt.scatter(top_5_outliers['X'], top_5_outliers['Y'])
plt.title("Random data points with only 5 outliers identified.")
plt.show()

总结

孤立森林是一种齐全不同的异样值检测模型,能够以极快的速度发现异常。它具备线性工夫复杂度,这使其成为解决大量数据集的最佳办法之一。

它基于异样“很少且不同”这个概念,因而与失常点相比,异样点更容易被孤立。它的 Python 实现能够在 sklearn.ensemble.IsolationForest 找到。

论文地址:https://www.overfit.cn/post/079d4e026b3d42fd9131f14036a6a0f1

Isolation Forest by Fei Tony Liu, Kai Ming Ting Gippsland School of Information Technology Monash University, Victoria, Australia.

作者:Yenwee Lim

退出移动版