有没有办法计算隔离森林中观测级别的特征重要性?

Sid*_*wal 5 r anomaly-detection

我正在 R 中使用隔离森林对多变量数据执行异常检测。

我尝试计算异常分数以及计算该分数时各个指标的贡献。我能够获得异常分数,但在计算指标重要性时面临问题。

我能够通过 BigML(在线平台)获得所需的结果,但不能通过 R 获得。

R代码:

> library(solitude) # tried 'IsolationForest' and 'h2o' but not getting desired result
> mo = isolation_forest(data)
> final_scores <- predict(mo,data)
> summary(mo)
     Length Class  Mode
forest 14     ranger list

> head(final_scores,5)
[1] 0.4156554 0.3923926 0.4262782 0.4595296 0.4174865
Run Code Online (Sandbox Code Playgroud)

BigMl 的输出: 在此输入图像描述

我想通过 R 代码获取每个指标(a、b、c、d)的重要性值,就像我在 BigML 中得到的一样

我想我错过了一些基本参数。实际上我是 R 新手,所以我无法弄清楚。

我想到了一些方法来获得观察级别的特征重要性,但我在实现它时遇到了问题。

这是我正在计划的片段。

指标中的点是单独的观察结果,而线是根据特定变量进行分割的。

我能够追踪森林中的单棵树,但问题是森林中有 500 棵树,追踪单棵树并获取它们的重要性值是不切实际的。下面的示例纯粹基于虚拟数据。

在此输入图像描述

单棵树的输出:

> x = treeInfo(mo$forest,tree=3)
> x
   nodeID leftChild rightChild splitvarID splitvarName  splitval terminal prediction
1       0         1          2          2            c 0.6975663    FALSE         NA
2       1         3          4          1            b 0.3455875    FALSE         NA
3       2         5          6          0            a 0.2620023    FALSE         NA
4       3         7          8          0            a 0.1425075    FALSE         NA
5       4         9         10          0            a 0.6611566    FALSE         NA
6       5        NA         NA         NA         <NA>        NA     TRUE         10
7       6        NA         NA         NA         <NA>        NA     TRUE          2
8       7        NA         NA         NA         <NA>        NA     TRUE          6
9       8        NA         NA         NA         <NA>        NA     TRUE          1
10      9        NA         NA         NA         <NA>        NA     TRUE          3
11     10        NA         NA         NA         <NA>        NA     TRUE          5
Run Code Online (Sandbox Code Playgroud)

任何形式的帮助表示赞赏。

小智 1

可以使用 Lime 包来估计局部特征的重要性。

library(solitude)
library(lime)
Run Code Online (Sandbox Code Playgroud)

首先,一些玩具数据:

set.seed(1234)
data<-data.frame(rnorm(20,0,1),rnorm(20,0,0.5))
colnames(data)<-c("x","y")
row.names(data)<-seq(1,nrow(data),1)
Run Code Online (Sandbox Code Playgroud)

看看玩具数据:

plot(data)
text(data-0.05,row.names(data))
Run Code Online (Sandbox Code Playgroud)

这些案例似乎是异常值:

outliers<-c(4,20) 
Run Code Online (Sandbox Code Playgroud)

种植隔离林:

model<-isolation_forest(data, importance="impurity")
Run Code Online (Sandbox Code Playgroud)

由于 Lime 不支持 solitude,因此我们需要构建两个函数,以便 Lime 可以处理 solitude 对象。model_type 函数告诉 Lime 我们有什么样的模型。Predict_model 函数使 Lime 能够对孤独对象进行预测。

model_type.solitude <- function(x, ...) {
  return("regression")
}

predict_model.solitude <- function(x, newdata, ...) {
  pred <- predict(x, newdata)
  return(as.data.frame(pred))
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以生成石灰对象并估计观察级别特征重要性(并且可以将排列数量设置得更高以获得更可靠的结果):

lime1 <- lime(data, model)
importance <- data.frame(explain(data, lime1,
                             n_features = 2,n_permutations = 500 ))
Run Code Online (Sandbox Code Playgroud)

特征重要性为importance$feature_weight。逐例检查结果:

importance[importance$case %in% outliers,c("case","feature","feature_weight")]
Run Code Online (Sandbox Code Playgroud)

阴谋:

plot_features(importance[importance$case %in% outliers,] , ncol = 2)
Run Code Online (Sandbox Code Playgroud)

希望这有帮助!

当然,请仔细阅读石灰,因为它基于某些假设。