Wine detective with a decision tree
scikit-learn's wine dataset describes 178 wines from three different growers in the same region of Italy, using chemistry measurements like alcohol, colour intensity and flavonoids. A decision tree learns a set of yes/no questions to tell the growers apart, and unlike many models, you can read every question it asks.
Skills you'll practise
- Decision trees
- Train/test split
- Feature importance
- Overfitting
Steps
Step 1: Load the wines
Load the dataset as a pandas DataFrame and look at the first few rows and the column names.
Show a hintHide the hint
load_wine(as_frame=True).framegives you one table with the features and atargetcolumn.Step 2: Split, then train a small tree
Hold back a quarter of the wines, then fit a
DecisionTreeClassifierwithmax_depth=3on the rest.Show a hintHide the hint
A shallow tree is easier to read and less likely to memorise the training data.
Step 3: Test it
Print the accuracy on the wines the tree hasn't seen.
Step 4: Read the tree's questions
Print the tree as text with
export_textto see each question it asks, in order.Step 5: Find the most useful clues
Sort
feature_importances_to see which measurements did most of the work.Show a hintHide the hint
Put them in a pandas Series with the feature names as the index, then call
.sort_values(ascending=False).
Starter code
It already runs. The TODO comments mark where to start.
import pandas as pd
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_text
wine = load_wine(as_frame=True)
df = wine.frame
print(df.head())
print()
print("Growers:", ", ".join(wine.target_names))
# TODO: split into training and test wines, train a
# DecisionTreeClassifier(max_depth=3), and print its accuracy.
Example solution
One way to finish it. Have a go first; yours doesn't need to match.
Reveal the solutionHide the solution
import pandas as pd
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_text
wine = load_wine(as_frame=True)
X = wine.data
y = wine.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=0, stratify=y
)
tree = DecisionTreeClassifier(max_depth=3, random_state=0)
tree.fit(X_train, y_train)
print(f"Accuracy on unseen wines: {tree.score(X_test, y_test):.0%}")
print()
print("The questions the tree asks:")
print(export_text(tree, feature_names=list(X.columns)))
importance = pd.Series(tree.feature_importances_, index=X.columns)
print("Most useful clues:")
print(importance.sort_values(ascending=False).head(5).round(2))
Stretch goal
Train trees with max_depth from 1 to 10 and print both the training and the test accuracy for each. Where does the tree start memorising instead of learning?