igrigorik / decisiontree

ID3-based implementation of the ML Decision Tree algorithm
1.44k stars 130 forks source link

export ruleset to ruby conditional blocks and method #22

Closed newx closed 10 years ago

newx commented 10 years ago

Generated ruby code example: \ this editor removes original code's indentation

def classify(hunger, happiness) if (hunger >= 4.5 and happiness >= 4.0) then 'angry' elsif (hunger >= 4.5 and happiness < 4.0) then 'not angry' elsif (hunger < 4.5) then 'not angry' else nil end end

def classify(hunger, color) if (hunger == 'no') then 'not angry' elsif (hunger == 'yes' and color == 'blue') then 'not angry' elsif (hunger == 'yes' and color == 'red') then 'angry' else nil end end

newx commented 10 years ago

@igrigorik do you think it is good enough? Let me know if you have any comment on it... thanks

igrigorik commented 10 years ago

Silly question.. Have you verified that this works for nested trees?

newx commented 10 years ago

@igrigorik Do you have an example of nested trees? I'm not sure if you mean "bagging". So if you point me an example of nested tree I'll test it and work on it if it breaks :)

igrigorik commented 10 years ago

@newx any tree with multiple variables would do the trick. For example, the one in this post: https://www.igvita.com/2007/04/16/decision-tree-learning-in-ruby/

newx commented 10 years ago

@igrigorik unfortunately it breaks with multiple variables ): . But I'll work on it. Thanks

newx commented 10 years ago

@igrigorik here it goes. This is my first interaction to make it work with nested trees (or value ranges). Now it works and generates the code below. Let me know if you think something that can be improved or is just wrong. Thanks...

def my_classify_method(age, education, income, marital_status) if ((age.to_f >= 18 and age.to_f <= 35)) then 'will not buy' elsif ((age.to_f >= 36 and age.to_f <= 55) and marital_status == 'married') then 'will not buy' elsif ((age.to_f >= 36 and age.to_f <= 55) and marital_status == 'single') then 'will buy' elsif (age.to_f <= 18) then 'will buy' elsif (age.to_f >= 55) then 'will buy' else nil end end

igrigorik commented 10 years ago

I'm not sure this makes sense.. You shouldn't be looking for "value ranges". The range is an arbitrary and opaque attribute (i.e. it's just a string). The code generator should be a recursive function that generates a nested if that matches the output decision tree. E.g:

image

igrigorik commented 10 years ago

(feel free to reopen once/if previous comments are addressed)