在循环中使用bnlearn函数“cpquery”

时间:2013-10-08 23:51:53

标签: r probability bayesian-networks

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

提前致谢!

3 个答案:

答案 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的第一行,我们只解析了证据字符变量,并且没有在其上调用cpqueryconditional.probability.queryconditional.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 的原始数据集的子集可以解决问题