Random forests are a strong tree-ensemble baseline when tabular classification data has nonlinear signals or interacting features. In scikit-learn, RandomForestClassifier fits many decision trees and averages their class votes, which produces a classifier that usually needs little preprocessing for numeric features.
Use a held-out split before reading the score so the forest is checked on rows outside the fit call. The breast cancer dataset keeps the workflow small while still showing class labels, feature names, and enough rows for a stratified train/test split.
Feature importances from a fitted forest are a quick impurity-based signal for model inspection. Treat them as a first pass rather than a final explanation, and use permutation importance on held-out data when the importance ranking will drive decisions.
import sklearn from sklearn.datasets import load_breast_cancer from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score, classification_report from sklearn.model_selection import train_test_split data = load_breast_cancer() X_train, X_test, y_train, y_test = train_test_split( data.data, data.target, test_size=0.2, random_state=42, stratify=data.target, ) model = RandomForestClassifier( n_estimators=200, max_depth=5, random_state=42, ) model.fit(X_train, y_train) predictions = model.predict(X_test) accuracy = accuracy_score(y_test, predictions) top_features = sorted( zip(data.feature_names, model.feature_importances_), key=lambda item: item[1], reverse=True, )[:5] print(f"sklearn version: {sklearn.__version__}") print(f"train rows: {X_train.shape[0]}") print(f"test rows: {X_test.shape[0]}") print(f"classes: {data.target_names.tolist()}") print(f"trees: {len(model.estimators_)}") print(f"held-out accuracy: {accuracy:.3f}") print(f"first predictions: {data.target_names[predictions[:5]].tolist()}") print("top feature importances:") for feature, importance in top_features: print(f" {feature}: {importance:.3f}") print("classification report:") print(classification_report(y_test, predictions, target_names=data.target_names))
stratify=data.target keeps the malignant and benign class proportions close in both splits. random_state=42 makes the split and forest reproducible while the script is being checked.
$ python3 train_random_forest.py
sklearn version: 1.9.0
train rows: 455
test rows: 114
classes: ['malignant', 'benign']
trees: 200
held-out accuracy: 0.956
first predictions: ['malignant', 'benign', 'malignant', 'malignant', 'malignant']
top feature importances:
worst perimeter: 0.136
worst area: 0.125
worst concave points: 0.110
mean concave points: 0.102
worst radius: 0.093
classification report:
precision recall f1-score support
malignant 0.95 0.93 0.94 42
benign 0.96 0.97 0.97 72
accuracy 0.96 114
macro avg 0.96 0.95 0.95 114
weighted avg 0.96 0.96 0.96 114
The built-in breast cancer dataset has 569 rows, so the 20 percent test split leaves 455 training rows and 114 held-out rows. The trees: 200 line confirms that n_estimators=200 controlled the fitted forest size.
held-out accuracy: 0.956 summarizes the test-set score. The per-class recall lines show whether one class is being missed more often than the other.
feature_importances_ reports impurity-based importances from the fitted forest. Correlated features can split credit between themselves, so use held-out permutation importance before treating the ranking as evidence for a model decision.
X = your_dataframe[feature_columns].to_numpy() y = your_dataframe["target"].to_numpy()
Keep the same split, fit, predict, score, and inspection pattern. Add preprocessing in a Pipeline when real features need imputation, encoding, or scaling.
Related: How to create a scikit-learn pipeline
$ rm train_random_forest.py