Act I · The tension
We can’t randomly assign people different incomes, or give one city a tax cut and another none.
So how do we measure how one economic variable moves with another? Regression — the primary tool of econometrics — turns a cloud of observed data into a line we can read.
The slope is almost always the number you actually care about.
Act II · The investigation
29 house sales in Davis, California (1999). Two columns carry the story: price and size.
\[\text{price} = \beta_0 + \beta_1 \cdot \text{size} + \varepsilon\]
We want \(\beta_1\) — the predicted change in price per extra square foot. OLS chooses \(\beta_0, \beta_1\) to make the squared gaps between the dots and the line as small as possible.
import pandas as pd # pandas → load & handle tabular data
# dataset: 29 house sales in Davis, CA, 1999 (price, size, bedrooms, …)
url = "https://raw.githubusercontent.com/quarcs-lab/data-open/master/AED/AED_HOUSE.DTA"
data = pd.read_stata(url) # read the Stata .dta into a DataFrame
data.head() # peek at the first few rows
data.describe().round(2) # summary stats: mean, std, min, max, quartilesimport pandas as pd # tabular data
import matplotlib.pyplot as plt # plotting
url = "https://raw.githubusercontent.com/quarcs-lab/data-open/master/AED/AED_HOUSE.DTA"
data = pd.read_stata(url) # load the 29 Davis, CA house sales
fig, ax = plt.subplots(figsize=(10, 6)) # one figure + axes
ax.scatter(data["size"], data["price"], # x = size, y = price
s=80, alpha=0.7, color="#22d3ee") # marker size, transparency, colour
plt.show() # render the scatter plotEach dot is a house. The upward drift is the relationship; the vertical scatter is everything size doesn’t explain.
A scatter plot is the honest first look — it shows direction and spread before any model.
!pip install -q pyfixest # install pyfixest in Colab (-q = quiet; not preinstalled)
import pandas as pd # tabular data
import pyfixest as pf # pyfixest → OLS regression, R-style formulas
url = "https://raw.githubusercontent.com/quarcs-lab/data-open/master/AED/AED_HOUSE.DTA"
data = pd.read_stata(url) # load the 29 Davis, CA house sales
fit = pf.feols("price ~ size", data=data) # OLS: regress price on size (intercept auto-added)
fit.summary() # β0, β1, SEs, t, p, R²The fitted line through the cloud, with its equation.
Slope \(\beta_1 = \$73.77\)/sq ft · intercept \(\beta_0 = \$115{,}017\) · \(R^2 = 0.62\).
Report magnitude, not just significance: $74 per square foot is the economically meaningful finding.
Act III · The resolution
Objection. “Each square foot adds $74 — so extending my house 100 sq ft adds $7,400.”
Response. Association is not causation. Bigger houses may also be better-located and better-renovated — the slope credits size for quality’s effect too. Like ice-cream sales and drownings: both rise in summer, but one doesn’t cause the other.
Regression shows how \(Y\) and \(X\) move together; a causal reading needs a design that rules out the alternatives.
pandas, matplotlib, pyfixest).