Skip to learning content

DATA SCIENCE PYTHON PLAYGROUND

Machine Learning · Learn / Refresh

← Classification lessons
Margins and rules · ML-C-K1 · 25–35 MIN

Classification checkpoint

  1. Retrieval 1Retrieve and applyCurrent exercise

Outputs you create

cv_results
  1. Dataframe indexed by the requested model IDs, with initial_score, selected_score and settings columns.
  2. Scores are observed mean training-fold scores; settings describes the chosen recipe.
reference_results
  1. cross_validate result for the dummy reference; test_score contains five scores.
chosen_name
  1. Model ID nominated from training evidence.
matrix
  1. Confusion matrix of training-only diagnostic predictions.
final_f1
  1. Macro F1 on final-test class predictions.
final_accuracy
  1. Final-test accuracy, supplementary to macro F1.
ablation_results
  1. Five matching training-fold scores for the measurements-only ablation.
penguins · first 8 rows
islandbill_length_mmbill_depth_mmflipper_length_mmbody_mass_gsexyearspecies
Torgersen39.118.71813750male2007Adelie
Torgersen39.517.41863800female2007Adelie
Torgersen40.3181953250female2007Adelie
Torgersen36.719.31933450female2007Adelie
Torgersen39.320.61903650male2007Adelie
Torgersen38.917.81813625female2007Adelie
Torgersen39.219.61954675male2007Adelie
Torgersen41.117.61823200female2007Adelie
Your task
  1. Complete a stratified mixed Penguin logistic workflow with macro F1, a reference, tuning, a measurements-only ablation at the selected C on identical folds, and confusion evidence.
  2. Report the ablation fold scores in ablation_results and use them to qualify reliance on island/year/sex context.
cv_resultsreference_resultschosen_namematrixfinal_f1final_accuracyablation_results
Hints

Think: Reconstruct class-aware validation while investigating the role of context.

Tools: Stratified folds, mixed logistic pipeline, C search, measurement ablation and confusion matrix.

Approach: Compare reference and candidate, select C, evaluate the matched ablation and OOF class errors, then report final metrics.

Explained solution
from sklearn.base import clone
from sklearn.model_selection import train_test_split, StratifiedKFold, cross_validate, cross_val_predict, GridSearchCV
from sklearn.dummy import DummyClassifier
from sklearn.metrics import f1_score, accuracy_score, confusion_matrix

import matplotlib.pyplot as plt
import seaborn as sns
X=df[['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g', 'sex', 'island', 'year']]
y=df['species']
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=.2,random_state=42,stratify=y)
folds=StratifiedKFold(n_splits=5,shuffle=True,random_state=42)
candidates={}
grids={}
# Prepare inputs and construct the candidate pipeline.
numeric_features = ['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g']
categorical_features = ['island', 'year']
encoded_binary_features = ['sex']
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
category_encoder = OneHotEncoder(handle_unknown='ignore', sparse_output=False, drop=None)
preprocessor = ColumnTransformer([('continuous', StandardScaler(), numeric_features), ('encoded', category_encoder, encoded_binary_features + categorical_features)], verbose_feature_names_out=False)
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(max_iter=2000, random_state=42)
pipeline = Pipeline([('prepare', preprocessor), ('model', model)])
model = pipeline
candidates['logistic']=model
grids['logistic']={'model__C': [0.1, 1.0, 10.0]}
# Validate initial candidates on matching training folds.
initial_results={name:cross_validate(candidate,X_train,y_train,cv=folds,scoring='f1_macro') for name,candidate in candidates.items()}
# Compare with a simple reference before tuning.
reference_results=cross_validate(DummyClassifier(strategy='most_frequent'),X_train,y_train,cv=folds,scoring='f1_macro')
rows=[]
selected={}
for name,candidate in candidates.items():
    initial=initial_results[name]
    grid=grids[name]
    if grid:
        search=GridSearchCV(candidate,grid,cv=folds,scoring='f1_macro',n_jobs=1)
        search.fit(X_train,y_train)
        selected[name]=search.best_estimator_
        validation_score=float(search.best_score_)
        settings=search.best_params_
    else:
        selected[name]=candidate
        validation_score=float(np.mean(initial['test_score']))
        settings='Keep defaults: no production search'
    rows.append({'model':name,'initial_score':float(np.mean(initial['test_score'])),'selected_score':validation_score,'settings':str(settings)})
cv_results=pd.DataFrame(rows).set_index('model')
# This solution nominates by mean training-fold score. Other evidence-based choices can be defensible.
chosen_name=cv_results.selected_score.idxmax()
chosen=selected[chosen_name]
# Training-only measurements ablation at the selected regularisation strength.
measurement_columns=['bill_length_mm','bill_depth_mm','flipper_length_mm','body_mass_g']
measurement_model=Pipeline([('scale',StandardScaler()),('model',LogisticRegression(C=chosen.named_steps['model'].C,max_iter=2000,random_state=42))])
ablation_results=cross_validate(measurement_model,X_train[measurement_columns],y_train,cv=folds,scoring='f1_macro')
oof_predictions=cross_val_predict(chosen,X_train,y_train,cv=folds)
diagnostic_y=y_train
class_labels=sorted(y_train.unique())
matrix=confusion_matrix(diagnostic_y,oof_predictions,labels=class_labels)
fig,ax=plt.subplots(figsize=(6,4))
sns.heatmap(matrix,annot=True,fmt='d',cmap='Blues',ax=ax,xticklabels=class_labels,yticklabels=class_labels)
ax.set(xlabel='Predicted class',ylabel='Actual class',title='Training-only confusion matrix')
fig.tight_layout()
fig.savefig('diagnostic.png',dpi=150,bbox_inches='tight')
final_model=clone(chosen).fit(X_train,y_train)
final_predictions=final_model.predict(X_test)
final_f1=f1_score(y_test,final_predictions,average='macro')
final_accuracy=accuracy_score(y_test,final_predictions)
print('Final macro F1:',final_f1,'; accuracy:',final_accuracy)

The ablation tests reliance on context using training evidence; stratification and macro F1 keep minority-class behaviour visible before final evaluation.

Ctrl/⌘+Enter: Run · Tab: indent · Esc then Tab: leave editor

Python loads when you run. Code and results stay in this activity only.

Run your code to inspect its output. Check uses that same run.