Использование функции 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, поможет