隨機森林分類(Random Forest Classification)


    其實,之前就接觸過隨機森林,但僅僅是用來做分類和回歸。最近,因為要實現一個idea,想到用隨機森林做ensemble learning才具體的來看其理論知識。隨機森林主要是用到決策樹的理論,也就是用決策樹來對特征進行選擇。而在特征選擇的過程中用到的是熵的概念,其主要實現算法有ID3和C4.5.下面我們先來看看決策樹。

    下面我們用一個例子具體的來說明


                                                     image

 

 

    我們要選取一個最好的特征來判斷是否貸款,上面給出了年齡,工作,房子,信貸四種特征。如果一種特征具有更好的分類能力,或者說,按照這一特征將訓練數據集分割成子集,使得各個子集是當前條件下最好的分類,我們就應該選擇這個特征。對於這個問題,直觀上是否有房子應該是最好的特征。但這也僅僅是從直觀上判斷,具體上來講哪個特征最好了,這里我們引入一個概念-信息增益。

    假設X是一個取值無限的離散隨機變量,其概率分布為:

image

    則其熵計算如下,這里我們把image定義為經驗熵。

image

    由於熵只依賴X的分布,而與X的取值無關。所以,我們又把熵定義為:
                                                                                    image

    假設我們有兩個隨機變量x,y(generally,X denote the feature vectors,and Y denote labels)。其聯合概率分布為:

image

    這里,假如給定一個X,要我們准確的判斷其所屬類別,也就是要准確的判斷Y。很自然的,我們需要求解給定X下的條件熵:

image

    假設,特征A 對訓練集D的信息增益為image,定義為集合D 的經驗熵H(D)與特征A給定條件下D的經驗熵H(D|A)之差,那么我們定義信息增益如下:

image

 

    一般的,我們把熵H(Y)與條件熵H(Y|X)只差定義為互信息,決策樹中的信息增益就是訓練數據集中的類與特征的互信息。下面給出計算信息增益的方法:

    image

                                                  image

                                                 image

    如果我們以信息增益為划分訓練數據集的特征,存在於選擇取值較多的特征的問題。這里我們使用信息增益比(information gain ratio),可以對這一問題進行校正。這是特征選擇的另一准則。

image

    下面來介紹一下ID3算法,該算法的核心就是不斷的利用信息增益准則選擇特征,最終達到分類的目的。

image

