【发布时间】:2021-05-25 02:32:49
【问题描述】:
我正在使用 R 编程语言,我正在尝试了解以下用于异常值检测的函数的详细信息:https://rdrr.io/cran/dbscan/src/R/LOF.R
此函数(来自“dbscan”库)使用局部异常值因子 (LOF) 算法计算异常值:https://en.wikipedia.org/wiki/Local_outlier_factor。
LOF 算法是一种无监督的基于距离的算法,它定义数据集中相对于观测值的“可达性和邻域”的异常值。通常,相对于其附近的其他观测值而言,不是“非常可达”的观测值被认为是“异常值”。基于这些属性(用户指定这些属性,例如邻域(用“k”表示)可以是“3”),该算法为数据集中的每个点分配一个 LOF“分数”。给定观测值的 LOF 分数越大,该观测值被认为是异常值。
现在,我试图更好地理解 dbscan::lof() 函数中发生的一些计算。
1)基本的LOF算法可以在一些人工创建的数据上运行,如下所示:
```#load library(dbscan)
par(mfrow = c(1,2))
#generate data
n <- 100
x <- cbind(
x=runif(10, 0, 5) + rnorm(n, sd=0.4),
y=runif(10, 0, 5) + rnorm(n, sd=0.4)
)
### calculate LOF score
lof <- lof(x, k=3)
### distribution of outlier factors
summary(lof)
hist(lof, breaks=10)
### point size is proportional to LOF
plot(x, pch = ".", main = "LOF (k=3)")
points(x, cex = (lof-1)*3, pch = 1, col="red") ```
我的问题是:“k”值越大,识别出的异常值越少(直方图左偏),但识别出的异常值越“极端”(即 LOF 分数越大)?
我观察到了这种一般模式,但我不确定这种趋势是否反映在 LOF 算法代码中。例如
#plot LOF results for different values of k
par(mfrow = c(2,2))
### calculate LOF score
lof <- lof(x, k=3)
### distribution of outlier factors
summary(lof)
hist(lof, main = "k = 3",breaks=10)
### calculate LOF score
lof <- lof(x, k=10)
### distribution of outlier factors
summary(lof)
hist(lof, main = "k = 10", breaks=10)
### calculate LOF score
lof <- lof(x, k=20)
### distribution of outlier factors
summary(lof)
hist(lof, main = "k = 20", breaks=10)
### calculate LOF score
lof <- lof(x, k=40)
### distribution of outlier factors
summary(lof)
hist(lof, main = "k = 10", breaks=40)
在上图中,您可以看到随着“k”值的增加,识别出的异常值越少。这是正确的吗?
2) 是否有一种“最佳”方式为 LOF 算法选择“k”值?看到 LOF 算法如何,在我看来并没有一种“最佳”方式来选择“k”的值。看来你必须参考1)中描述的逻辑:
-
“k”值越大,识别出的异常值越少,但 识别出的异常值更“极端”
-
较小的“k”值会导致识别出更多的异常值,但 识别出的异常值不那么“极端”
这是正确的吗?
【问题讨论】:
-
有谁知道如何从这个链接中获取答案:stats.stackexchange.com/questions/138675/… ... 并编写等效的 R 代码?
标签: r algorithm data-science histogram outliers