The most open-ended of the three. There’s no list of inputs: part of the test is deciding what data matters before any regression happens.
In an interview you would alternate between brainstorming variables and working out how to preprocess and tune them. Here are two rounds.
Round 1: the obvious drivers
Time of day, month or season, location, temperature and weather (sunny, cloudy, rainy).
Time is a circle
Hour and month are ordered, but the order wraps around: 23:00 is next to 00:00 and December is next to January. Coding the hour as the number 0–23 creates a fake jump at midnight. Three fixes:
- One-hot the hour (24 dummies) and month (12). No fake ordering, but many inputs, and the natural ordering is lost.
- Bucket first, then one-hot: morning, afternoon, evening, night; four seasons. Fewer inputs, and some ordering is recovered.
- Use a cyclical basis: map the hour to a point on a circle, , and add higher harmonics (, …) for more detail. Cyclic splines do the same job more flexibly.
Location
Neighbourhoods are irregular in shape and activity. The simplest approach one-hot encodes the neighbourhood, assuming usage is uniform inside one. Better: use latitude and longitude, which are continuous, and let a smooth nonlinear function of them (a medium-degree polynomial, or low-degree splines to keep the input count down) capture how activity varies across the city.
Temperature and weather
Temperature goes in as a number; weather is categorical, so one-hot. The trap is correlation: rain and temperature move together, and both follow the time of day and season. Measure it (point-biserial correlation or a logistic regression for the categorical–continuous pairs). If it’s high, use ridge, lasso, subset selection, or combine the two into one variable. A neat trick for cyclical correlation: subtract the previous cycle, using “temperature minus the same hour yesterday” instead of the raw temperature.
Round 2: less obvious variables
Day of week, holidays, traffic, subway usage, rainfall in inches, air quality, local housing prices, local business activity. Their preprocessing is like round 1. With ten or more correlated variables the tuning matters most:
- Compute t-statistics for every input and flag the weak ones.
- F-test groups of correlated weak inputs before dropping them.
- Use elastic net: ridge’s proportional shrinkage handles correlated groups, lasso’s soft thresholding drops what doesn’t matter.
- For a big-picture view of what drives usage, run forward or backward stepwise selection.
In code
import numpy as np
from sklearn.linear_model import LinearRegression
rng = np.random.default_rng(14)
h = rng.uniform(0, 24, 3000)
demand = (30 + 70 * np.exp(-0.5 * ((h - 8.5) / 1.3) ** 2) + 85 * np.exp(-0.5 * ((h - 17.8) / 1.6) ** 2)
+ 9 * rng.standard_normal(h.size))
def harmonics(h, K):
return np.column_stack([f(2 * np.pi * k * h / 24) for k in range(1, K + 1) for f in (np.sin, np.cos)])
for name, X in [("hour as number", h[:, None]),
("24 one-hot", np.eye(24)[h.astype(int)]),
("sin/cos, K=3", harmonics(h, 3))]:
r2 = LinearRegression().fit(X, demand).score(X, demand)
print(f"{name:15s} inputs={X.shape[1]:2d} R^2={r2:.3f}")
Check yourself
Why is ‘hour of day as a number from 0 to 23’ a poor input for a linear model of bike demand?