1. 程式人生 > >機器學習:貝葉斯網淺析(附程式碼實現)

機器學習:貝葉斯網淺析(附程式碼實現)

貝葉斯網的目的是為了從已知屬性推測其他未知屬性的取值。

貝葉斯網是描述屬性間依賴關係的有向無環圖,並使用概率分佈表描述屬性的聯合概率分佈。如下圖(A指向B表示B依賴於A):貝葉斯網由結構G和引數Θ組成,即B=<G,Θ>。Θ定量描述了屬性間的依賴關係,即Θ包含了每個屬性條件概率表。我們要做的就是構建一個儘量能準確反應屬性間依賴關係的貝葉斯圖。常使用“評分搜尋”。定義評分函式(稍後解釋):其中,|B|表示貝葉斯網引數的個數(所有條件概率表涉及的概率個數總和),f(θ)表示描述每個引數θ所需的位元組數,對f(θ)的不同取值,可以得到AIC和BIC評分函式:另外:其中(樣本x有d個屬性):以最開始的西瓜問題的貝葉斯網為例:
回頭看評分函式:第一項描述了編碼貝葉斯網所需的位元組數(越少越好),第二項LL(B|D)是貝葉斯網的對數釋然,即計算貝葉斯網B對應的概率分佈對資料集D描述的有多好(越大越好),於是,要構建一個好的貝葉斯網,就轉變為一個優化任務:尋找一個貝葉斯網使評分函式s(B|D)最小。然而,從所有可能的網路中尋找最優的貝葉斯網是一個NP難問題,難以快速解決,只能通過某些方法求解近似解。如K2演算法(g()是評分函式):matlab程式碼(仿K2演算法,基於BIC準則的評分函式):
%attrs:樣本屬性表,行為屬性(有序屬性,根據經驗對屬性排序,最有可能被依賴的屬性排在最前),列為樣本
%parents_limit:每個屬性最多依賴的屬性個數
%attrs_valid_num:每個屬性可能的取值數列表
function [parent_attrs] = createbnFunc(attrs,parents_limit,attrs_valid_num)
%屬性個數
attr_num = size(attrs,1);
%為每個屬性初始化空的依賴屬性(父節點)
parent_attrs = {};
for i=1:attr_num,
  parent_attrs{i} = [];
endfor;
%沒有任何依賴關係的評分
[min_score] = scoreFunc(parent_attrs,attrs,attrs_valid_num);
%為每個屬性搜尋依賴屬性
for i=1:attr_num,
  %在當前屬性之前的屬性中尋找依賴屬性,防止形成有環圖
  for j=1:i-1,
    len = length(parent_attrs{i});
    if len<parents_limit,
      %設定當前屬性依賴的屬性
      parent_attrs{i}(len+1) = j;
      %計算評分
      [score] = scoreFunc(parent_attrs,attrs,attrs_valid_num);
      if score<min_score,
        min_score = score;
      else
        %評分變高,刪掉這個依賴屬性,並且結束進一步搜尋當前屬性的依賴屬性
        parent_attrs{i}(len+1) = [];
        break;
      endif;
    else
      break;
    endif;
  endfor;
endfor;
評分函式(BIC準則):
function [score] = scoreFunc(parent_attrs,attrs,attrs_valid_num)

[rows cols] = size(attrs);
f = log(cols)/2;
b = 0;
%計算引數個數
for i=1:length(parent_attrs),
  if length(parent_attrs{i}) == 0,
    b = b + attrs_valid_num(i);
  else
    condition_num = 1;
    for j=1:length(parent_attrs{i}),
      condition_num = condition_num * attrs_valid_num(parent_attrs{i}(j));
    endfor;
    b = b + condition_num * attrs_valid_num(i);
  endif;
endfor;

%計算LL(B|D)
p = 0;
%樣本迴圈
for i=1:cols,
  x_p = 1;
  %當前樣本屬性迴圈
  for j=1:rows,
    %沒有依賴屬性
    if length(parent_attrs{j}) == 0,
      count = 0;
      for k=1:cols,
        if isequal(attrs{j,k},attrs{j,i}),
          count ++;
        endif;
      endfor;
      x_p = x_p * count / cols;
    else%有依賴屬性
      c_count = 0;
      count = 0;
      for k=1:cols,
        %滿足條件的樣本標記
        flag = true;
        for m=1:length(parent_attrs{j}),
          if ~isequal(attrs{parent_attrs{j}(m),i},attrs{parent_attrs{j}(m),k}),
            flag = false;
            break;
          endif;
        endfor;
        if flag,
          c_count ++;
        endif;
        if flag&&isequal(attrs{j,i},attrs{j,k}),
          count ++;
        endif;
      endfor;
      if c_count == 0,
        x_p = 0;
        break;
      else
        x_p = x_p * count / c_count;
      endif;
    endif;
  endfor;
  if x_p~=0,
    p = p + log(x_p);
  endif;
endfor;
%BIC準則評分
score = f * b - p;
多多指教~參考資料:周志華《機器學習》參考博文: