我正在尝试使用bnlearn package来计算条件概率,而我在循环中使用"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)
提前致谢!
答案 0 :(得分:0)
为避免确定范围问题,您可以将调用推迟到cpquery
,并在<{em>} 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
的前端(请参阅here),我们依赖于eval
随后对method='ls'
的调用。
我应该说这是一个相当丑陋的解决方法。它只适用于使用逻辑采样(check.mutilated.evidence
)的情况。但是如果你想使用似然加权,eval
函数会引发错误。我没有检查在被调用之前注入Task t = new Task(() => TimeSpan.FromSeconds(10));
t.Start();
表达式是否会导致后续错误导致地狱的混乱。
答案 1 :(得分:0)
我不知道这是由于错误修正还是因为我尝试了另一种方法 - 无论如何,如果你在cpquery-function之外迭代地建立证据列表,循环就会起作用。
通过名为evidenceData的列表进行迭代的示例,其中包含所有正面证据:
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”准备工作,但是一旦准备好了,它就可以正常工作。
答案 2 :(得分:0)
我觉得问题在于您在证据和事件中使用了相同的变量。 Learning.test 包含“C”变量的值。然后我们试图将 C 预测为事件。也许使用不包括 C 的原始数据集的子集可以解决问题