8

我正在尝试使用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)

提前致谢!

4

3 回答 3

0

我觉得问题在于您在证据和事件中使用相同的变量。Learning.test 包含“C”变量的值。然后我们试图将 C 预测为事件。也许使用不包括 C 的原始数据集的子集就可以了

于 2021-08-06T11:26:32.760 回答
0

我不知道这是由于错误修复还是仅仅因为我尝试了另一种方法 - 无论如何,如果您在 cpquery 函数之外迭代地建立证据列表,则循环工作。

通过一个名为 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”进行更复杂的准备,但是一旦准备好,它就可以正常工作。

于 2018-05-07T09:56:33.397 回答
0

为避免范围问题,您可以推迟调用eval并在函数内部cpquery执行。如果您直接将evi(字符变量)传递给cpquery定义,然后在定义中对其进行解析,则环境链将被转移cpquery可以访问evi.

您可以使用m.cpquery <- edit(cpquery)fork 自己的函数版本,并在其开头插入以下行:

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.queryeval.

我应该说这是一个相当丑陋的解决方法。它仅在您使用逻辑采样( method='ls') 时才有效。但是如果你想使用似然加权,这个check.mutilated.evidence函数会报错。我还没有检查eval在调用之前注入表达式是否会导致后续错误的混乱导致地狱。

于 2016-10-02T13:22:20.033 回答