使用for循环隔离森林异常分数

时间:2019-03-21 09:11:53

标签: r for-loop

我有一个由id变量分隔的不同组的数据集,我想计算并在数据框中添加异常分数。

这是一个包含三个公司的示例数据集,

set.seed(1234)

id1 <- rep(23, 60)
n1 <- rnorm(n = 60, mean = 100, sd = 5.2)
g1 <- rnorm(n = 60, mean = 200, sd = 8)

id2 <- rep(34, 60)
n2 <- rnorm(n = 60, mean = 500, sd = 110)
g2 <- rnorm(n = 60, mean = 800, sd = 160)

id3 <- rep(3, 60)
n3 <- rnorm(n = 60, mean = 50, sd = 11)
g3 <- rnorm(n = 60, mean = 80, sd = 16)

id <- c(id1, id2, id3)
n <- c(n1, n2, n3)
g <- c(g1, g2, g3)

df <- data.frame(id, n, g)
rm(list = ls() [!ls() %in% "df"])

第一个变量是公司id。每个公司有60个观测值。我要在每个公司上运行的代码如下。

library(isofor)
mod <- iForest(X = df, 50, 10)
anomalyscore <- predict(mod, df)
df <- data.frame(df, anomalyscore)

但是,要分别在每个公司上运行命令,我需要像这样的循环,

n <- 3
for (i in 1:n {
  mod <- iForest(X = df, 50, 10)
  anomalyscore <- predict(mod, df)
  df <- data.frame(df, anomalyscore)
}

问题1 我在上述循环中犯了什么错误?它要做的是创建三个异常评分而不是一个。我需要为每家公司分别计算一列异常分数。

问题2 假设我不知道每个公司的观察数,那么如何在循环中进行调整?

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

类似的事情应该起作用:

df$anomalyscore <- NA
library(dplyr)
for (i in unique(df$id)) {
    mod <- iForest(X = filter(df, id == i), 50, 10)
    anomalyscore <- predict(mod, filter(df, id == i))
    df$anomalyscore[df$id == i] <- anomalyscore
    rm(anomalyscore)
}

说明:

  
      
  • 添加具有NA值的字段anomalyscore
  •   
  • 迭代id并仅为此id生成分数
  •   
  • 为此ID更新anomalyscore
  •   

虽然这可以解决您的问题,但您应该查看purrr函数和dplyr以使用mutategroup_by在每个组上运行一个函数