第四章 选股模型构建:打分法、回归法与机器学习

各位同学,今天我们来聊聊选股模型的核心构建方法。说实话,这部分内容是我在量化投资领域摸爬滚打多年后,觉得最有意思也最实用的部分。你想想看,选股这件事,本质上就是给股票排个序——谁该买,谁该卖,谁该持有。但怎么排,这里面的门道可就多了。

我个人习惯把选股模型分成三大流派:打分法、回归法、机器学习法。这三种方法各有千秋,咱们一个一个来看。

4.1 打分法选股:最直观的排序逻辑

打分法,说白了就是给每个股票打个分。你设定几个因子,比如市盈率、市净率、ROE、动量等,然后给每个因子分配权重,最后加权求和得到一个总分。分数高的股票就买,分数低的就卖。

我在项目中遇到过这样一个案例:某私募团队用打分法做沪深300增强,选了5个因子,每个因子权重相等。结果跑下来,超额收益还不错,但回撤有点大。后来我帮他们调整了权重——把估值因子的权重从20%提到35%,动量因子降到10%,效果立马好了不少。

打分法的核心步骤其实很简单:

  1. 因子选择:选哪些因子?这取决于你的投资哲学。价值派喜欢PE、PB、股息率;成长派喜欢营收增速、利润增速;技术派喜欢动量、反转、波动率。
  2. 因子标准化:不同因子的量纲不同,必须标准化。我常用的是Z-score或者百分位排名。
  3. 权重分配:等权、专家赋权、还是优化求解?这里我建议先用等权跑一遍,看看效果再说。
  4. 综合打分:加权求和,得到每个股票的总分。
  5. 选股与调仓:选总分最高的N只股票,定期调仓。

重要提示:打分法的优势在于透明、可解释。你很清楚为什么买了某只股票——因为它分数高。但缺点也很明显:因子之间的相关性没处理,权重设定比较主观。

我的小技巧:打分法里,我习惯用「分层回测」来验证因子有效性。把股票按分数分成10组,看最高分组是否跑赢最低分组。如果跑赢了,说明你的打分逻辑是有效的。

4.2 回归法选股:用历史预测未来

回归法比打分法更「数学」一点。它的思路是:用历史数据去拟合一个模型,然后用这个模型去预测未来的收益。

具体来说,我们做的是截面回归。什么意思呢?就是在每个时间点,用所有股票的因子值去回归它们下一期的收益。回归系数就是每个因子的「权重」——注意,这个权重不是人定的,是数据算出来的。

我记得有一次,我用回归法做中证500的选股模型。跑了三年数据,发现动量因子的系数一直是正的,但突然某个月变成了负的。我当时吓了一跳,后来一查,原来是市场风格切换了。嗯,这里要注意:回归法的系数是不稳定的,需要定期重新估计。

回归法的代码实现其实不复杂:

import statsmodels.api as sm
import pandas as pd

# 假设 factors 是因子数据,returns 是下一期收益
# 每个时间点做一次截面回归
def cross_sectional_regression(factors, returns):
    # 添加截距项
    X = sm.add_constant(factors)
    y = returns
    
    # OLS回归
    model = sm.OLS(y, X).fit()
    
    # 返回系数
    return model.params

# 滚动回归:每个月重新估计一次
def rolling_regression(factor_data, return_data, window=12):
    coefs = []
    for i in range(window, len(factor_data)):
        # 取过去window个月的数据
        X = factor_data.iloc[i-window:i]
        y = return_data.iloc[i-window:i]
        
        # 回归
        coef = cross_sectional_regression(X, y)
        coefs.append(coef)
    
    return pd.DataFrame(coefs)

避坑指南:我曾经犯过一个错误——直接用全部历史数据做一次回归,然后用这个固定系数去选股。结果市场风格一变,模型立马失效。后来我改成滚动回归,每个月重新估计系数,效果才稳定下来。

4.3 机器学习选股:随机森林与XGBoost

机器学习选股,说白了就是让算法自己去「学习」因子和收益之间的关系。你不需要假设线性关系,也不需要手动设定权重。算法会自己找到最有效的因子组合和交互作用。

我个人最常用的两个模型是随机森林和XGBoost。为什么是它们?因为这两个模型对金融数据特别友好——能处理非线性关系,能自动做特征选择,而且不容易过拟合(当然,前提是你调参得当)。

4.3.1 随机森林:集成学习的入门之选