image

    C4.5算法其實就是在ID3算法上做了一點的改動,把特征選擇的方法改為用信息增益比來計算,而不用ID3中的計算信息增益的方法。其算法流程和ID3差不多,這里就不介紹了。下面來簡單的談一下決策樹的剪枝問題,由於決策樹是嚴格的按照一定的規則進行計算,過多的考慮了訓練樣本的正確性,所以這導致其容易過擬合。所以這里引入剪枝的概念,通過優化損失函數,減少模型的復雜性。具體算法過程可以看課本P-66~P-67頁。

    下面我給出C4.5的matlab代碼,改代碼轉自http://blog.csdn.net/ice110956/article/details/10049149

   1: function D = C4_5(train_features, train_targets, inc_node,test_features)
   2: %http://blog.csdn.net/ice110956/article/details/10049149
   3: % 1.train_features,為訓練集; train_targets,為訓練集標簽;
   4: % inc_node為防止過擬合參數,表示樣本數小於一定閾值結束遞歸,可設置為5-10;test_features為測試集。
   5: % 2.取消離散變量,上面說了,是因為我不知道如何處理Miss value的問題,至於影響,應該就是連貪心也算不上了吧,應該是一個理論上還過得去的處理方法。
   6: % 3.圖怎么畫?介紹幾個畫圖軟件:http://www.cnblogs.com/damonlan/archive/2012/03/29/2410301.html 
   7: % 決策樹擴展篇:http://blog.csdn.net/ice110956/article/details/29175215 
   8:  
   9: [Ni, M]        = size(train_features); %輸入向量為NI*M的矩陣,其中M表示訓練樣本個數,Ni為特征維數維數
  10: inc_node    = inc_node*M/100; 
  11:  
  12: disp('Building tree') 
  13: tree        = make_tree(train_features, train_targets, inc_node); 
  14:  
  15: %Make the decision region according to the tree %根據產生的數產生決策域
  16: disp('Building decision surface using the tree') 
  17: [n,m]=size(test_features);
  18: targets        = use_tree(test_features, 1:m, tree, unique(train_targets)); %target里包含了對應的測試樣本分類所得的類別數
  19:  
  20: D           = targets; 
  21: %END 
  22:  
  23: function targets = use_tree(features, indices, tree,  Uc) %target里包含了對應的測試樣本分類所得的類別
  24:  
  25:  
  26: targets = zeros(1, size(features,2)); %1*M的向量
  27:  
  28: if (tree.dim == 0) 
  29:    %Reached the end of the tree 
  30:    targets(indices) = tree.child; 
  31:    return %child里面包含了類別信息,indeces包含了測試樣本中當前測試的樣本索引
  32: end 
  33:          
  34:  
  35: dim = tree.dim; %當前節點的特征參數
  36: dims= 1:size(features,1); %dims為1-特征維數的向量
  37:  
  38:    %Discrete feature 
  39:    in                = indices(find(features(dim, indices) <= tree.split_loc)); %in為左子樹在原矩陣的index
  40:    targets        = targets + use_tree(features(dims, :), in, tree.child_1, Uc); 
  41:    
  42:    in                = indices(find(features(dim, indices) >  tree.split_loc)); %in為右子樹在原矩陣的index
  43:    targets        = targets + use_tree(features(dims, :), in, tree.child_2, Uc); 
  44: return 
  45:       
  46:  
  47: function tree = make_tree(features, targets, inc_node) 
  48:  
  49: [Ni, L]                        = size(features); 
  50: Uc                             = unique(targets); %UC表示類別數
  51: tree.dim                        = 0; %樹的維度為0
  52: %tree.child(1:maxNbin)    = zeros(1,maxNbin); 
  53:  
  54: if isempty(features), %如果特征為空,退出
  55:    return 
  56: end 
  57:  
  58: %When to stop: If the dimension is one or the number of examples is small 
  59: if ((inc_node > L) | (L == 1) | (length(Uc) == 1)), %剩余訓練集只剩一個,或太小,小於inc_node,或只剩一類,退出
  60:    H                    = hist(targets, length(Uc)); %返回類別數的直方圖
  61:    [m, largest]     = max(H); %更大的一類,m為大的值,即個數,largest為位置,即類別的位置
  62:    tree.child         = Uc(largest); %直接返回其中更大的一類作為其類別
  63:    return
  64: end 
  65:  
  66: %Compute the node's I 
  67: %計算現有的信息量(經驗熵)
  68: for i = 1:length(Uc), 
  69:     Pnode(i) = length(find(targets == Uc(i))) / L; 
  70: end 
  71: Inode = -sum(Pnode.*log(Pnode)/log(2)); 
  72:  
  73: %For each dimension, compute the gain ratio impurity 
  74: %This is done separately for discrete and continuous features 
  75: delta_Ib    = zeros(1, Ni); 
  76: S=[];
  77: for i = 1:Ni, 
  78:    data    = features(i,:); 
  79:    temp=unique(data); 
  80:       P    = zeros(length(Uc), 2); 
  81:        
  82:       %Sort the features 
  83:       [sorted_data, indices] = sort(data); 
  84:       sorted_targets = targets(indices); 
  85:        %結果為排序后的特征和類別
  86:       %Calculate the information for each possible split 
  87:       I    = zeros(1, L-1); 
  88:       
  89:       for j = 1:L-1, 
  90:          for k =1:length(Uc), 
  91:             P(k,1) = length(find(sorted_targets(1:j)         == Uc(k))); %p(1,1):小於第j個樣本的b的個數,p(1,2):大於第j個樣本的b的個數。
  92:             P(k,2) = length(find(sorted_targets(j+1:end) == Uc(k)));    %p(2,1):小於第j個樣本的g的個數,p(1,2):大於第j個樣本的g的個數。
  93:          end 
  94:          Ps        = sum(P)/L; %兩個子樹的權重 
  95:          temp1=[P(:,1)]; 
  96:          temp2=[P(:,2)]; 
  97:          fo=[Info(temp1),Info(temp2)];
  98:          %info    = sum(-P.*log(eps+P)/log(2)); %兩個子樹的I
  99:          I(j)    = Inode - sum(fo.*Ps);%信息增益    
 100:       end 
 101:       [delta_Ib(i), s] = max(I); 
 102:       S=[S,s];
 103:    
 104: end
 105:  
 106: %Find the dimension minimizing delta_Ib  
 107: %找到最大的划分方法
 108: [m, dim] = max(delta_Ib); %第dim維特征最好,最大信息增益為m
 109:  
 110: dims        = 1:Ni; 
 111: tree.dim = dim; 
 112:  
 113: %Split along the 'dim' dimension 
 114: %分裂樹 
 115:    %Continuous feature 
 116:    [sorted_data, indices] = sort(features(dim,:)); 
 117:    %tree.split_loc        = split_loc(dim); 
 118:    %disp(tree.split_loc);
 119:    S(dim)
 120:    indices1=indices(1:S(dim))
 121:    indices2=indices(S(dim)+1:end)
 122:    tree.split_loc=sorted_data(S(dim))
 123:    tree.child_1        = make_tree(features(dims, indices1), targets(indices1), inc_node); 
 124:    tree.child_2        = make_tree(features(dims, indices2), targets(indices2), inc_node); 
 125: %D = C4_5_new(train_features, train_targets, inc_node);

    其實代碼不難,下面我給出我的理解。

P50724-095915

    Here we split the data into two sets,with 300 training samples and 51 testing samples,each data is a 34-dimensional vector. Here, each dimension can  be regarded as a variable,with respect to a kind of “feature”.

    在這個決策樹中,對每個節點我們計算它的信息增益比,如果信息增益比小於某個閾值。或者,節點包含的樣本數小於18(自己設定),則結束遞歸。從上圖中可以看出,從根節點出發(這個節點包含300個樣本),第5維特征最好,所以用這個特征進行划分。得到左子樹(57個樣本全為“1”),右子樹(包含243個樣本)。所以左子樹結束遞歸,接着計算右子樹的特征,第27維特征最好。一直循環….

    最后我們得到這樣的一個決策樹,除了葉節點,中間節點都包含一個最佳分類的特征,和這個特征對應的特征值。每個葉節點包含一定數量的樣本,葉節點的類別規定為多數樣本對應的類別。得到了這樣的一個決策樹后,我們就可以對測試樣本進行分類了。使用中間節點記錄的特征對測試樣本進行划分,直到測試樣本划分到每個葉節點中。葉節點中樣本的類別就是該測試樣本的類別了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM