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;