14 / Quantitative modeling / Regression
Diamond Price Regression
An interpretable log–log OLS on 53,940 diamonds, and an audit of what its headline R² actually measures.
01 / The question
Can a price model be accurate and readable?
A diamond's length, width and depth are almost the same variable: a bigger stone is bigger in every direction. Feeding all three into a regression inflates the condition number and makes the coefficients unstable. The study makes interpretability a design constraint rather than chasing the highest fit.
02 / What the model does
One size variable, ordered grades, log–log space.
Price is heavily right-skewed, so price and size are log-transformed and coefficients read as elasticities. log_length_mm stands in for all physical size: it has the strongest Phik association with log price (0.92). Cut, colour and clarity are encoded in their true quality order rather than one-hot expanded. The final specification is log_length_mm + cut_code + color_code + clarity_code − 1, with the intercept suppressed to bring the condition number down from 97.7 to 10.7.
03 / What a re-check shows
Stable coefficients, but not a better model.
Dropping the intercept makes statsmodels report an uncentered R², 0.997. Measured the same way as the simpler models, the final specification scores 0.838, below log_length_mm alone (0.912). Putting the intercept back gives 0.950. The coefficients tell the same story: without the intercept, better cut and colour grades appear to lower price, and with it every grade coefficient turns positive.
| Term | No intercept (notebook) | With intercept |
|---|---|---|
| intercept | — | −5.0433 |
| log_length_mm | 4.2170 | 6.4505 |
| cut_code | −0.0548 | +0.0091 |
| color_code | −0.0123 | +0.0724 |
| clarity_code | +0.0094 | +0.1137 |
| R² as reported | 0.997 | 0.950 |
| R² centered | 0.838 | 0.950 |
| Condition number | 10.7 | 97.7 |
| Hold-out R² (log price) | 0.845 | 0.963 |
| Hold-out MAPE (dollar price) | 33.4% | 12.7% |
04 / Data audit
Does depth_pct match its own formula?
The dataset ships a depth percentage that should equal 2 × depth_mm / (length_mm + width_mm) × 100. Recomputing it, 96.7% of rows reconcile within 0.1 percentage points.
The exceptions are mostly rounding-scale gaps, plus 20 rows where a physical dimension is recorded as zero. Those are the rows worth raising with whoever supplies the data, and they are small enough that depth_pct is usable as a feature.
05 / What to change next
Keep the intercept, compare on the same basis.
Keep the intercept and handle collinearity by using a single size term, as this study already does. Report centered R² and a hold-out error next to every specification, so the comparison is like for like. Drop the zero-dimension rows, and test grade dummies against the ordinal codes, since ordinal codes assume the steps between grades are equally spaced.