使用 Kevin Murphy 的贝叶斯网络工具箱学习稀疏数据

问题描述

我在使用使用 Kevin Murphy's Bayesian Network Toolbox(以下称为 BNT)训练的贝叶斯网络的学习参数时遇到问题。

最终我想将训练好的参数导出到 Python 中的另一个包,例如 pgmpy。当我这样做时,我注意到局部条件属性的总和不等于 1。实际上,如果在不满足此条件的情况下尝试使用贝叶斯网络进行预测,则 pgmpy 会抛出错误

我认为这是由于在稀疏数据上使用 BNT 学习参数造成的,其中一些变量的估值实际上并未出现在数据中。最初,我在使用期望最大化和结树算法训练的带有隐藏变量的复杂网络中遇到了这个问题。但是,我可以使用简单的马尔可夫链和最大似然估计 (MLE) 重现相同的问题。在这个例子中,我们定义了一个网络来采样一些测试数据。然后我们创建该网络的新版本,并使用不会出现在测试数据中的新“虚构”状态。

O=1:2; % We have 2 observable nodes O(1) and O(2)

node_sizes=repelem(2,2);
%   initially both variables have just two states,but this will change later
num_nodes=length(node_sizes);
onodes=O;

dag=false(num_nodes,num_nodes);
dag(1,2)=true; % O(1) -> O(2)

ix2var = string({'o1','o2'});

seed=42;
rand('state',seed);
randn('state',seed);

% the initial network that will create some test data
bnet = mk_bnet(dag,node_sizes,'names',cellstr(ix2var),'observed',onodes);

% set some arbitrary probabilities to get some test data
bnet.CPD{O(1)} = tabular_CPD(bnet,O(1),'CPT',[0.2,0.8]);
bnet.CPD{O(2)} = tabular_CPD(bnet,O(2),[0.3,0.7,0.6,0.4]);

N = length(onodes);
nsamples = 200;
samples = cell(N,nsamples);
for i=1:nsamples
  samples(:,i) = sample_bnet(bnet);
end

node_sizes=repelem(3,2); % introduce the imaginary state into our observable variables

% redefined the network with the new imaginary states
bnet = mk_bnet(dag,onodes);

% initialise the CPTs to uniform distributions prior to training
bnet.CPD{O(1)} = tabular_CPD(bnet,O(1));
bnet.CPD{O(2)} = tabular_CPD(bnet,O(2));

% learn parameters using MLE
bnet = learn_params(bnet,samples);

% copy CPT parameters to cpts
cpts=cell(num_nodes);
for i = 1:num_nodes
    cpts{i} = struct(bnet.CPD{i}).CPT;
end

% Now check Sigma(i=1..3)(P(O(2)_i)| O(1)=3) == 1 
%sum(cpts{O(2)}(3,:))
% ans =
% 
%      0
% Oh no! It's zero!

所以我的问题是:

  1. BNT 工作正常吗?我不是打算在稀疏数据上训练它吗?
  2. 如果我想将这些参数加载到另一个包中,我是否可以将这些“空”分布设置为均匀分布,即所有系数均为 1/n,其中 n 是变量可以采用的状态数?

PS 我对此感到困扰的一件事是,如果以小批量方式进行学习,那么学习过程似乎会完全忘记一些局部条件概率,因为特定值没有出现在数据集中。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)