Module Assessment

Overview

In this module, you learned the foundational concepts and practical skills of machine learning: what ML is and how it differs from traditional programming, the distinction between supervised and unsupervised learning, how to source and evaluate data, how to clean raw data for ML, and how to engineer features that models can actually use. This assessment asks you to demonstrate all of those skills together — building a complete data preparation pipeline from a raw dataset to a processed feature matrix ready for a model.

Complete the assessment using this Colaboratory notebook.

Learning Objectives

By the end of this assessment, you will have demonstrated the ability to:

  • Show readiness for more complex ML modules.
  • Demonstrate basic data prep and understanding of ML tasks.

Assessment Overview

You'll work with the Palmer Penguins dataset — a classic ML dataset with realistic data quality issues, categorical variables, and numeric features at different scales. Your task is to take it from raw to ready: cleaned, encoded, scaled, and split for supervised classification.

Skills Assessed

SkillLessons covered
Identify the ML problem typeSupervised vs. Unsupervised
Load and inspect a datasetCollecting Data
Handle missing values and duplicatesCleaning Data
Drop irrelevant or leaking columnsCleaning Data
Encode categorical variablesFeature Engineering
Scale numeric featuresFeature Engineering
Create engineered featuresFeature Engineering
Perform a stratified train/test splitCollecting Data, Feature Engineering
Assemble a ColumnTransformer pipelineFeature Engineering

Starter Code

Use the included Colaboratory notebook to complete the tasks below. Submit the link for grading.

Coding Assessment

The Dataset

import pandas as pd
import seaborn as sns

df = sns.load_dataset("penguins")
print(df.shape)
print(df.head())
print(df.isnull().sum())

The penguins dataset contains 344 rows and these columns:

ColumnDescriptionType
speciesPenguin species (Adelie, Chinstrap, Gentoo)Categorical — this is the target
islandIsland where observed (Biscoe, Dream, Torgersen)Categorical
bill_length_mmBill length in millimetersNumeric
bill_depth_mmBill depth in millimetersNumeric
flipper_length_mmFlipper length in millimetersNumeric
body_mass_gBody mass in gramsNumeric
sexPenguin sex (Male, Female)Categorical

Task 1: Identify the ML Problem Type

In a markdown cell, answer the following:

  1. Is this a supervised or unsupervised learning problem? Why?
  2. Is this a classification or regression task? Why?
  3. Is this binary classification or multi-class classification? Why?

Task 2: Inspect and Clean the Data

Perform the following steps:

  1. Print the shape, data types, and missing value counts.
  2. Drop any duplicate rows.
  3. Handle missing values:
    • For numeric columns (bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g): impute with the median.
    • For the categorical column sex: impute with the mode.
  4. After cleaning, confirm there are zero missing values with df.isnull().sum().
# Your cleaning code here

Task 3: Define Features and Target

  1. Separate the features (X) and target (y):
    • y = species
    • X = all other columns
  2. Perform a stratified train/test split: 80% train, 20% test, random_state=42.
  3. Print the shape of X_train and X_test.
  4. Print the class distribution in y_train using value_counts(normalize=True).
from sklearn.model_selection import train_test_split

# Your code here

Task 4: Engineer a New Feature

Before building the preprocessing pipeline, create one new feature on both X_train and X_test:

  • bill_ratio: bill_length_mm divided by bill_depth_mm. This captures the shape of the bill regardless of absolute size.
# Add bill_ratio to X_train and X_test
X_train = X_train.copy()
X_test  = X_test.copy()

X_train["bill_ratio"] = ...
X_test["bill_ratio"]  = ...

Task 5: Build a ColumnTransformer Pipeline

Build a preprocessing pipeline using ColumnTransformer that:

  • Numeric columns (bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g, bill_ratio): apply StandardScaler
  • Categorical columns (island, sex): apply OneHotEncoder(drop="first", sparse_output=False)
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.pipeline import Pipeline

numeric_features     = ["bill_length_mm", "bill_depth_mm",
                         "flipper_length_mm", "body_mass_g", "bill_ratio"]
categorical_features = ["island", "sex"]

# Build numeric_transformer, categorical_transformer, and preprocessor here

Fit the preprocessor on training data and transform both sets:

X_train_processed = preprocessor.fit_transform(X_train)
X_test_processed  = preprocessor.transform(X_test)

print(f"Processed train shape: {X_train_processed.shape}")
print(f"Processed test shape:  {X_test_processed.shape}")

Task 6: Verify the Output

After processing, confirm the following:

  1. No NaN values exist in X_train_processed (hint: np.isnan(X_train_processed).sum()).
  2. The numeric columns have approximately mean = 0 and std = 1. Compute the column-wise mean and standard deviation of the numeric portion of X_train_processed.
  3. Print how many total features are in the processed output and list what they represent (e.g., 5 scaled numeric + how many one-hot columns?).

Task 7: Reflection

In a markdown cell, answer the following questions:

  1. Why must the ColumnTransformer be fitted on training data only and then used to transform the test set — rather than being fitted on the full dataset?
  2. You created bill_ratio as an engineered feature. Propose one additional feature you could create from the existing columns and explain what signal you think it would capture.
  3. The penguins dataset has three species. If you trained a model and it achieved 95% accuracy, but 40% of the rows are Adelie penguins — would accuracy alone be sufficient to evaluate the model? What other metric(s) might you look at?

Grading Rubric

TaskPointsCriteria
Task 1: Problem identification10Correctly identifies supervised multi-class classification with justification
Task 2: Cleaning20Removes duplicates, imputes all missing values correctly, confirms zero NaN
Task 3: Train/test split15Correct stratified split, prints shapes and class balance
Task 4: Feature engineering15bill_ratio correctly computed on both train and test sets
Task 5: ColumnTransformer25Pipeline built correctly, fit on train only, transform applied to both sets
Task 6: Verification10Confirms no NaN, verifies scaled statistics, explains output shape
Task 7: Reflection5Thoughtful answers demonstrating conceptual understanding
Total100

Knowledge Check

Question 1: You are building a model to classify penguin species using body measurements. After completing feature engineering, you realize you accidentally called `preprocessor.fit_transform()` on the combined train + test data instead of training data only. What problem does this cause?

Question 2: The penguins dataset has three species: Adelie (44%), Chinstrap (20%), and Gentoo (36%). When you call `train_test_split`, you use `stratify=y`. Why?

Question 3: A teammate suggests skipping feature scaling because "the model will figure out the right weights anyway." For which of the following algorithms is this reasoning most problematic?