機器學習-ID3決策樹算法(附matlab/octave代碼)

ID3決策樹算法是基於信息增益來構建的,信息增益能夠由訓練集的信息熵算得,這裏舉一個簡單的例子node

data=[心情好 天氣好  出門算法

          心情好 天氣很差 出門3d

          心情很差 天氣好 出門blog

          心情很差 天氣很差 不出門]遞歸

前面兩列是分類屬性,最後一列是分類get

分類的信息熵能夠計算獲得:
出門=3,不出門=1,總行數=4
分類信息熵 = -(3/4)*log2(3/4)-(1/4)*log2(1/4)io

第一列屬性有兩類,心情好,心情很差function

心情好 ,出門=2,不出門=0,行數=2class

心情好信息熵=-(2/2)*log2(2/2)+(0/2)*log2(0/2)循環

同理

心情很差信息熵=-(1/2)*log2(1/2)-(1/2)*log2(1/2)

心情的信息增益=分類信息熵 - 心情好的機率*心情好的信息熵 - 心情很差的機率*心情很差的信息熵


 

由此能夠獲得每一個屬性對應的信息熵,信息熵最大的即爲最優劃分屬性。

仍是這個例子,加入最優劃分屬性爲心情

而後分別在心情屬性的每一個具體狀況下的分類是否所有爲同一種,若爲同一種則該節點標記爲此類別,

這裏咱們在心情好的狀況下無論什麼天氣結果都是出門因此,有了

心情很差的狀況下有不一樣的分類結果,繼續計算在心情很差的狀況下,其它屬性的信息增益,

把信息增益最大的屬性做爲這個分支節點,這個咱們只有天氣這個屬性,那麼這個節點就是天氣了,

天氣屬性有兩種狀況,以下圖

在心情很差而且天氣好的狀況下,若分類全爲同一種,則改節點標記爲此類別

有訓練集能夠,心情很差而且天氣好爲出門,心情很差而且天氣很差爲不出門,結果入下圖

對於分支節點下的屬性頗有可能沒有數據,好比,咱們假設訓練集變成

data=[心情好 晴天  出門

          心情好 陰天 出門

          心情好 雨天 出門

          心情好 霧天 出門

          心情很差 晴天 出門

          心情很差 雨天 不出門

          心情很差 陰天 不出門]

以下圖:

在心情很差的狀況下,天氣中並無霧天,咱們如何判斷霧天究竟是否出門呢?咱們能夠採用該樣本最多的分類做爲該分類,
這裏天氣很差的狀況下,咱們出門=1,不出門=2,那麼這裏將不出門,做爲霧天的分類結果

 

在此咱們全部屬性都劃分了,結束遞歸,咱們獲得了一顆很是簡單的決策樹。

下面附上個人實現ID3決策樹算法代碼:(octave/matlab,該程序本人已經驗證過能夠執行且結果正確,這裏屬性集我偷了一個懶,

沒有標識出具體屬性名,我是使用矩陣中的列號)

著名的還有C4.5決策樹算法,它是ID3的改進,做者都是同一我的,羅斯昆蘭

