【问题标题】:Using bnlearn Function "cpquery" Within a Loop在循环中使用 bnlearn 函数“cpquery”
【发布时间】:2013-10-16 03:16:06
【问题描述】:

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

提前致谢!

【问题讨论】:

  • 我已经与 bnlearn 包的作者联系,我收到的错误似乎是由于 cpquery 函数的范围问题。当我能够让 cpquery 函数在用户定义函数的 outside 构造的 for 循环中正常工作时,这一点很明显,但是当相同的 for 循环是在用户定义函数的内部中使用。
  • 我在循环中遇到了与 cpquery 类似的问题,一个对我有用的快速解决方法是在 cpquery 调用之前包含一行 evi &lt;&lt;- evi。这定义了全局环境中的变量。
  • 我想你的问题在这里解决了:stackoverflow.com/questions/44676501/…

标签: r probability bayesian-networks


【解决方案1】:

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

【讨论】:

  • 您能否提供示例代码以了解其工作原理?
【解决方案2】:

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

您可以使用m.cpquery &lt;- 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的第一行,我们只解析了证据字符变量,并没有调用evalcpqueryconditional.probability.query 的前端(参见here),我们依赖conditional.probability.queryeval 的后续调用。

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

【讨论】:

    【解决方案3】:

    我不知道这是由于错误修复还是仅仅因为我尝试了另一种方法 - 无论如何,如果您在 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”进行更复杂的准备,但一旦准备好,它就可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-27
      • 2020-01-18
      • 2020-06-03
      • 1970-01-01
      • 1970-01-01
      • 2022-10-21
      • 2017-11-24
      • 2020-02-14
      相关资源
      最近更新 更多