一、核心应用场景
在因子研究中,scikit-learn
主要解决以下几类问题:
-
因子预处理与标准化 :
StandardScaler
,RobustScaler
-
因子有效性分析 :
LinearRegression
(IC分析) -
降维与因子合成 :
PCA
,FactorAnalysis
-
机器学习预测模型 :
LinearRegression
,Ridge
,Lasso
,ElasticNet
,RandomForest
,GradientBoosting
(XGBoost/LightGBM 更常用,但思想一致) -
特征选择 :
SelectKBest
,SelectFromModel
-
聚类分析 :
KMeans
(用于股票分类或市场状态识别)
二、完整实战流程与代码示例
我们以一个完整的流程来演示:从因子计算开始,到最终生成预测信号。
步骤 1:准备数据与计算基础因子
假设我们已有股票价格数据 df_prices
和成交量数据 df_volumes
。
python
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline
from sklearn.feature_selection import SelectKBest, f_regression
# 假设 df_prices 是股票价格DataFrame,索引为日期,列为股票代码
# 假设 df_volumes 是成交量DataFrame,结构相同
# 计算一些常见的技术因子
def calculate_factors(prices, volumes):
"""
计算一系列因子
"""
factors_df = pd.DataFrame(index=prices.index)
# 1. 价格动量因子 (过去5天收益率)
factors_df['momentum_5'] = prices.pct_change(5).iloc[-1] # 取最近一天的值
# 2. 波动率因子 (过去20天收益率的标准差)
factors_df['volatility_20'] = prices.pct_change().rolling(20).std().iloc[-1]
# 3. 成交量加权平均价格 (VWAP) 因子
typical_price = (prices['high'] + prices['low'] + prices['close']) / 3
factors_df['vwap_ratio'] = (prices['close'] / (typical_price.rolling(20).mean())).iloc[-1]
# 4. 相对强弱指数 (RSI) 因子
delta = prices['close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
rs = gain / loss
factors_df['rsi'] = 100 - (100 / (1 + rs)).iloc[-1]
# 5. 布林带位置因子
rolling_mean = prices['close'].rolling(20).mean()
rolling_std = prices['close'].rolling(20).std()
factors_df['bollinger_position'] = ((prices['close'] - rolling_mean) / (2 * rolling_std)).iloc[-1]
return factors_df
# 为每只股票计算因子
all_factors = {}
for ticker in df_prices.columns:
# 这里需要为每只股票准备包含 OHLC 数据的数据框
# 假设我们有一个字典 stock_data,包含每只股票的OHLCV数据
stock_data = get_stock_data(ticker) # 这是一个假设的函数
factors = calculate_factors(stock_data, stock_data['volume'])
all_factors[ticker] = factors
# 将所有股票的因子合并成一个大的因子矩阵
factor_matrix = pd.DataFrame(all_factors).T # 索引为股票代码,列为因子
步骤 2:因子预处理与标准化
python
# 处理缺失值
factor_matrix = factor_matrix.dropna()
# 初始化标准化器
scaler = StandardScaler()
# 标准化因子数据
factor_scaled = scaler.fit_transform(factor_matrix)
# 转换回DataFrame
factor_scaled_df = pd.DataFrame(
factor_scaled,
index=factor_matrix.index,
columns=factor_matrix.columns
)
print("标准化后的因子数据:")
print(factor_scaled_df.head())
步骤 3:因子有效性分析 (IC分析)
python
# 假设我们有下期收益率数据 (目标变量)
# next_period_returns 是一个Series,索引为股票代码,值为下期收益率
# 确保因子和目标变量的股票代码对齐
common_index = factor_scaled_df.index.intersection(next_period_returns.index)
X = factor_scaled_df.loc[common_index]
y = next_period_returns.loc[common_index]
# 计算信息系数 (IC) - 因子与未来收益率的相关系数
ic_values = {}
for factor in X.columns:
ic = np.corrcoef(X[factor], y)[0, 1]
ic_values[factor] = ic
# 排序并显示IC值
ic_series = pd.Series(ic_values).sort_values(ascending=False)
print("因子IC值:")
print(ic_series)
# IC值绝对值大于0.05通常认为有一定预测能力
significant_factors = ic_series[abs(ic_series) > 0.05].index.tolist()
print(f"\n显著因子 ({len(significant_factors)}个): {significant_factors}")
步骤 4:因子降维与合成 (PCA)
python
# 使用PCA合成因子
pca = PCA(n_components=3) # 提取3个主成分
factors_pca = pca.fit_transform(X)
# 查看主成分的方差解释比例
print("主成分方差解释比例:", pca.explained_variance_ratio_)
# 查看每个主成分的因子载荷
pca_components_df = pd.DataFrame(
pca.components_,
columns=X.columns,
index=[f'PC{i+1}' for i in range(pca.n_components_)]
)
print("\n主成分因子载荷:")
print(pca_components_df)
# 将主成分作为新因子
X_pca = pd.DataFrame(factors_pca,
index=X.index,
columns=[f'PC{i+1}' for i in range(pca.n_components_)]
步骤 5:构建机器学习预测模型
python
# 划分训练集和测试集 (按时间划分更合适,这里简单随机划分)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 方法1: 线性回归模型
lr_model = LinearRegression()
lr_model.fit(X_train, y_train)
# 查看因子权重
lr_weights = pd.Series(lr_model.coef_, index=X.columns).sort_values(ascending=False)
print("线性回归因子权重:")
print(lr_weights)
# 方法2: 随机森林模型
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)
# 查看特征重要性
rf_importance = pd.Series(rf_model.feature_importances_,
index=X.columns).sort_values(ascending=False)
print("\n随机森林因子重要性:")
print(rf_importance)
# 评估模型
lr_score = lr_model.score(X_test, y_test)
rf_score = rf_model.score(X_test, y_test)
print(f"\n模型R²分数: 线性回归={lr_score:.4f}, 随机森林={rf_score:.4f}")
步骤 6:使用Pipeline构建完整因子处理流程
python
# 创建一个完整的处理管道
pipeline = Pipeline([
('scaler', StandardScaler()),
('feature_selection', SelectKBest(score_func=f_regression, k=5)), # 选择最好的5个因子
('regressor', RandomForestRegressor(n_estimators=100, random_state=42))
])
# 训练管道
pipeline.fit(X_train, y_train)
# 获取选择的因子
selected_mask = pipeline.named_steps['feature_selection'].get_support()
selected_factors = X.columns[selected_mask].tolist()
print(f"管道选择的因子: {selected_factors}")
# 测试管道性能
pipeline_score = pipeline.score(X_test, y_test)
print(f"管道模型R²分数: {pipeline_score:.4f}")
步骤 7:生成预测信号与选股
python
# 使用训练好的模型对所有股票进行预测
current_factors = factor_scaled_df # 当前时点的因子数据
# 确保没有训练时未见过的股票
current_factors = current_factors[current_factors.index.isin(X.index)]
# 生成预测
predictions = pipeline.predict(current_factors)
# 创建预测结果DataFrame
prediction_df = pd.DataFrame({
'ticker': current_factors.index,
'predicted_return': predictions
}).sort_values('predicted_return', ascending=False)
print("预测收益率排名前10的股票:")
print(prediction_df.head(10))
# 生成买入信号 (例如预测收益率最高的前20%股票)
threshold = prediction_df['predicted_return'].quantile(0.8)
buy_signals = prediction_df[prediction_df['predicted_return'] >= threshold]
print(f"\n买入信号股票 ({len(buy_signals)}只):")
print(buy_signals)
三、不同机器学习模型在因子研究中的特点
模型类型 | 代表算法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
线性模型 | LinearRegression , Ridge , Lasso |
可解释性强,速度快 | 只能捕捉线性关系 | 因子加权,初步筛选 |
树模型 | RandomForest , GradientBoosting |
捕捉非线性关系,抗过拟合较好 | 可解释性较差 | 主力预测模型 |
降维方法 | PCA , FactorAnalysis |
去除因子间多重共线性,提取核心特征 | 失去因子经济意义 | 因子合成,数据预处理 |
特征选择 | SelectKBest , SelectFromModel |
简化模型,提高泛化能力 | 可能遗漏重要因子 | 因子筛选 |
四、关键注意事项
-
避免前视偏差:确保在任何时间点,因子计算只使用当时及之前的信息。
-
过拟合问题:金融数据信噪比极低,务必使用严格的交叉验证(时间序列CV)。
-
因子可解释性:尽管机器学习强大,但最好能理解因子背后的经济逻辑。
-
数据质量:确保因子计算准确,处理缺失值和异常值。
-
基准对比:始终与简单策略(如市值加权)对比,确保模型真正增加价值。
五、进阶方向
-
集成学习:结合多个模型的预测结果(Stacking、Blending)。
-
深度学习:使用神经网络处理高维因子数据或另类数据。
-
强化学习:用于动态资产配置和择时。
-
自然语言处理:分析文本数据(新闻、财报)生成情感因子。
这个框架提供了使用 scikit-learn
进行股票因子研究的完整流程。实际应用中,你需要根据具体需求调整因子计算方法、模型参数和评估标准。