← Back to selected work

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.

Decision signalOLS / MODEL 14
0.838 centered0.950 + intercept0.997 uncentered0.800.901.00
0.997 → 0.838Same model, same data: uncentered vs centered R²
Model chart / R² by specificationcentered basis
Diamond price regression R-squared by specificationCentered R-squared is 0.847 for carat, 0.909 for log carat, 0.912 for log length, 0.838 for the final no-intercept model and 0.950 for the same model with an intercept. The no-intercept model reports 0.997 only because statsmodels computes an uncentered R-squared. 0.800.901.00 log_price ~ carat~ log_carat~ log_length_mmfinal · no interceptfinal · with intercept 0.847 0.909 0.912 0.8380.997 uncentered, as reported 0.950
intercept modelsno intercept, centeredfinal + intercept○ uncentered
R² on log price · axis 0.80–1.00 · statsmodels reports an uncentered R² when the intercept is dropped, which is not comparable to the models above it
0.838centered R² · final spec
0.950same spec + intercept
96.7%of rows reconcile on depth %

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.

Automated stepwise selection on the log-transformed inputs kept adding overlapping size variables (ten features) and flagged a train–test gap, which is what motivated a hand-built specification.

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.

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.

Same four predictors, with and without the intercept
TermNo intercept (notebook)With intercept
intercept—−5.0433
log_length_mm4.21706.4505
cut_code−0.0548+0.0091
color_code−0.0123+0.0724
clarity_code+0.0094+0.1137
R² as reported0.9970.950
R² centered0.8380.950
Condition number10.797.7
Hold-out R² (log price)0.8450.963
Hold-out MAPE (dollar price)33.4%12.7%
Grade codes run from worst to best, so a negative coefficient means a better grade lowers price at a given size. The lower condition number bought numerical stability, not a better-behaved model. Hold-out uses a 75/25 split with seed 42, and dollar predictions are a plain back-transform of the log prediction.

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.

Data audit / depth_pct reconciliation53,940 rows
depth_pct reconciliation52,175 rows, 96.7 percent, match the depth formula within 0.1 points. 1,765 rows, 3.3 percent, do not.
52,175 reconcile · 96.7%1,765 do not · 3.3%
Tolerance 0.1 pt · 20 of the 1,765 have a zero-valued dimension; the rest have a median gap of 0.15 pt

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.

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.