matlab 貝葉斯網絡學習

提綱:
最近工作:
    B-COURSE工具學習
    BNT研究與學習
    BNT相關實驗及結果
手動建立貝葉斯網及簡單推理
       參數學習
        結構學習
下一步工作安排
 
 
最近工作:
1.   B-COURSE 工具學習
B-COURSE是一個供教育者和研究者免費使用的web貝葉斯網絡工具。主要分爲依賴關係建模和分類器模型設計。輸入自己的研究數據,就可以利用該工具在線建立模型,並依據建立好的模型進行簡單推理。
B-COURSE要求數據格式是ASCII txt格式的離散數據,其中第一行是各種數據屬性變量,其餘各行則是採集的樣本,屬性變量值可以是字符串也可以是數據,屬性變量之間用製表符分割,缺失屬性變量值用空格代替。讀入數據後,在進行結構學習前,可以手動的選擇需要考慮的數據屬性!生成過程中,可以手動確定模型,確定好模型後,可以選擇JAVA playgroud,看到一個java applet程序,可以手動輸入相應證據,從而進行簡單推理。
B-COURSE的詳細使用介紹,可詳見[url]http://b-course.cs.helsinki.fi/obc/[/url]
B-COURSE工具隱藏了數據處理,算法實現等技術難點,所以對初學者來說,容易上手。但是卻不能夠針對不同的應用進行自主編程,缺乏靈活性。
2.   貝葉斯網工具箱BNT的研究與學習
基於matlab的貝葉斯網絡工具箱BNT是kevin p.murphy基於matlab語言開發的關於貝葉斯網絡學習的開源軟件包,提供了許多貝葉斯網絡學習的底層基礎函數庫,支持多種類型的節點(概率分佈)、精確推理和近似推理、參數學習及結構學習、靜態模型和動態模型。
   貝葉斯網絡表示:BNT中使用矩陣方式表示貝葉斯網絡,即若節點i到j有一條弧,則對應矩陣中(i,j)值爲1,否則爲0。
   結構學習算法函數:BNT中提供了較爲豐富的結構學習函數,都有:
1.     學習樹擴展貝葉斯網絡結構的TANC算法learn_struct_tan().
2.     數據完整條件下學習一般貝葉斯網絡結構的K2算法learn_struct_k2()、貪婪搜索GS(greedy search)算法learn_struct_gs()和爬山HC(hill climbing)算法learn_struct_hc()等。
3.     缺失數據條件下學習一般貝葉斯網絡結構的最大期望EM(expectation maximization)算法learn_struct_EM()和馬爾科夫鏈蒙特卡羅MCMC(Markov Chain Monte Carlo)learn_struct_mcmc()算法等。
參數學習算法函數:BNT中也提供了豐富的參數學習函數,都有:
1.  完整數據時,學習參數的方法主要有兩種:最大似然估計learn_params()和貝葉斯方法bayes_update_params();
2.  數據缺失時,如果已知網絡拓撲結構,用EM算法來計算參數,倘若未知網絡拓撲結構,使用結構最大期望SEM(structure EM)算法learn_struct_SEM()。
推理機制及推理引擎:爲了提高運算速度,使各種推理算法能夠有效應用,BNT工具箱採用了引擎機制,不同的引擎根據不同的算法來完成模型轉換、細化和求解。這個推理過程如下:
 
 
BNT中提供了多種推理引擎,都有:
1.  聯合樹推理引擎jtree_inf_engine();
2.  全局聯合樹推理引擎global_joint_inf_engine();
3.  信念傳播推理引擎 belprop_inf_engine();
4.  變量消元推理引擎 var_elim_inf_engine().
3.   使用BNT做的相關實驗及結果
u       手動建立貝葉斯網模型及簡單推理實驗:
1.     “草地潮溼原因模型”建立及推理:(全是離散變量)
%建立貝葉斯網絡結構並制定條件概率表
N = 4;  %四個節點 分別是cloudy,sprinkler,rain,wetgrass
dag = zeros(N,N);
C = 1; S = 2; R = 3; W = 4;
dag(C,[R S]) = 1; %節點之間的連接關係
dag(R,W) = 1;
dag(S,W) = 1;
discrete_nodes = 1:N; %離散節點
node_sizes = 2*ones(1,N);%節點狀態數
bnet =mk_bnet(dag,node_sizes,'names',{'cloudy','sprinkler','rain','wetgrass'},'discrete',discrete_nodes);    
bnet.CPD{C} = tabular_CPD(bnet,C,[0.5 0.5]);
bnet.CPD{R} = tabular_CPD(bnet,R,[0.8 0.2 0.2 0.8]);
bnet.CPD{S} = tabular_CPD(bnet,S,[0.5 0.9 0.5 0.1]);
bnet.CPD{W} = tabular_CPD(bnet,W,[1 0.1 0.1 0.01 0 0.9 0.9 0.99]);
%畫出建立好的貝葉斯網絡
figure
draw_graph(dag)
%選擇jtree_inf_engine推理引擎。
engine = jtree_inf_engine(bnet);
%輸入證據
evidence = cell(1,N);
evidence{R} = 2;
[engine, loglike] = enter_evidence(engine, evidence);
%計算單個節點後驗概率,即進行推理
marg1 = marginal_nodes(engine,S);
marg1.T
%計算對節點聯合後驗概率
marg2 = marginal_nodes(engine,[S R W]);
marg2.T
%給出“軟證據”,即節點的可能分佈概率情況下的推理
evidence{R} = [];
soft_evidence{R}=[0.6 0.4];
[engine, loglike] = enter_evidence(engine,evidence,'soft',soft_evidence);
marg3 = marginal_nodes(engine,S);
marg3.T
實驗結果:
1.貝葉斯網絡                             2.單個節點後驗概率                                 
3.多個節點後驗概率                        4.soft_evidence情況下的後驗概率
   
