ID3很不錯的講解(matlab程序實現)


1)決策樹之ID3

決策樹算法是分類算法的一種,基礎是ID3算法,C4.5、C5.0都是對ID3的改進。ID3算法的基本思想是,選擇信息增益最大的屬性作為當前的分類屬性。

看Tom M. Mitchell老師的《Machine Learing》第三章中的例子:

我們先解釋一下這張表,表中有14條實例數據,就是我們的訓練數據,其中 Outlook,Temperature,Humidity ,Wind 稱作條件屬性PlayTennis 稱作是決策屬性(標簽)

每一個屬性都有各自的值記做:Value(Outlook)={Sunny,OverCast,Rain},Value(Temperature)={Hot,Mild,Cool},Value(Humidity)={High,Normal},Value(Wind)={Strong,Weak},Value(PlayTennis)={NO,Yes}。

第一個重要的概念:Entropy。

我們數一下  決策屬性PlayTennis,一共有兩個類別:Yes,No。Yes的實例數是 9,No的實例數是 5。計算決策屬性的Entropy(熵):計算結果為:0.940286

這里的決策屬性S的值只有兩個值(Yes,No),當然可以有多個值(s1,s2,s3,...,sk),這些決策屬性的值的概率分別為:p1,p2,p3,...,pk所以決策屬性的Entroy的計算公式:

第二個重要的概念:information gain(信息增益)

我們只拿Outlook條件屬性舉例,其他的屬性一樣:

Value(Outlook)={Sunny,OverCast,Rain}:Outlook是sunny的實例數為5(其中Yes的個數為2,No的個數為3),占總的實例數為5/14,那么針對sunny的Entropy:

Entropy(Sunny)=,計算結果為:0.97095

Outlook是OverCast的實例數為4(其中Yes的個數為4,No的個數為0),占總的實例數為4/14,那么針對Overcast的Entropy:

,計算結果為:0

Outlook是Rain的實例數為5(其中Yes的個數為3,No的個數為2),占總的實例數為5/14,那么針對Rain的Entropy,

,計算結果為:0.97095

那么最后針對Outlook條件屬性的information gain為:

,計算結果為:0.24675

所以針對某一條件屬性的information gain為:

        

那么其他三個條件屬性Temperature、Humidity、Wind的信息增益為:

我們看到Outlook的信息增益是最大的,所以作為決策樹的一個根節點。即:

 

然后,從Outlook下面出來三個樹枝,最左邊的Sunny,我們從Outlook是Sunny的實例數據中,找到信息增益最大的那一個,依次類推。
(注釋:http://blog.csdn.net/mmc2015/article/details/42525655;而下面程序本人寫的)
clc;
clear all;
close all;


%% 導入數據
%data = [1,1,1;1,1,1;1,0,0;0,1,0;0,1,0];

data = [0,2,0,0,0;
    0,2,0,1,0;
    1,2,0,0,1;
    2,1,0,0,1;
    2,0,1,0,1;
    2,0,1,1,0;
    1,0,1,1,1;
    0,1,0,0,0;
    0,0,1,0,1;
    2,1,1,0,1;
    0,1,1,1,1;
    1,1,0,1,1;
    1,2,1,0,1;
    2,1,0,1,0];
% data = {'sunny','hot','high','week','no';
%              'sunny','hot','high','strong','no';
%              'overcast','hot','high','week','yes';
%              'rain','midd','high','week','yes';
%              'rain','cool','nomal','week','yes';
%              'rain','cool','nomal','strong','no';
%              'overcast','cool','nomal','strong','yes';
%              'sunny','midd','high','week','no';
%              'sunny','cool','nomal','week','yes';
%              'rain','midd','nomal','week','yes';
%              'sunny','midd','nomal','strong','yes';
%              'overcast','midd','high','strong','yes';
%              'overcast','hot','nomal','week','yes';
%              'rain','midd','high','strong','no'};
%sunuy-0,overcast-1,rain-2;--hot-2,midd-1,cool-2---high-0,nomal-1--week-0,strong-1,no-0,yes-1

%% 生成決策樹
make_tree(data);

function  make_tree(train_data)
%input                 train_data          訓練數據
%output               

[m,n] = size(train_data);
disp('original data');
disp(train_data);
class_list = train_data(:,n);
class_first = 1;

for i = 2:m
   if train_data(i,n) ==  class_list(1,:)
%    if strcmp(train_data(i,n),class_list(1,:))
        class_first = class_first + 1;
    end
end

%% 退出程序條件
if class_first == m || n == 1
    disp('final data');
    disp(train_data);
    return;
end

%% 建立決策樹
bestfeat = choose_bestfeat(train_data);

disp(['bestfeature:',num2str(bestfeat)]);

featvalue = unique(train_data(:,bestfeat));

featvalue_num = length(featvalue);

for i = 1:featvalue_num
    make_tree(splitData(train_data,bestfeat,featvalue(i,:)));
    disp('--------------------------------------------');
end
end

function [best_feature] = choose_bestfeat(data)
%input                 data                        輸入數據
%output               bestfeature             選擇特征值

[m,n] = size(data);
feature_num = n - 1;
baseentropy = calc_entropy(data);

best_gain = 0;
best_feature = 0;

%% 挑選最佳特征位
for j =1:feature_num
    feature_temp = unique(data(:,j));
    num_f = length(feature_temp);
    new_entropy = 0;
    for i = 1:num_f
        subSet = splitData(data, j, feature_temp(i,:));
        [m_s,n_s] = size(subSet);
        prob = m_s./m;
        new_entropy = new_entropy + prob * calc_entropy(subSet);
    end
    inf_gain = baseentropy - new_entropy;
    if inf_gain > best_gain
        best_gain = inf_gain;
        best_feature = j;
    end
end
end

function [entropy] = calc_entropy(train_data)
%input                 train_data          訓練數據
%output               entropy             熵值

[m,n] = size(train_data);

%% 得到類的項並統計每個類的個數
label_value = train_data(:,n);
label = unique(label_value);
label_number = zeros(length(label),2);
label_number(:,1) = label';
for i = 1:length(label)
    label_number(i,2) = sum(label_value == label(i));
end

%% 計算熵值
label_number (:,2) = label_number(:,2) ./ m;
entropy = 0;
entropy = sum(-label_number(:,2).*log2 (label_number(:,2)));

end

function [subSet] = splitData(data, j, value)
%input                 data              訓練數據
%input                  j                   對應第j個屬性
%input                 value             第j個屬性對應的特征值
%output               sunset              熵值

subSet = data;
subSet(:,j) = [];
k = 0;
for i = 1:size(data,1)
    if data(i,j) ~= value
        subSet(i-k,:) =[];
        k = k + 1;
    end
end
end

function [subSet] = splitData(data, j, value)
%input                 data              訓練數據
%input                  j                   對應第j個屬性
%input                 value             第j個屬性對應的特征值
%output               sunset              熵值

subSet = data;
subSet(:,j) = [];
k = 0;
for i = 1:size(data,1)
    if data(i,j) ~= value
        subSet(i-k,:) =[];
        k = k + 1;
    end
end
end

 


免責聲明!

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



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