第 7 章 · 05 逻辑回归宏观数据 本节摘要:本节讲从回归转到分类的关键模型——逻辑回归(Logistic Regression),用于预测离散状态。前几节预测的是连续收益,本节预测「涨/跌」二元结果。逻辑回归用 sigmoid 把线性组合压到 (0,1) 区间解释为概率,用最大似然估计系数。本节用两个场景演示:一是宏观经济学经典的「预测 GDP 增速是否高于滚动均值」(衰退 vs 扩张),用 statsmodels 看似然比检验、伪 R²;二是用 sklearn 配 MultipleTimeSeriesCV 预测股票涨跌,用 AUC(ROC 曲线下面积)和 IC 双指标评估正则化强度 C 的影响。逻辑回归是金融分类的强基线,和第 01 节的线性回归基线遥相呼应。
本节摘要:本节讲从回归转到分类的关键模型——逻辑回归(Logistic Regression),用于预测离散状态。前几节预测的是连续收益,本节预测「涨/跌」二元结果。逻辑回归用 sigmoid 把线性组合压到 (0,1) 区间解释为概率,用最大似然估计系数。本节用两个场景演示:一是宏观经济学经典的「预测 GDP 增速是否高于滚动均值」(衰退 vs 扩张),用 statsmodels 看似然比检验、伪 R²;二是用 sklearn 配 MultipleTimeSeriesCV 预测股票涨跌,用 AUC(ROC 曲线下面积)和 IC 双指标评估正则化强度 C 的影响。逻辑回归是金融分类的强基线,和第 01 节的线性回归基线遥相呼应。
内容来源:原项目
ch07/07_logistic_regression_macro_data.ipynb、08_predicting_price_movements_with_logistic_regression.ipynb,汉化并套用体系化模板。
⚠️ 风险提示:宏观预测样本极少(季度数据几十年才几百点),过拟合风险极高,任何高准确率都要怀疑样本量不足。涨跌二分类接近随机(50%),AUC >0.55 已属优秀。
阅读完本节,你应当能够:
前面几节预测的是连续收益(回归问题)。但很多金融问题是二元的:
这类问题用分类模型。最基础的分类模型是逻辑回归(logistic regression),它名字里有「回归」却是分类——因为它回归的是「属于正类的概率」。
逻辑回归用 sigmoid 函数把线性组合 z = β₀ + β⊤x 压缩到 (0,1):
逻辑回归不用最小二乘,而用最大似然(MLE):找一组 β,让观测到的标签在模型下概率最大。对数似然:
这是凸函数,梯度下降或牛顿法都能解。statsmodels 用牛顿法,sklearn 用 LIBLINEAR/SAGA。
💡 核心心法:逻辑回归仍是「线性」的——决策边界是 x 的超平面。它只是把线性组合映射成概率,本质和第 01 节的线性回归同源,所以同样享有可解释、低方差、强基线的优点。
07 notebook 用 statsmodels 内置的 macrodata(美国宏观经济季度数据)。变量含 realgdp、realcons、realinv、unemp、infl 等。目标是构造二分类:
import statsmodels.api as sm data = pd.DataFrame(sm.datasets.macrodata.load().data) # 二分类标签:GDP 增速是否高于其 20 季度滚动均值(扩张=1, 衰退=0) data['growth_rate'] = data.realgdp.pct_change(4) data['target'] = (data.growth_rate > data.growth_rate.rolling(20).mean()).astype(int).shift(-1)
shift(-1) 把「下季度是否扩张」对齐到当前季度的特征——我们用本季度宏观指标预测下季度的状态。这是前向标签,不能漏 shift。
特征工程:把消费、投资、政府支出等变量变成同比增长率,季度做虚拟变量:
pct_cols = ['realcons', 'realinv', 'realgovt', 'realdpi', 'm1'] data.loc[:, pct_cols] = data.loc[:, pct_cols].pct_change(4) data = pd.get_dummies(data.drop(['year', 'realgdp', 'pop', 'cpi', 'growth_rate'], axis=1), columns=['quarter'], drop_first=True).dropna()
model = sm.Logit(data.target, sm.add_constant(data.drop('target', axis=1))) result = model.fit() print(result.summary())
statsmodels 的 Logit summary 输出和 OLS 类似,但有几个分类专属指标:
| 指标 | 含义 |
|---|---|
| Log-Likelihood | 最大化对数似然值 |
| LL-Null | 仅截距模型的对数似然(基线) |
| LLR p-value | 似然比检验,类似 F 检验,模型整体显著性 |
| Pseudo R² | (LL_Null - LL_full)/LL_Null,类比 R²,值域 [0,1] |
| coef / P>|z| | 系数和 z 检验 p 值 |
Pseudo R² 是分类版的「拟合优度」:0 表示模型不比「总猜多数类」好,1 表示完美拟合。宏观这种小样本,Pseudo R² 0.3~0.5 已属不错。
⚠️ 小样本陷阱:宏观数据 200 个季度点,塞 13 个变量很容易过拟合,LLR 显著不代表样本外可用。务必留出 holdout 或做时序 CV。
08 notebook 用 sklearn 预测股票涨跌,严格用 MultipleTimeSeriesCV(第 6 章):
from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from utils import MultipleTimeSeriesCV train_period_length = 63 test_period_length = 10 lookahead = 1 n_splits = int(3 * 252 / test_period_length) cv = MultipleTimeSeriesCV(n_splits=n_splits, test_period_length=test_period_length, lookahead=lookahead, train_period_length=train_period_length) # 二分类标签:1 天前向收益 > 0 y.loc[:, 'label'] = (y['target_1d'] > 0).astype(int)
逻辑回归的正则化强度用 C(= 1/α,C 越小正则越强)。扫一组 C:
from sklearn.metrics import roc_auc_score from scipy.stats import spearmanr Cs = np.logspace(-5, 5, 11) log_scores = [] for C in Cs: model = LogisticRegression(C=C, fit_intercept=True, random_state=42) pipe = Pipeline([('scaler', StandardScaler()), ('model', model)]) for train_idx, test_idx in cv.split(X): pipe.fit(X.iloc[train_idx], y.label.iloc[train_idx]) y_score = pipe.predict_proba(X.iloc[test_idx])[:, 1] # 正类概率 y_test = y.label.iloc[test_idx] actuals = y['target_1d'].iloc[test_idx] # 分类指标:AUC auc = roc_auc_score(y_score=y_score, y_true=y_test) # 回归式指标:概率与实际收益的 Spearman IC ic, pval = spearmanr(y_score, actuals) log_scores.append([C, date, auc, ic * 100, pval])
两个指标各有侧重:
| 指标 | 衡量 | 范围 | 金融含义 |
|---|---|---|---|
| AUC | 分类排序能力 | [0.5, 1.0] | 0.5=随机,0.55+可用,0.6+优秀 |
| IC | 概率与连续收益的相关 | [-1, 1] | 与回归模型可比 |
💡 为何同时看 AUC 和 IC:AUC 只看「涨/跌分类对不对」,IC 看「概率排序与涨幅大小的相关性」。一个 AUC 0.55 但 IC 0.04 的模型,虽然分类只比随机好一点点,但作为连续信号配多空组合可能很赚钱。两个指标互补,不可偏废。
把不同 C 下的 AUC 画出来,典型形状是「倒 U」:C 太小(强正则)欠拟合,AUC 接近 0.5;C 太大(无正则)过拟合,样本外 AUC 也下降;中间有个最优 C。
log_scores.groupby('C').auc.describe() # 画 mean AUC vs log(C)
IC 分布图则显示最优 C 下 IC 的均值和中位数——均值高但中位数低说明 IC 被少数极端日拉高,稳定性差。
| 维度 | 线性回归(第 01~03 节) | 逻辑回归(本节) |
|---|---|---|
| 目标 | 连续收益 | 涨/跌二元 |
| 损失 | 均方误差 | 对数损失(交叉熵) |
| 评估 | IC、R² | AUC、准确率、IC |
| 输出 | 收益预测 | 概率 + 类别 |
| 适用 | 排序选股 | 状态判断、择时 |
两者都是线性强基线。实务常并行训练:线性回归做选股排序,逻辑回归做仓位开关(择时)。
shift(-1) 把下季度状态对齐当前特征;股票用 1d 前向收益 >0。本章完。下一章我们进入「整合篇」——ML4T 端到端工作流,把本章的线性模型、第 5 章的回测、第 6 章的时序 CV 串成完整的可部署策略。