2013-10-08 19 views
5

Tôi đang cố gắng sử dụng bnlearnpackage để tính toán xác suất có điều kiện và tôi đang gặp sự cố khi chức năng "cpquery" được sử dụng trong vòng lặp. Tôi đã tạo một ví dụ, được hiển thị bên dưới, sử dụng dữ liệu đi kèm với gói. Khi sử dụng hàm cpquery trong một vòng lặp, một biến được tạo trong vòng lặp ("evi" trong ví dụ) không được hàm nhận biết. Tôi nhận được lỗi:Sử dụng bnlearn Chức năng "cpquery" Trong vòng lặp

Error in parse(text = evi) : object 'evi' not found 

Các bước tạo "evi" dựa trên các ví dụ do tác giả cung cấp.

Bất kỳ trợ giúp nào bạn có thể cung cấp đều tuyệt vời. Tôi đang tuyệt vọng để tìm một cách mà tôi có thể áp dụng các chức năng cpquery cho một số lượng lớn các quan sát.

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) 

Cảm ơn bạn trước!

+1

Tôi đã liên lạc với tác giả của gói bnlearn và có vẻ như lỗi tôi nhận được là do vấn đề phạm vi với chức năng cpquery. Điều này hiển nhiên khi tôi có thể nhận hàm cpquery hoạt động đúng trong vòng lặp for được xây dựng _outside_ của hàm do người dùng định nghĩa, nhưng có lỗi khi cùng một vòng lặp được sử dụng _inside_ của người dùng định nghĩa chức năng. –

Trả lời

0

Để tránh sự cố phạm vi, bạn có thể trì hoãn cuộc gọi đến eval và thực hiện bên trong chức năng cpquery. Nếu bạn trực tiếp vượt qua evi (biến ký tự) thành cpquery và sau đó phân tích cú pháp trong định nghĩa, chuỗi môi trường được được chuyểncpquery sẽ có quyền truy cập evi.

Bạn có thể sử dụng m.cpquery <- edit(cpqurey) đến ngã ba phiên bản của riêng bạn của hàm và chèn dòng sau ngay từ đầu của nó:

evidence = parse(text = evidence) 

và sau đó lưu chức năng mới của bạn. Vì vậy, các tiêu đề của m.cpquery sẽ trông giống như:

> m.cpquery 
function (fitted, event, evidence, cluster = NULL, method = "ls", 
    ..., debug = FALSE) 
{ 
    evidence = parse(text = evidence) 
    check.fit(fitted) 
    check.logical(debug) 
... 

Bây giờ bạn có thể sử dụng m.cpquery trong chức năng của riêng bạn như trước đây, ngoại trừ chúng tôi sẽ vượt qua biến nhân vật đồng bằng với nó:

a[i] <- m.cpquery(network, (C=='c'), evi) 

Lưu ý rằng trong dòng đầu tiên của m.cpquery, chúng tôi chỉ phân tích cú pháp biến ký tự bằng chứng và không gọi số eval trên đó. cpquery là giao diện người dùng đối với conditional.probability.query (xem here) và chúng tôi đang dựa vào cuộc gọi tiếp theo của conditional.probability.query tới eval.

Tôi nên nói rằng đây là giải pháp khá xấu. Và nó chỉ hoạt động nếu bạn đang sử dụng lấy mẫu logic (method='ls'). Nhưng nếu bạn muốn sử dụng khả năng trọng số, chức năng check.mutilated.evidence sẽ làm tăng lỗi. Tôi đã không kiểm tra nếu tiêm một biểu thức eval trước khi nó được gọi là sẽ dẫn đến một tình trạng lộn xộn của các lỗi tiếp theo dẫn đến địa ngục.

Các vấn đề liên quan