R squared, with the flat-target case

Easy8 min10 hidden tests

A rent model predicts monthly rent in thousands of dollars, and the team reports R squared: how much of the spread in real rents the model explains. Write r_squared(y_true, y_pred) that returns 1 - SS_res / SS_tot. SS_res is the sum of squared errors, and SS_tot is the sum of squared distances of the targets from their mean. When every target is the same, SS_tot is 0, and the score is 1.0 for perfect predictions and 0.0 otherwise.

Drag the ends of the line

R² = 1 − SS_res / SS_tot
Real rentsYour lineMean rent
Your line, SS_res1.46The mean, SS_tot3.21

R² = 1 − 1.46 / 3.21 = 0.54.

R squared 0.54.

Examples

The errors cover a quarter of the spread, so R squared is 0.75

r_squared([3.0, 5.0, 7.0], [4.0, 5.0, 6.0])

returns 0.75

Flat targets predicted perfectly score 1.0

r_squared([5.0, 5.0, 5.0], [5.0, 5.0, 5.0])

returns 1

Requirements

  • y_true and y_pred are lists or 1-D arrays of the same length, 1 or more.
  • SS_res = sum((y_true - y_pred) ** 2) and SS_tot = sum((y_true - mean(y_true)) ** 2).
  • When SS_tot is 0, return 1.0 if SS_res is also 0 and 0.0 otherwise.
  • Return a float. It can be negative when the predictions are worse than always predicting the mean.
The idea behind it

R squared, the coefficient of determination, compares a regression model with the dumbest model there is: one that always predicts the mean target. SS_tot = sum((y - mean(y)) ** 2) is the squared error of that baseline, and SS_res = sum((y - pred) ** 2) is the squared error of your model. Then R^2 = 1 - SS_res / SS_tot. A perfect model scores 1. A model no better than the mean scores 0. A model worse than the mean scores below 0, which surprises people who think of R squared as a square. It is not the squared correlation in general: those two agree only for a least-squares fit with an intercept, scored on its own training data. When all targets are equal, SS_tot is 0 and the ratio is undefined. scikit-learn's r2_score then returns 1.0 for perfect predictions and 0.0 otherwise, and this problem uses the same rule.

pythonCtrl+Enter runs
import numpy as np

def r_squared(y_true, y_pred):
"""Coefficient of determination of predictions against targets.

y_true: list or 1-D array of n targets
y_pred: list or 1-D array of n predictions
Returns 1 - SS_res / SS_tot as a float. When all targets are equal,
returns 1.0 for perfect predictions and 0.0 otherwise.
"""
raise NotImplementedError

Stuck? Reveal one rung at a time

Worked solution

Give it a real try first. Then read the solution and why each line is there.