机器学习——LOF和孤立森林算法
机器学习——LOF和孤立森林算法
文章目录
- 前言
- 一、局部异常因子算法(LOF)
- 1.1. 原理
- 1.2. 代码实现
- 二、孤立森林(Isolation Forest)
- 2.1. 原理
- 2.2. 代码实现
- 三、比较
- 四、局部(全局)异常
- 4.1. 局部异常
- 4.2. 全局异常
- 4.3. 区别
- 总结
前言
在传统的机器学习中,局部异常因子(Local Outlier Factor,LOF)算法和孤立森林(Isolation Forest)算法都是常用的异常值检测算法。本文将简单介绍一下这两个算法。
一、局部异常因子算法(LOF)
1.1. 原理
该算法是一种用于异常检测的算法。它是基于密度的离群点检测方法,可以用来识别数据集中的异常数据点。
通过计算每个数据点与其周围邻域数据点的密度之比,来判断当前数据点是否为异常点。如果一个样本数据点的密度比邻域数据点相对较低,则该数据点可能是一个异常点。
算法的步骤如下:
-
对每个数据点计算其与其周围邻域数据点的距离。(周围邻域数据点由K最近邻给出)
-
对每个数据点计算其邻域密度,即与其邻域数据点的平均距离的倒数(即局部可达密度(LRD))
-
对于每个数据点,计算其局部异常因子(LOF)值,即其邻域数据点的邻域密度与该数据点的邻域密度之比的平均值。
-
根据LOF值判断每个数据点是否为异常点。(LOF值越大表示该数据点相对于其邻域数据点的密度越低,越有可能是一个异常点)
也就是说,对于一个样本数据点,先通过K最近邻找出其邻域数据点,计算其与邻域数据点的距离,再取距离平均值的倒数(即LRD),当LRD是一个较大的值时,说明平均距离较小,则可得出该数据点的邻域密度较大。
然后再其每个邻域数据点的LRD与该数据点的LRD相除,再计算平均值,得到的结果自然便是LOF值,当LOF值较大时,说明该数据点的局部密度相对于邻域数据点的局部密度较小。
LOF算法的优点是能够发现各种形状的异常点,并且对于不同密度区域内的异常点具有较好的鲁棒性。
LOF算法的结果是一个异常值得分,而不是二进制的异常值标记。可以根据得分的阈值来确定哪些观测值被认为是异常值。
1.2. 代码实现
from sklearn.neighbors import LocalOutlierFactor
import numpy as np
import pandas as pd
np.random.seed(0)
normal_data = np.random.normal(loc=0, scale=1, size=(100, 2))
outlier_data = np.random.normal(loc=10, scale=1, size=(10, 2))
#合并
data = np.concatenate((normal_data, outlier_data), axis=0)
data = pd.DataFrame(data= data,columns= ["x1","x2"])
lof = LocalOutlierFactor(n_neighbors= 20)
y_pred = lof.fit_predict(data)
data["lof"] = y_pred
#LOF统计离群点个数
print(data["lof"].value_counts())
1 96
-1 14
#print(data.query("lof == -1"))
#可视化
import matplotlib.pyplot as plt
plt.style.use("ggplot")
sc = plt.scatter(data.x1,data.x2,c= data.lof)
handles,labels = sc.legend_elements()
plt.legend(handles,labels)
plt.show()
当K最近邻值为较小的数时,如n_neighbors= 3,(可见异常点为数据集中两个区域的异常点,即局部异常点)
如图所示:
二、孤立森林(Isolation Forest)
2.1. 原理
孤立森林算法基于树的构建,通过将样本随机划分到树的不同分支中来检测异常值。
它和随机森林类似,但每一次选择划分属性和划分点时都是随机的,而不是根据信息增益和基尼指数来选择
算法步骤:
- 对于给定的样本集合,孤立森林算法首先随机选择一个特征和一个切割值,将样本划分到两个分支中。
- 然后,重复上述过程,递归地构建二叉树,直到每个叶子节点只包含一个样本或达到预定的树的最大深度。
- 最后,孤立森林算法根据样本在树中的路径长度来评估其异常程度。路径长度越短,表示样本点越异常。
路径长度越短,表示样本点在构建孤立森林时被更早地分离出来,与其他样本点的关联性较低(即距离主要的样本点的分布中心比较远),因此可以被认为是更异常的点。
其结果是二进制的异常值标记,-1表示异常值,1表示正常值。可根据需要调整contamination参数来控制异常值的比例。
2.2. 代码实现
np.random.seed(42)
from sklearn.ensemble import IsolationForest
outlier = IsolationForest(
n_estimators= 200,
contamination= 0.16,
random_state= 42
)
y_pred = outlier.fit_predict(data)
data["y_pred"] = y_pred
print(data["y_pred"].value_counts())
1 92
-1 18
#孤立森林可视化异常点
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
sns.scatterplot(
x = data["x1"],
y = data["x2"],
hue= data["y_pred"]
)
plt.show()
三、比较
-
LOF算法的计算复杂度较高,它需要计算每个数据点与其邻近点的距离,并计算密度比值。
孤立森林算法的计算复杂度相对较低,因为它只需要构建一棵二叉树,并计算路径长度。 -
LOF算法对于局部异常点的检测效果较好,可以识别出分布在不同密度区域的异常点。
孤立森林算法对于全局异常点的检测效果较好,可以快速识别出在整个数据集中与其他点关联性较低的异常点。
四、局部(全局)异常
局部异常和全局异常是异常点在数据集中的不同类型。
4.1. 局部异常
局部异常是指在数据集中相对于其周围邻近点而言,具有较低密度的点
这意味着局部异常点与其邻近点之间的距离较远,该点的密度较低。
局部异常点通常是在数据集中分布在不同密度区域的点,可能表示数据中的特殊情况或异常情况。
4.2. 全局异常
全局异常是指在整个数据集中相对于其他点而言,具有较低关联性的点
这意味着全局异常点与其他点之间的关联性较低,可能是数据集中的离群点或异常点。
全局异常点通常是在整个数据集中相对较少见的点,与其他点的关联性较弱。
4.3. 区别
局部异常点主要关注数据集中不同密度区域中的异常情况,而全局异常点主要关注整个数据集中与其他点关联性较低的异常情况。
这意味着局部异常点可能是数据集中特定区域的异常点,而全局异常点可能是整个数据集中的离群点。
总结
本文介绍了两个异常值检测算法:LOF和iForest算法,然后对它们进行了比较(前者主要关注数据集中不同密度区域的异常;后者则关注整个数据集中与其它点关联性较低的异常),LOF算法对局部异常点的检测较好,iForest算法对全局异常点的检测较好。最后简单介绍了一下局部与全局异常。
无名,天地之始;有名,万物之母。
–2023-9-10 筑基篇
星石传说: 我就是用的vs code插件Code Geex,或者通义灵码
阳洋杨~扬: 做的特别好,学习了。想请教你用的是哪个AI翻译工具?
°3: 可以发一下目录结构吗
MIhard160: 太优秀了 好有恒心 去哪读研啊
星石传说: 而且我在项目启动的博客里也放了GitHub链接