2.     焚化爐廠廢物排放模型建立及推理:(包含離散變量和連續變量)
這個實驗與第一個實驗不同的地方就是它所建立的貝葉斯網中的節點變量包含連續變量,在建立條件概率概率表時會有所不同,離散變量使用CPD構造器tabular_CPD,連續變量使用gaussian_CPD。這裏指給出這一部分的代碼:
bnet.CPD{B} = tabular_CPD(bnet,B,'CPT',[0.85 0.15]);
bnet.CPD{F} = tabular_CPD(bnet,F,'CPT',[0.95 0.05]);
bnet.CPD{W} = tabular_CPD(bnet,W,'CPT',[2/7 5/7]);
bnet.CPD{E} = gaussian_CPD(bnet,E,'mean',[-3.9 -0.4 -3.2 -0.5],'cov',[0.00002 0.0001 0.00002 0.0001]);
bnet.CPD{D} = gaussian_CPD(bnet,D,'mean',[6.5 6.0 7.5 7.0],'cov',[0.03 0.04 0.1 0.1],'weights',[1 1 1 1]);
bnet.CPD{C} = gaussian_CPD(bnet,C,'mean',[-2 -1],'cov',[0.1 0.3]);
bnet.CPD{L} = gaussian_CPD(bnet,L,'mean',3,'cov',0.25,'weights',-0.5);
bnet.CPD{Min} = gaussian_CPD(bnet, Min,'mean',[0.5 -0.5],'cov',[0.01 0.005]);
bnet.CPD{Mou}=gaussian_CPD(bnet,Mout,'mean',0,'cov',0.002,'weights',[1 1]);
貝葉斯網建立好後,推理部分和實驗一相似,這裏就不再討論。
實驗結果建立的貝葉斯網如下:
 
 
u       參數學習實驗:
這裏使用的例子依然是“草地潮溼原因模型”。首先我先如上面實驗那樣建立好貝葉斯網bnet,並手動構造條件概率表CPT。然後使用BNT裏的函數sample_bnet(bnet)來產生nsamples個數據樣本,nsamples分別取值20,200,2000。然後,再重新建立一個不知道條件概率表的貝葉斯網bnet2(結構和bnet相同),並把得到的樣本作爲訓練集代入learn_params()函數進行學習,把學習到的條件概率表CPT2與手動構造的CPT進行了比較。參數學習部分代碼:
nsamples = 20;
samples = cell(N, nsamples);
for i = 1:nsamples
    samples(:,i) = sample_bnet(bnet);
end
data = cell2num(samples);
bnet2 = mk_bnet(dag,node_sizes,'discrete',discrete_nodes);
seed = 0;
rand('state',seed);
bnet2.CPD{C} = tabular_CPD(bnet2,C);
bnet2.CPD{S} = tabular_CPD(bnet2,S);
bnet2.CPD{R} = tabular_CPD(bnet2,R);
bnet2.CPD{W} = tabular_CPD(bnet2,W);
bnet3 = learn_params(bnet2,data);
實驗結果:
手動給出的CPT         
nsamples=20        
nsamples=200      
nsamples=2000
查看網絡中節點條件概率的方法:
%查看節點C的條件概率
s = struct(bnet.CPD{C})
s.CPT

 
可以看出,隨着訓練樣本數的增加,學習到的條件概率表越來越逼近於手動給出的條件概率表。
u       結構學習實驗:
這裏我主要作了兩個實驗,一個是基於上面“草地潮溼原因模型”例子,首先手動建立好貝葉斯網bnet,然後使用函數sample_bnet(bnet)產生訓練樣本,制定節點順序和最大父親節點數,代入K2算法,進行結構學習,並比較了不同訓練樣本數(nsamples)的情況下,學習到的結構和實際結構的差異。實驗結果如下:
可以看出當樣本數達到一定的值以後,K2算法可以很好的建立出需要的貝葉斯網絡結構。
 
 
1.手動給出的結構                    2.nsamples=10
 
3.nsamples=20                         4.nsamples=30
 
另一個是根據葉進,林士敏的《基於貝葉斯網絡的推理在移動客戶中流失分析中的應用》提到的使用K2算法進行結構學習方法,通過手動構造相應數據,最後實現了該算法,成功實現了模型的建立,而且與論文中給出的模型比較接近。實驗部分代碼如下:
n = 6;
ns = [3,3,2,2,2,2];
names = {'A','B','C','D','E','class'};
A = 1; B = 2; C = 3; D = 4;E = 5; class = 6;
order = [4 5 6 3 2 1];
max_fan_in = 2;
result_matrix = zeros(ns(class),ns(class));
fn = 'e:/data.txt';
load(fn);
data_train1 = data';
[num_attrib num_cases] = size(data_train1);
data_train = zeros(num_attrib, num_cases);
dag = zeros(n,n);
dag = learn_struct_k2(data_train,ns,order,'max_fan_in',max_fan_in);%結構學習
bnet = mk_bnet(dag,ns);
priors = 1;
seed = 0;
rand('state', seed);
for i = 1:n
    bnet.CPD{i} = tabular_CPD(bnet,i,'CPT','unif','prior_type','dirichlet','dirichlet_type','BDeu','dirichlet_weight',priors);
end
bnet2 = bayes_update_params(bnet,data_train);%更新條件概率表
實驗結果如下,雖然比較接近作者給出的結構,但多了幾條邊,而且因爲訓練樣本是自己手動給出的,不是實際數據,所以學習到的條件概率表偏離較大。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章