Использование функции bnlearn "cpquery" в цикле

Я пытаюсь использовать пакет bnlearn для вычисления условных вероятностей и сталкиваюсь с проблемой, когда в цикле используется функция "cpquery". Я создал пример, показанный ниже, используя данные, включенные в пакет. При использовании функции cpquery в цикле переменная, созданная в цикле (в данном случае "evi"), не распознается функцией. Я получаю ошибку:

Error in parse(text = evi) : object 'evi' not found

Этапы создания "evi" основаны на примерах, предоставленных автором.

Любая помощь, которую вы могли бы оказать, была бы великолепна. Я отчаянно пытаюсь найти способ применения функции cpquery для большого количества наблюдений.

library(bnlearn)
data(learning.test)
fitted = bn.fit(hc(learning.test), learning.test)

bn.function <- function(network, evidence_data) {
  a <- NULL
  b <- nrow(evidence_data)
  for (i in 1:b) {
    evi <- paste("(", names(evidence_data), "=='",
               sapply(evidence_data[i,], as.character), "')",
               sep = "", collapse = " & ")
    a[i] <- cpquery(network, (C=='c'), eval(parse(text=evi)))
  }
  return(a)
}

test <- bn.function(fitted, learning.test)

Заранее спасибо!

3 ответа

Я не знаю, происходит ли это из-за ошибки или просто потому, что я попробовал другой подход - в любом случае, цикл работает, если вы итеративно создаете список доказательств вне функции cpquery.

Пример итерации по списку под названием очевидные данные с полностью положительными доказательствами:

for(i in names(evidenceData)){
  loopEvidenceList <- list()
  loopEvidenceList[[i]] <- "TRUE"
  a =cpquery(fitted = bayesNet, event = queryNode == "TRUE", 
             evidence = loopEvidenceList, method = "lw", n = 100000)
  print(a)
  }

В зависимости от того, каким образом ваши доказательства доступны, вам может потребоваться более сложная подготовка "loopEvidenceList", но как только вы подготовите его, он будет работать нормально.

Чтобы избежать проблемы с ограничением, вы можете отложить вызов eval и сделать это внутри cpquery функция. Если вы проходите прямо evi (символьная переменная) в cpquery а затем проанализировать его внутри определения, цепочка окружений сдвигается и cpquery будет иметь доступ к evi,

Ты можешь использовать m.cpquery <- edit(cpquery) раскошелиться на собственную версию функции и вставить следующую строку в ее начало:

evidence = parse(text = evidence)

и затем сохраните вашу новую функцию.

Итак, заголовок m.cpquery будет выглядеть так:

> m.cpquery
function (fitted, event, evidence, cluster = NULL, method = "ls", 
    ..., debug = FALSE) 
{
    evidence = parse(text = evidence)
    check.fit(fitted)
    check.logical(debug)
...

Теперь вы можете использовать m.cpquery в вашей собственной функции, как раньше, за исключением того, что мы передадим ей переменную простого символа:

a[i] <- m.cpquery(network, (C=='c'), evi)

Обратите внимание, что в первой строке m.cpqueryмы только проанализировали символьную переменную доказательства и не вызывали eval в теме. cpquery это интерфейс conditional.probability.query (см. здесь), и мы полагаемся на conditional.probability.queryпоследующий призыв к eval,

Я должен сказать, что это довольно уродливый обходной путь. И это работает только если вы используете логическую выборку (method='ls'). Но если вы хотите использовать вероятностное взвешивание, то check.mutilated.evidence Функция выдаст ошибку. Я не проверял, вводит ли eval Выражение перед вызовом может привести к хаосу последующих ошибок, ведущих в ад.

Я чувствую, что проблема в том, что вы используете одну и ту же переменную как в свидетельстве, так и в событии. Learning.test содержит значения переменной "C". затем мы пытаемся предсказать C как событие. Возможно, использование подмножества исходного набора данных, исключая C, поможет

Другие вопросы по тегам