1

BNT 및 MATLAB을 사용하여 Naive Bayes 분류기를 구현하려고합니다. 지금까지 나는 단순한 tabular_CPD 변수와 변수에 대한 "guesstimating"확률을 고수했습니다. 내 프로토 타입 그물 지금까지 다음과 같이 구성BNT gaussian_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 중 출력 클래스에 0.5 확률을 할당하는 설정 내 원하는 출력 변수입니다.

변수 2-5 기능 CPDS는 I 측정 정의

  • 2 1 다스 범위, 클러스터 크기보다
  • 3 실제 값하는 비율> = 1
  • 4와 5는 내가 지금처럼, 3-4 범위 괄호로 기능 측정의 모든 휴식 후보 클러스터를 분류하기 위해 표준 편차 (실제) 값 (X와 Y 분산)

있습니다 :

... 
    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입니다. I gaussian_CPD이 최적의 괄호와 확률 (평균 및 공분산 행렬 및 가중치)을 모두 습득 할 수 있다고 생각합니다.

제 문제는 BNT gaussian_CPD 클래스의 사용 방법에 대한 예가 입니다. 예를 들어, 위의 tabular_CPD 변수 중 하나와 거의 동일한 동작으로 gaussian_CPD을 초기화하는 방법은 무엇입니까?

답변

2

결국 나는 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/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을 실행했습니다. 내가 그려 어떤 개선 ROC 다이어그램을 중첩이 있다면

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] 

그런 다음 알아낼 : 여기가 새 그물에 사용되는 코드입니다. 그것이 나왔을 때, 원래의 그물은 충분히 훌륭했기 때문에 Gaussian 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 

ROC Diagram

내가 여기를 게시하도록하겠습니다 .

1

다음은 BNT 도구 상자를 사용하여 순진한 Bayes Net을 작성하는 방법을 보여주는 완전한 예제입니다. cars dataset의 하위 집합을 사용하고 있습니다. 그것은 이산 속성과 연속 속성을 모두 포함합니다.

편의상 통계 도구 상자가 필요한 몇 가지 기능을 사용하고 있습니다. 마지막으로

%# build samples as cellarray 
data = num2cell(cell2mat(struct2cell(D)')'); 

%# split train/test: 1/3 for testing, 2/3 for training 
cv = cvpartition(D.Origin, 'HoldOut',1/3); 
trainData = data(:,cv.training); 
testData = data(:,cv.test); 
testData(1,:) = {[]}; %# remove class 

:

%# info about the nodes 
nodeNames = fieldnames(D); 
numNodes = numel(nodeNames); 
node = [nodeNames num2cell((1:numNodes)')]'; 
node = struct(node{:}); 
dNodes = [node.Origin node.Cylinders node.Model_Year]; 
cNodes = [node.MPG node.Weight node.Acceleration]; 
depNodes = [node.MPG node.Cylinders node.Weight ... 
      node.Acceleration node.Model_Year]; 

vals = cell(1,numNodes); 
vals(dNodes) = cellfun(@(f) unique(D.(f)), nodeNames(dNodes), 'Uniform',false); 
nodeSize = ones(1,numNodes); 
nodeSize(dNodes) = cellfun(@numel, vals(dNodes)); 

%# DAG 
dag = false(numNodes); 
dag(node.Origin, depNodes) = true; 

%# create naive bayes net 
bnet = mk_bnet(dag, nodeSize, 'discrete',dNodes, 'names',nodeNames, ... 
    'observed',depNodes); 
for i=1:numel(dNodes) 
    name = nodeNames{dNodes(i)}; 
    bnet.CPD{dNodes(i)} = tabular_CPD(bnet, node.(name), ... 
     'prior_type','dirichlet'); 
end 
for i=1:numel(cNodes) 
    name = nodeNames{cNodes(i)}; 
    bnet.CPD{cNodes(i)} = gaussian_CPD(bnet, node.(name)); 
end 

%# visualize the graph 
[~,~,h] = draw_graph(bnet.dag, nodeNames); 
hTxt = h(:,1); hNodes = h(:,2); 
set(hTxt(node.Origin), 'FontWeight','bold', 'Interpreter','none') 
set(hNodes(node.Origin), 'FaceColor','g') 
set(hTxt(depNodes), 'Color','k', 'Interpreter','none') 
set(hNodes(depNodes), 'FaceColor','y') 

이제 우리는 교육/시험에 데이터를 분할 :

%# load dataset 
D = load('carsmall'); 

%# keep only features of interest 
D = rmfield(D, {'Mfg','Horsepower','Displacement','Model'}); 

%# filter the rows to keep only two classes 
idx = ismember(D.Origin, {'USA' 'Japan'}); 
D = structfun(@(x)x(idx,:), D, 'UniformOutput',false); 
numInst = sum(idx); 

%# replace missing values with mean 
D.MPG(isnan(D.MPG)) = nanmean(D.MPG); 

%# convert discrete attributes to numeric indices 1:mx 
[D.Origin,~,gnOrigin] = grp2idx(cellstr(D.Origin)); 
[D.Cylinders,~,gnCylinders] = grp2idx(D.Cylinders); 
[D.Model_Year,~,gnModel_Year] = grp2idx(D.Model_Year); 

다음으로 우리는 우리의 그래픽 모델을 구축 :

우리는 데이터 집합을 준비하여 시작 우리는 훈련 세트로부터 매개 변수를 학습하고 테스트 데이터의 클래스를 예측합니다 :

%# training 
bnet = learn_params(bnet, trainData); 

%# testing 
prob = zeros(nodeSize(node.Origin), sum(cv.test)); 
engine = jtree_inf_engine(bnet);   %# Inference engine 
for i=1:size(testData,2) 
    [engine,loglik] = enter_evidence(engine, testData(:,i)); 
    marg = marginal_nodes(engine, node.Origin); 
    prob(:,i) = marg.T; 

end 
[~,pred] = max(prob); 
actual = D.Origin(cv.test)'; 

%# confusion matrix 
predInd = full(sparse(1:numel(pred),pred,1)); 
actualInd = full(sparse(1:numel(actual),actual,1)); 
conffig(predInd, actualInd);    %# confmat 

%# ROC plot and AUC 
figure 
[~,~,auc] = plotROC(max(prob), pred==actual, 'b') 
title(sprintf('Area Under the Curve = %g',auc)) 
set(findobj(gca, 'type','line'), 'LineWidth',2) 

결과 :

confusion matrix ROC plot

naive bayes net 우리가 CPT를 추출하고 각각의 노드/시그마 의미 :

cellfun(@(x)dispcpt(struct(x).CPT), bnet.CPD(dNodes), 'Uniform',false) 
celldisp(cellfun(@(x)struct(x).mean, bnet.CPD(cNodes), 'Uniform',false)) 
celldisp(cellfun(@(x)struct(x).cov, bnet.CPD(cNodes), 'Uniform',false))