0
votes

I am trying to implement decision tree with recursion: So far I have written the following:

  1. From a give data set, find the best split and return the branches, to give more details lets say I have data with features as columns of matrix and last column indicate the class of the data 1, -1.
  2. Based on 1. I have a best feature to split along with the branches under that split, lets say based on Information gain I get feature 9 is the best split and unique values in feature 9 {1,3,5} are the branches of 9
  3. I have figured how to get the data related to ach branch, then I need to iterate over each branch's data to get the next set of split. I am having trouble figuring this recursion.

Here is the code that I have so far, the recursion that I am doing right now doesn't look right: How can I fix this?

function [indeces_of_node, best_split] = split_node(X_train, Y_train)

    %cell to save split information
    feature_to_split_cell = cell(size(X_train,2)-1,4);

    %iterate over features
    for feature_idx=1:(size(X_train,2) - 1)
        %get current feature
        curr_X_feature = X_train(:,feature_idx);

        %identify the unique values
        unique_values_in_feature = unique(curr_X_feature);

        H = get_entropy(Y_train); %This is actually H(X) in slides
        %temp entropy holder

        %Storage for feature element's class
        element_class = zeros(size(unique_values_in_feature,1),2);

        %conditional probability H(X|y)
        H_cond = zeros(size(unique_values_in_feature,1),1); 

        for aUnique=1:size(unique_values_in_feature,1)
            match = curr_X_feature(:,1)==unique_values_in_feature(aUnique);
            mat = Y_train(match);
            majority_class = mode(mat);
            element_class(aUnique,1) = unique_values_in_feature(aUnique);
            element_class(aUnique,2) = majority_class;
            H_cond(aUnique,1) = (length(mat)/size((curr_X_feature),1)) * get_entropy(mat);
        end

        %Getting the information gain
        IG = H - sum(H_cond);

        %Storing the IG of features
        feature_to_split_cell{feature_idx, 1} = feature_idx;
        feature_to_split_cell{feature_idx, 2} = max(IG);
        feature_to_split_cell{feature_idx, 3} = unique_values_in_feature;
        feature_to_split_cell{feature_idx, 4} = element_class;
    end
    %set feature to split zero for every fold
    feature_to_split = 0;

    %getting the max IG of the fold
    max_IG_of_fold = max([feature_to_split_cell{:,2:2}]);

    %vector to store values in the best feature
    values_of_best_feature = zeros(size(15,1));

    %Iterating over cell to get get the index and the values under best
    %splited feature.
    for i=1:length(feature_to_split_cell)
        if (max_IG_of_fold == feature_to_split_cell{i,2});
            feature_to_split = i;
            values_of_best_feature = feature_to_split_cell{i,4};
        end
    end
    display(feature_to_split)
    display(values_of_best_feature(:,1)')

    curr_X_feature = X_train(:,feature_to_split);

    best_split = feature_to_split
    indeces_of_node = unique(curr_X_feature)

    %testing
    for k = 1 : length(values_of_best_feature)
        % Condition to stop the recursion, if clases are pure then we are
        % done splitting, if both classes have save number of attributes
        % then we are done splitting.
        if (sum(values_of_best_feature(:,2) == -1) ~= sum(values_of_best_feature(:,2) == 1))
            if((sum(values_of_best_feature(:,2) == -1) ~= 0) || (sum(values_of_best_feature(:,2) == 1) ~= 0))
                mat1 = X_train(X_train(:,5)== values_of_best_feature(k),:);
                [indeces_of_node, best_split] = split_node(mat1, Y_train);
            end
        end
    end
end

Here is the out of my code: and looks like some in my recursion I am only going depth of one branch and after that I never go back to rest of the branches

feature_to_split =

     5


ans =

     1     2     3     4     5     6     7     8     9


feature_to_split =

     9


ans =

     3     5     7     8    11


feature_to_split =

    21


feature_to_split =

    21


feature_to_split =

    21


feature_to_split =

    21

if you are interest in running this code: git

1
You say it "Doesn't look right", what problem are you encountering specifically? Perhaps you can give a sample of output and compare it to expected output?Dennis Jaheruddin
Please don't paste duplicate questionsslayton
@slayton You request the other question to be close, so I cleared the question and put the steps and ask again. If you don't want to help someone by answering question please let other help. This is community forum goal is to find an answer to a problem that someone is unable to do it. People help the community by answering the question. People leave forums simply because things like this.add-semi-colons
@Null-Hypothesis stackoverflow isn't a message forum. Its a question and answer site. Duplicate questions get closed all the time even if they are posted by different authors. If you feel like your old question is bad and isn't getting answers you should edit your old question. If you feel that a new question is necessary then by all means post a new question but either delete the old question or explain why you feel a new question is merited. Re-asking questions on SO is considered very bad form by the SO community (not just by me)slayton

1 Answers

0
votes

After multiple rounds of debug, I figured the answers, I hope someone will benefit from this:

for k = 1 : length(values_of_best_feature)
    % Condition to stop the recursion, if clases are pure then we are
    % done splitting, if both classes have save number of attributes
    % then we are done splitting.
    if((sum(values_of_best_feature(:,2) == -1) ~= 0) || (sum(values_of_best_feature(:,2) == 1) ~= 0))
        X_train(:,feature_to_split) = [];
        mat1 = X_train(X_train(:,5)== values_of_best_feature(k),:);
        %if(level >= curr_level)
        split_node(mat1, Y_train, 1, 2, level-1);
        %end
    end

end
return;