A decision node is a branching point in a tree. In a predictive decision tree, the root and internal decision nodes test feature conditions to divide observations into subsets; leaf nodes hold predictions. In a decision-analysis tree, a decision node instead marks a choice between actions. These trees share a branching shape but serve different purposes: one predicts from data, while the other evaluates choices under uncertainty. section 6.3.6 section 10.2
Read each kind of node according to its tree:
- For classification, follow the condition satisfied by an observation from the root through internal nodes to a leaf prediction. Training selects splits that reduce node impurity; evaluation uses held-out data rather than the training paths alone. section 6.3.6 section 6.5
- For a choice, follow an action branch from the decision node to chance nodes and their possible payoffs. Probabilities belong to chance-event branches, not to the available actions. Interpret the finished tree backward from outcomes to the initial choice. section 10.2 section 10.2.1
To assess a classification split, count the classes on each side of its condition, calculate Gini impurity separately for those subsets, then combine the impurities using their row counts as weights. A useful split separates classes; its displayed condition also explains how an observation proceeds through the tree. Numeric and categorically encoded features can both supply conditions. section 6.3.6
Two branches, two purposes
For fourth-down conversion prediction, a condition such as PLAY_TYPE <= 0.5 routes running plays to one side and passing plays to the other; the training counts are 175 conversions and 64 failures for running plays, versus 160 conversions and 219 failures for passing plays. For a contract choice, a root decision node offers two teams. One offer has a $120 million payoff; the other leads through health and performance-incentive chance nodes. Those latter branches require probabilities and payoffs, not a classifier’s Gini score. section 6.3.6 section 10.2.1
>>> to_go_less_than_3_5 = \
>>> train_data[train_data['TO_GO'] <= 3.5] #1
>>> to_go_greater_than_3_5 = \
>>> train_data[train_data['TO_GO'] > 3.5] #2
>>> counts_less_than_3_5 = (to_go_less_than_3_5 \
>>> .groupby('CONVERT').size()) #3
>>> print('Counts for TO_GO <= 3.5:') #4
>>> print(counts_less_than_3_5) #5
>>> counts_greater_than_3_5 = (to_go_greater_than_3_5 \
>>> .groupby('CONVERT').size()) #6
>>> print('Counts for TO_GO > 3.5:') #7
>>> print(counts_greater_than_3_5) #8
Counts for TO_GO <= 3.5:
CONVERT
0 127
1 268
dtype: int64
Counts for TO_GO > 3.5:
CONVERT
0 156
1 67
dtype: int64
The Python split on TO_GO shows how to check the class counts on both sides of a numeric decision-node condition before interpreting it. section 6.3.6
>>> stays_healthy_payoff = (0.10 * 90000000 +
>>> 0.20 * 120000000 +
>>> 0.70 * 150000000) #1
>>> does_not_stay_healthy_payoff = (0.40 * 90000000 +
>>> 0.30 * 120000000 +
>>> 0.30 * 150000000) #2
>>> dodgers_expected_payoff = (0.75 * stays_healthy_payoff +
>>> 0.25 * does_not_stay_healthy_payoff -
>>> agent_fees) #3
>>> dodgers.name += (f'\nExpected Payoff: \
>>> f"${dodgers_expected_payoff:,.0f}') #4
>>> stays_healthy.name += (f'\nExpected Payoff: '
>>> f'${stays_healthy_payoff:,.0f}') #5
>>> does_not_stay_healthy.name += (f'\nExpected Payoff: '
>>> f'${does_not_stay_healthy_payoff:,.0f}') #6
The payoff calculation shows how chance-node outcomes are weighted and carried back toward a contract decision node, with agent fees deducted. section 10.2.1
For a choice tree, draft the node hierarchy before plotting it: label decisions and chance events, list every branch and payoff, and check that probabilities leaving each chance node sum to 1. A Python tree can then store the hierarchy with anytree nodes and display it with Matplotlib. Distinct labels or colors help keep decision and chance nodes legible. section 10.2.1 section 10.2.2


