我正在尝试使用BNT和MATLAB实现朴素贝叶斯分类器。到目前为止,我一直坚持使用简单的tabular_CPD变量和变量的“猜测”概率。到目前为止,我的原型网络包括以下内容:

DAG = false(5);
DAG(1, 2:5) = true;
bnet = mk_bnet(DAG, [2 3 4 3 3]);
bnet.CPD{1} = tabular_CPD(bnet, 1, [.5  .5]);
bnet.CPD{2} = tabular_CPD(bnet, 2, [.1  .345   .45 .355   .45 .3]);
bnet.CPD{3} = tabular_CPD(bnet, 3, [.2  .02    .59 .2     .2  .39    .01 .39]);
bnet.CPD{4} = tabular_CPD(bnet, 4, [.4  .33333 .5  .33333 .1  .33333]);
bnet.CPD{5} = tabular_CPD(bnet, 5, [.5  .33333 .4  .33333 .1  .33333]);
engine = jtree_inf_engine(bnet);


在这里,变量1是我想要的输出变量,设置为最初为任一输出类别分配.5概率。

变量2-5为我测量的特征定义了CPD:


2是集群大小,范围从1到十几个或更大
3是一个比率,它将是大于等于1的实际值
4和5是标准偏差(实际)值(X和Y散点)


为了对候选聚类进行分类,我将所有特征量划分为3-4个范围括号,如下所示:

...
    evidence = cell(1, 5);
    evidence{2} = sum(M > [0 2 6]);
    evidence{3} = sum(O > [0 1.57 2 3]);
    evidence{4} = sum(S(1) > [-Inf 1 2]);
    evidence{5} = sum(S(2) > [-Inf 0.4 0.8]);
    eng = enter_evidence(engine, evidence);
    marginals = marginal_nodes(eng, 1);
    e = marginals.T(1);
...


考虑到我只是在范围括号和概率值上猜测,这实际上效果很好。但是我相信我应该在这里使用gaussian_CPD。我认为gaussian_CPD可以同时学习最佳括号和概率(均值和协方差矩阵及权重)。

我的问题是,我找不到如何使用BNT gaussian_CPD类的任何简单示例。例如,如何将gaussian_CPD初始化为与上述tabular_CPD变量之一大致相同的行为?

最佳答案

我最终通过在MATLAB命令提示符下尝试BNT来解决了这一问题。这是我使用gaussian_CPD节点定义分类器网络的方式:

DAG = false(5); DAG(1, 2:5) = true
bnet = mk_bnet(DAG, [2 1 1 2 1], 'discrete', 1);
bnet.CPD{1} = tabular_CPD(bnet, 1, 'prior_type', 'dirichlet');
for node = 2:5
   bnet.CPD{node} = gaussian_CPD(bnet, node);
end
bnet

DAG =

     0     1     1     1     1
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0

bnet =

               equiv_class: [1 2 3 4 5]
                    dnodes: 1
                  observed: []
                     names: {}
                    hidden: [1 2 3 4 5]
               hidden_bitv: [1 1 1 1 1]
                       dag: [5x5 logical]
                node_sizes: [2 1 1 2 1]
                    cnodes: [2 3 4 5]
                   parents: {[1x0 double]  [1]  [1]  [1]  [1]}
    members_of_equiv_class: {[1]  [2]  [3]  [4]  [5]}
                       CPD: {[1x1 tabular_CPD]  [1x1 gaussian_CPD]  [1x1 gaussian_CPD]  [1x1 gaussian_CPD]  [1x1 gaussian_CPD]}
             rep_of_eclass: [1 2 3 4 5]
                     order: [1 5 4 3 2]


为了训练它,我使用了原始的分类器来帮助我标记300个样本集,然后只需通过训练算法运行它们的2/3。

bnet = learn_params(bnet, lsamples);
CPD = struct(bnet.CPD{1}); % Peek inside CPD{1}
dispcpt(CPD.CPT);

1 : 0.6045
2 : 0.3955


dispcpt的输出大致给出了训练集中带标签的样本中的班级分配之间的细目分类。

为了测试新的分类器,我在原始和新的贝叶斯网络中同时运行了结果的最后1/3。这是我用于新网络的代码:

engine = jtree_inf_engine(bnet);
evidence = cell(1, 5);
tresults = cell(3, length(tsamples));
tresults(3, :) = tsamples(1, :);
for i = 1:length(tsamples)
    evidence(2:5) = tsamples(2:5, i);
    marginal = marginal_nodes(enter_evidence(engine, evidence), 1);
    tresults{1, i} = find(marginal.T == max(marginal.T)); % Generic decision point
    tresults{2, i} = marginal.T(1);
end
tresults(:, 1:8)

ans =

    [         2]    [     1]    [         2]    [         2]    [         2]    [     1]    [     1]    [     1]
    [1.8437e-10]    [0.9982]    [3.3710e-05]    [3.8349e-04]    [2.2995e-11]    [0.9997]    [0.9987]    [0.5116]
    [         2]    [     1]    [         2]    [         2]    [         2]    [     1]    [     1]    [     2]


然后找出是否有任何改进,我绘制了重叠的ROC图。事实证明,我的原始网络表现很好,很难确定使用高斯CPD训练的网络是否更好。打印ROC曲线下的区域说明新网的确确实表现稍好。 (base area是原始网络,而area是新网络。)

conf = cell2mat(tresults(2,:));
hit = cell2mat(tresults(3,:)) == 1;
[~, ~, basearea] = plotROC(baseconf, basehit, 'r')
hold all;
[~, ~, area] = plotROC(conf, hit, 'b')
hold off;

basearea =

    0.9371

area =

    0.9555




我将其发布在此处,以便下次需要执行此操作时,我将能够找到答案。希望其他人也可以找到它。

关于matlab - BNT gaussian_CPD的简单示例/用例?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10889298/

10-09 18:55