DSCI 100 Week 6 : Classification

Sky (Kehan) Sheng

📋 Housekeeping: Midterm

  • Midterm: Thursday, Oct 22, 8AM, 70 minutes long, starting at the beginning of our tutorial period.
  • Midterm coverage: Weeks 1 to 6 (including today’s content).
  • Closed book quiz on Canvas: Multiple-choice questions, short answer questions, and fill-in-the-blank questions.
  • No live-coding quizes, and we will not run your code. However, fill-in-the-blank do ask you to write the correct function name or code snippet.
  • Requires the Lockdown Browser. Install and test it using the Canvas iPohone_poll assignment on the laptop you will bring.

📋 Housekeeping: Midterm

Important

  • Bring a laptop. The Lockdown Browser does not work on an iPad or phone.
  • Bring your UBC ID card to the midterm, we will check it during the exam.
  • No AI glasses or any recording or communication devices are allowed!

🔁 Week 5 Recap: Version control

iClicker: Where did my change go?

iClicker: Put them in order

🔁 Recap: map_dfr() and facets

🤔 mutate() or map_dfr()?

📊 facet_grid() or facet_wrap()?

One small plot per group, on the same axes. facet_grid() lays the panels out as a table of rows and columns. facet_wrap() fills them left to right, then wraps onto a new line, like words on a page.

ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g, colour = species)) +
  geom_point() +
  facet_grid(rows = vars(species))

ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g, colour = species)) +
  geom_point() +
  facet_grid(cols = vars(species))

ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g, colour = species)) +
  geom_point() +
  facet_grid(rows = vars(species), cols = vars(island))

ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g, colour = species)) +
  geom_point() +
  facet_wrap(~ island)

Week 6: Classification

🎯 Today’s Learning Objectives

By the end of today, you will be able to:

  • Explain how the K nearest neighbours (KNN) predicts the label of a new observation.
  • Understand why we need to standardize the predictors before using KNN.
  • Build a classifier in R with a recipe, a model, and a workflow.
  • Predict the category of a new observation.

🤔 Is this tumour dangerous?

A doctor takes a few cells from a new tumour and measures them under a microscope. Is it benign (not cancer) or malignant (cancer)?

Each dot is one past tumour, 569 in total, already diagnosed by a doctor.

The star is the new tumour. Benign or malignant?

How did you decide?

You looked at its neighbours. 🏘️

✏️ Classification

  • We have past observations whose label we already know: benign or malignant.
  • We have a new observation whose label we don’t know.
  • We use the past to predict the label of the new one.
Word Meaning In our example
observation one row one tumour
predictors the columns we use to decide Perimeter, Concavity
class (label) the category we predict benign or malignant
training set past observations with known labels the 569 diagnosed tumours

iClicker: What kind of question?

🔄 Where are we in the workflow?

Weeks 1 to 4: import, tidy, transform, visualize. Today we start to model.

🏘️ K-nearest neighbours, step by step

📏 Step 1 up close: how far is “near”?

The straight-line distance between two points:

\text{Distance} = \sqrt{(\text{new}_x - \text{train}_x)^2 + (\text{new}_y - \text{train}_y)^2}

📏 More than 2 predictors? Same idea

Add one squared difference per extra column:

\text{Distance} = \sqrt{(u_1 - v_1)^2 + (u_2 - v_2)^2 + \dots + (u_m - v_m)^2}

Our new tumour, now with a third measurement: Perimeter = 0.2, Concavity = 3.3, Symmetry = 1.

The 3 nearest past tumours, using all three predictors
Perimeter Concavity Symmetry diagnosis distance
0.540 3.018 -0.056 malignant 1.145
1.260 3.026 0.556 malignant 1.181
0.686 2.221 0.603 malignant 1.248

We can’t draw 10 dimensions, but the computer doesn’t need to. Sort, keep K, vote: the same algorithm.

🎛️ What if we change K?

An even K can split 2 against 2: a tie, and no answer. So with two classes, pick an odd K.

🗳️ Odd K, so never a tie?

An odd K fixed the tie for two classes. Now 3 classes: is this penguin an Adelie, a Chinstrap or a Gentoo? Every K below is odd.

Two classes: an odd K can’t split evenly, so no tie. Three or more classes: an odd K can still tie.

⚠️ When one class is rare

