Есть ли способ вычислить важность объекта на уровне наблюдения в изолированном лесу?

#r #anomaly-detection

#r #обнаружение аномалий

Вопрос:

Я использую изолированный лес в 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
  

Вывод из BigML :
введите описание изображения здесь

Я хочу получить значения важности для каждой метрики (a, b, c, d) с помощью R-кода, точно так же, как я получаю в 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
  

Приветствуется любая помощь.

Ответ №1:

Важность локального объекта можно оценить с помощью пакета lime.

 library(solitude)
library(lime)
  

Во-первых, некоторые игрушечные данные:

 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)
  

Взгляните на данные игрушки:

 plot(data)
text(data-0.05,row.names(data))
  

Эти случаи кажутся выбросами:

 outliers<-c(4,20) 
  

Создать изолированный лес:

 model<-isolation_forest(data, importance="impurity")
  

Поскольку уединение не поддерживается в lime, нам нужно создать две функции
чтобы lime мог обрабатывать одиночные объекты. Функция 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))
}
  

Затем мы можем сгенерировать объект lime и оценить важность объекта на уровне наблюдения (и количество перестановок может быть установлено выше для более надежных результатов):

 lime1 <- lime(data, model)
importance <- data.frame(explain(data, lime1,
                             n_features = 2,n_permutations = 500 ))
  

Важность объекта выражается в importance$feature_weight.
Выборочная проверка результатов:

 importance[importance$case %in% outliers,c("case","feature","feature_weight")]
  

График:

 plot_features(importance[importance$case %in% outliers,] , ncol = 2)
  

Надеюсь, это полезно!

Конечно, ознакомьтесь с lime, поскольку он основан на определенных предположениях.

Комментарии:

1. Я думаю, что ranger — это реализация для случайного леса, но я использую изолированный лес, также я пытался использовать его, но это не сработало

2. Я не имел в виду предлагать вам использовать другой пакет. Вы пытались вставить параметр важность = «примесь» в свой код?

3. Отредактировал ответ и добавил игрушечный пример.

4. В вашем примере есть 10 экземпляров a, b и c. Я даже получаю за это 10 баллов аномалий, но почему только 1 строка значений важности. Он должен давать 10 значений важности, верно? оценка = прогноз (a, данные). [1] 0.4873994 0.4873994 0.5412548 0.4873994 0.5833292 0.4873994 0.5174812 0.4323802 0.5833292 0.4873994

5. Показатель важности показывает, насколько данный объект (a, b c в примере) влияет на результат вашего прогноза. Таким образом, одни и те же значения важности применяются для каждой строки в вашем прогнозе.