随机森林的原理很简单:构建很多棵决策树,每棵树用不同的样本和不同的特征,最后取所有树的平均预测值。你想想看,一棵树可能过拟合,但1000棵树平均下来,过拟合的风险就大大降低了。

我在项目中遇到过这样一个场景:用随机森林做全A股的选股模型,输入了50多个因子。结果跑完特征重要性分析,发现排名前5的因子里,有3个是估值类因子,2个是动量类因子。这个结果和我的直觉完全一致——说明模型学到的规律是合理的。

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split

# 准备数据
X = factor_data.values  # 因子矩阵
y = return_data.values  # 下一期收益

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 训练随机森林
rf = RandomForestRegressor(
    n_estimators=500,      # 树的数量
    max_depth=5,           # 最大深度
    min_samples_leaf=50,   # 叶子节点最小样本数
    random_state=42
)
rf.fit(X_train, y_train)

# 查看特征重要性
importance = pd.DataFrame({
    'feature': factor_columns,
    'importance': rf.feature_importances_
}).sort_values('importance', ascending=False)

我的经验:随机森林里,min_samples_leaf这个参数特别重要。设得太小容易过拟合,设得太大又欠拟合。我一般从50开始试,根据验证集的表现调整。

4.3.2 XGBoost:梯度提升的王者

XGBoost是梯度提升树的一种高效实现。和随机森林不同,XGBoost是串行训练的——每棵新树都在纠正前一棵树的错误。这种「纠错」机制让XGBoost的预测精度通常比随机森林更高。

但要注意,精度高不代表一定好用。XGBoost的调参比随机森林复杂得多,而且更容易过拟合。我刚开始用XGBoost时,就吃过这个亏——训练集上R²高达0.8,测试集上只有0.1。后来加了正则化参数,才把过拟合压下去。

import xgboost as xgb

# 转换数据格式
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)

# 设置参数
params = {
    'objective': 'reg:squarederror',
    'max_depth': 4,           # 树深度,不宜过大
    'eta': 0.05,              # 学习率
    'subsample': 0.8,         # 样本采样比例
    'colsample_bytree': 0.8,  # 特征采样比例
    'lambda': 1.0,            # L2正则化
    'alpha': 0.1,             # L1正则化
    'seed': 42
}

# 训练模型
model = xgb.train(
    params,
    dtrain,
    num_boost_round=500,
    evals=[(dtrain, 'train'), (dtest, 'test')],
    early_stopping_rounds=50,
    verbose_eval=False
)

# 预测
y_pred = model.predict(dtest)

避坑指南:我曾经用XGBoost做选股时,发现模型在测试集上的表现时好时坏。后来排查发现,是因为我没有做时间序列的交叉验证——直接用随机划分的训练集和测试集,导致未来数据泄露。记住:金融数据必须按时间顺序划分,不能用随机划分。

4.4 三种方法的对比与选择

说了这么多,你可能会问:到底该用哪种方法?我的建议是:

方法 优点 缺点 适用场景
打分法 透明、可解释、易实现 权重主观、忽略因子交互 起步阶段、需要向客户解释
回归法 数据驱动、有统计基础 假设线性、系数不稳定 因子数量少、关系较线性
随机森林 非线性、抗过拟合、特征选择 可解释性差、调参复杂 因子多、关系复杂
XGBoost 精度高、速度快、正则化好 易过拟合、调参更复杂 追求极致精度、有足够数据

我个人习惯是:先用打分法快速验证因子有效性,再用回归法做初步优化,最后用XGBoost提升精度。这样既保证了可解释性,又兼顾了预测能力。

4.5 本章知识体系图

下面这张图展示了本章的核心知识结构,你可以看到三种选股方法之间的关系和各自的关键要素:

选股模型构建:三大方法对比 选股模型 打分法 回归法 机器学习 因子选择 标准化 权重分配 截面回归 滚动估计 系数更新 随机森林 XGBoost 调参优化 核心原则:先简单后复杂,先解释后精度 打分法:透明可解释,适合起步 回归法:数据驱动,适合中等复杂度 机器学习:高精度,适合复杂关系挖掘

好了,以上就是选股模型构建的三种核心方法。打分法简单直观,回归法有统计基础,机器学习则能挖掘更深层的规律。我个人建议你从打分法入手,逐步过渡到更复杂的方法。毕竟,在量化投资这个领域,理解模型比堆砌模型更重要。

记住:没有最好的模型,只有最适合你当前场景的模型。多试、多调、多复盘,这才是量化策略研究的真谛。

专注资料整理