A bank wants to flag fraud. Its data: 100 past card payments, only 4 were fraud. We use K = 9.

To win the vote, fraud needs 5 of 9 neighbours.

There are only 4 fraud payments in the whole data set.

Fraud can never win. Every new payment is called normal.

One fix is upsampling: copy the rare class until both classes are about the same size. But first, know your data: count how many of each class you have before you trust a classifier.

⚖️ Standardizing: a fair ruler

🦦 Oda wants a date

Oda is 30 years old and has 250 friends on Fishbook.

Fishbook suggests a match with KNN, using two columns: age and number of friends.

🦦 Who is the closest match?

Oda: 30 years old, 250 friends.

otter age friends age gap friends gap distance
A 25 400 5 150 150.1
B 27 300 3 50 50.1
C 60 250 30 0 30.0

Otter C is twice Oda’s age, and still the “nearest”.

Same problem as pounds and feet: a 30 year gap counts as 30, a 50 friend gap counts as 50.

Sea otter or river otter?

A biologist measured 22 otters on the BC coast and already knows each one’s species. A new otter (★): 1150 mm long, hind feet 8.6 cm wide.

What does KNN with K = 3 predict for the new otter?

  • (A) Sea otter
  • (B) River otter
  • (C) It’s a tie

📏 What KNN actually measures

✏️ How to standardize

\text{standardized value} = \frac{\text{value} - \text{mean}}{\text{standard deviation}}

KNN in R with tidymodels

🧰 tidymodels: one toolbox for modelling

  • A collection of packages, like tidyverse is for data.
  • It computes the distances, standardizes, and predicts for us.
  • Same 4 steps for almost every model we meet in this course.

🔬 Step 0: load the packages and the data

tumors <- tumors |>
  mutate(Class = as_factor(Class))
tumors

🔬 Step 1: a recipe()

A recipe says what to predict, from which columns, and how to prepare the data first.

Class ~ Perimeter + Concavity

read ~ as “is predicted by”: what we predict ~ the predictors
tumor_recipe <- recipe(Class ~ Perimeter + Concavity, data = tumors) |>
  step_center(all_predictors()) |>
  step_scale(all_predictors())

tumor_recipe

🔬 Step 2: a model specification

Which model, with which settings. No data yet.

  1. model type: nearest_neighbor()
  2. arguments: neighbors = 3 (K), weight_func = "rectangular" (every neighbour’s vote counts the same)
  3. engine: set_engine("kknn"), the package that does the work
  4. mode: set_mode("classification"), predict a category
tumor_model <- nearest_neighbor(weight_func = "rectangular",
                                neighbors = 3) |>
  set_engine("kknn") |>
  set_mode("classification")

tumor_model

🔬 Step 3: a workflow, then fit()

  • workflow(): put the recipe and the model together.
  • fit(): run it on the training data.
  • For KNN, fitting means remembering the standardized training tumours, plus the mean and sd of each column.
tumor_workflow <- workflow() |>
  add_recipe(tumor_recipe) |>
  add_model(tumor_model)

tumor_fit <- tumor_workflow |>
  fit(data = tumors)

tumor_fit

🔬 Step 4: predict()

Our new tumour from the start of class: Perimeter = 0.2, Concavity = 3.3.

new_obs <- tibble(Perimeter = 0.2, Concavity = 3.3)
predict(tumor_fit, new_obs)

🔬 Try it yourself

  • Predict tumour B from the K slider: Perimeter = -0.2, Concavity = 0.6.
  • Change neighbors to 1, then 5, then 7. Do you get the same answers as the slider?

🗺️ Today in one table

Idea In words In R
classification predict a category for a new observation set_mode("classification")
distance straight line between two points computed for us
K-nearest neighbours keep the K nearest neighbours, predict the category for new data using majority vote nearest_neighbor(neighbors = K)
standardize subtract the mean, divide by the sd step_center(), step_scale()
workflow recipe and model together workflow(), fit(), predict()

📅 Upcoming Due Dates

Important

  • worksheet_classification1 due Monday, Oct 19, 11:59PM
  • tutorial_classification1 due Monday, Oct 19, 11:59PM

❓ Questions?

If not, let’s work on this week’s worksheet together.

  • Want to save these slides? Right click → Print → Save to PDF.
  • Your code and notes only save if you save as a PDF!
  • Which function do I use? Every function so far, week by week: Function cheatsheet