%生成決策樹ID3算法
%data:訓練集
%feature:屬性集
function [node] =createTree(data,feature)
  type=mostType(data);
  [m,n]=size(data);
  %生成節點node
  %value:分類結果,若爲null則表示該節點是分支節點
  %name:節點劃分屬性
  %type:節點屬性值
  %children:子節點
  node=struct('value','null','name','null','type','null','children',[]);
  temp_type=data(1,n);
  temp_b=true;
  for i=1:m
    if temp_type!=data(i,n)
      temp_b=false;
    end
  end
  %樣本中全爲同一分類結果,則node節點爲葉子節點
  if temp_b==true
    node.value=data(1,n);
    return;
  end
  %屬性集合爲空,將結果標記爲樣本中最多的分類
  if sum(feature)==0
    node.value=type;
    return;
  end
  feature_bestColumn=bestFeature(data);
  best_feature=getData()(:,feature_bestColumn);
  best_distinct=unique(best_feature);
  best_num=length(best_distinct);
  best_proc=zeros(best_num,2);
  best_proc(:,1)=best_distinct(:,1);
  %循環該屬性的每個值
  for i=1:best_num
    Dv=[];
    Dv_index=1;
    %爲node建立一個bach_node分支,設樣本data中改屬性值爲best_proc(i,1)的集合爲Dv
    bach_node=struct('value','null','name','null','type','null','children',[]);
    for j=1:m
      if best_proc(i,1)==data(j,feature_bestColumn)
        Dv(Dv_index,:)=data(j,:);
        Dv_index=Dv_index+1;
      end
    end
    %Dv爲空則將結果標記爲樣本中最多的分類
    if length(Dv)==0
      bach_node.value=type;
      bach_node.type=best_proc(i,1);
      bach_node.name=feature_bestColumn;
      node.children(i)=bach_node;
      return;
    else
      feature(feature_bestColumn)=0;
      %遞歸調用createTree方法
      bach_node=createTree(Dv,feature);
      bach_node.type=best_proc(i,1);
      bach_node.name=feature_bestColumn;
      node.children(i)=bach_node;
    end
  end
end

%獲取最優劃分屬性
function [column] = bestFeature(data)
  [m,n]=size(data);
  featureSize=n-1;
  gain_proc=zeros(featureSize,2);
  entropy=getEntropy(data);
  for i=1:featureSize
    gain_proc(i,1)=i;
    gain_proc(i,2)=getGain(entropy,data,i);
  end
  for i=1:featureSize
    if gain_proc(i,2)==max(gain_proc(:,2))
      column=i;
      break;
    end
  end
end

%計算樣本最多的結果
function [res] = mostType(data)
  [m,n]=size(data);
  res_distinct = unique(data(:,n));
  res_proc = zeros(length(res_distinct),2);
  res_proc(:,1)=res_distinct(:,1);
  for i=1:length(res_distinct)
    for j=1:m
      if res_proc(i,1)==data(j,n)
        res_proc(i,2)=res_proc(i,2)+1;
      end
    end
  end
  for i=1:length(res_distinct)
    if res_proc(i,2)==max(res_proc(:,2))
      res=res_proc(i,1);
      break;
    end
  end
end

%計算信息熵
function [entropy] = getEntropy(data)
  entropy=0;
  [m,n]=size(data);
  label=data(:,n);
  label_distinct=unique(label);
  label_num=length(label_distinct);
  proc=zeros(label_num,2);
  proc(:,1)=label_distinct(:,1);
  for i=1:label_num
    for j=1:m
      if proc(i,1)==data(j,n)
        proc(i,2)=proc(i,2)+1;
      end
    end
    proc(i,2)=proc(i,2)/m;
  end
  for i=1:label_num
    entropy=entropy-proc(i,2)*log2(proc(i,2));
  end
end

%計算信息增益
function [gain] = getGain(entropy,data,column)
  [m,n]=size(data);
  feature=data(:,column);
  feature_distinct=unique(feature);
  feature_num=length(feature_distinct);
  feature_proc=zeros(feature_num,2);
  feature_proc(:,1)=feature_distinct(:,1);
  f_entropy=0;
  for i=1:feature_num
    feature_data=[];
    feature_proc(:,2)=0;
    feature_row=1;
    for j=1:m
      if feature_proc(i,1)==data(j,column)
        feature_proc(i,2)=feature_proc(i,2)+1;
      end
      if feature_distinct(i,1)==data(j,column)
        feature_data(feature_row,:)=data(j,:);
        feature_row=feature_row+1;
      end
    end
    f_entropy=f_entropy+feature_proc(i,2)/m*getEntropy(feature_data);
  end
  gain=entropy-f_entropy;
相關文章
相關標籤/搜索