I have some output from Weka that looks like this:
fac_a < 64
| fac_d < 71.5
| | fac_a < 49.5
| | | fac_d < 23.5 : 19.44 (13/43.71) [13/77.47]
| | | fac_d >= 23.5 : 24.25 (32/23.65) [16/49.15]
| | fac_a >= 49.5 : 30.8 (10/17.68) [5/22.44]
| fac_d >= 71.5 : 33.6 (25/53.05) [15/47.35]
fac_a >= 64
| fac_d < 83.5
| | fac_a < 91
| | | fac_e < 93.5
| | | | fac_d < 45 : 31.9 (16/23.25) [3/64.14]
| | | | fac_d >= 45
| | | | | fac_e < 21.5 : 44.1 (5/16.58) [2/21.39]
| | | | | fac_e >= 21.5
| | | | | | fac_a < 77.5 : 33.45 (4/2.89) [1/0.03]
| | | | | | fac_a >= 77.5 : 39.46 (7/10.21) [1/11.69]
| | | fac_e >= 93.5 : 45.97 (2/8.03) [1/107.71]
| | fac_a >= 91 : 42.26 (9/9.57) [4/69.03]
| fac_d >= 83.5 : 47.1 (9/30.24) [6/40.15]
I want to add a column onto my dataset (in MSSQL) that gives me the classification prediction of the response variable based on these rules. It's relatively easy to convert the above into a set of n
queries (where n
is leaf count on my tree) where the WHERE
clause is auto-generated from the branch information:
-- Rule 1
UPDATE table_name
SET prediction=value1
WHERE
fac_a < 64 AND
fac_d < 71.5 AND
fac_a < 49.5 AND
fac_d < 23.5
;
-- Rule 2
UPDATE table_name
SET prediction=value2
WHERE
fac_a < 64 AND
fac_d < 71.5 AND
fac_a < 49.5 AND
fac_d >= 23.5
;
etc. for each rule
But this doesn't scale well when I have complex trees (ca. 100 leaf nodes) and 100,000+ rows. Is there a design pattern for the SQL query that can apply this tree classification that will allow me to calculate the prediction more efficiently?
Here's a thought: put the rules into a hierarchical table, then package the lookup in a recursive user-defined scalar function. See below. (For some reason, SQL Fiddle isn't happy with the user-defined function, but I tested it on SQL Server 2012, and it should work on 2008.)
It's fast on the sample data you provided and a 1000-row table of facts. At the least, it might be easier to manage than what you have now. There are also variations on this approach that might be better, but see what you think.
If your decision tree is over 100 levels deep (or if you didn't populate the table of rules correctly), you'll hit the default recursion depth limit of 100 for functions. This can be changed with OPTION (MAXRECURSION 0) for no limit or OPTION (MAXRECURSION 32767) or less for a higher limit.