From a formula to a full regression
statsmodels.formula.api.ols('excess ~ mkt_rf + smb + hml', data=table).fit() fits an ordinary least squares regression from a one-line formula: the name on the left of ~ is the thing to explain, the names on the right are the regressors, and an intercept is added for you (write - 1 to remove it). The result object holds everything: params (the coefficients), bse (their standard errors), tvalues, pvalues, rsquared, rsquared_adj, aic, resid and summary() for the printed report. Because every one of these is a pandas Series or a number, putting them side by side in a DataFrame gives a clean table, and res.predict(new_frame) applies the fitted formula to new rows with the same column names. The factor regression of a stock is the standard use: excess is the stock's return above the risk-free rate, mkt_rf the market's, smb the size factor and hml the value factor.
Two comparisons make the table useful. The CAPM uses only the market, excess ~ mkt_rf; the three-factor model adds smb and hml. Adding regressors can never lower R², so use the adjusted R², the AIC, or an F test: ff3.compare_f_test(capm) returns the F statistic, its p-value and the number of extra regressors, and a small p-value says the two extra factors add real explanatory power. A second routine point is the table itself. Month-end returns come from the last close of each calendar month (prices.groupby(prices.index.to_period('M')).last() then pct_change()), and they must be joined to the factor table on the same month: a regression on misaligned months is a regression on noise.
- One line, one regression: the formula names the response and the regressors, and the results object holds every statistic.
- Compare nested models with the right tool: R-squared always rises, so use adjusted R-squared, AIC or the F test.
- Align the months first: a month-end return belongs with the factors of the same month.
Lab · what's graded
- The monthly regression table15 pts
- The CAPM fit10 pts
- The three-factor fit10 pts
- A tidy coefficient table15 pts
- Is the bigger model worth it?15 pts
- A prediction10 pts
- The whole study25 pts