🚀 AI 一键生成 joinquant 策略代码
立即体验

聚宽 JoinQuant 因子预处理三步法:去极值、标准化与中性化实战指南

joinquant | 发布时间: 2026/7/22
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: joinquant 因子预处理三步法:去极值、标准化与中性化实战

Question: 请问在聚宽中对自定义因子进行中位数去极值、Z-score标准化和行业市值中性化的标准流程是什么?

解决方案

在多因子选股模型中,因子的预处理(去极值、标准化、中性化)是消除异常值影响、统一量纲并剔除行业与市值暴露的关键步骤。聚宽(JoinQuant)平台在其 jqfactor 库中提供了高效的内置函数,支持一站式完成这三步预处理。

以下是在聚宽中对自定义因子进行预处理的标准流程与实战代码:

一、 因子预处理标准三步法流程

  1. 第一步:去极值(Winsorization)

    • 目的:消除极值(异常大或异常小的值)对因子暴露和回归分析的干扰。
    • 方法:推荐使用中位数绝对偏差去极值法(MAD, Median Absolute Deviation),相比均值标准差法,它对极值本身更具鲁棒性。聚宽内置函数为 winsorize_med
  2. 第二步:标准化(Standardization / Z-score)

    • 目的:将不同量纲的因子值转化为均值为0、标准差为1的无量纲分布,便于因子合成与比较。
    • 方法:使用 Z-score 标准化。聚宽内置函数为 standardlize
  3. 第三步:中性化(Neutralization)

    • 目的:剔除因子在特定风险暴露(如行业分类、市值大小)上的偏差,获取纯净的超额收益因子。
    • 方法:通过线性回归,将因子值作为因变量,行业哑变量和对数市值作为自变量进行回归,取其残差作为中性化后的新因子值。聚宽内置函数为 neutralize

二、 聚宽 API 实战代码示例

以下代码展示了如何获取沪深300成分股的原始因子数据,并依次进行中位数去极值Z-score标准化以及行业与对数市值中性化

import pandas as pd
import numpy as np
from jqdata import *
# 导入聚宽因子预处理专用库
from jqfactor import winsorize_med, standardlize, neutralize

def preprocess_my_factor(context):
    # 1. 获取目标股票池(以沪深300为例)及当前日期
    date_str = context.current_dt.strftime('%Y-%m-%d')
    stocks = get_index_stocks('000300.XSHG', date=date_str)
    
    # 2. 获取您的自定义因子数据(此处以聚宽因子库中的 'Skewness60' 偏度因子作为示例)
    from jqfactor import get_factor_values
    raw_factor_dict = get_factor_values(
        securities=stocks, 
        factors=['Skewness60'], 
        start_date=date_str, 
        end_date=date_str
    )
    
    # 提取 DataFrame,行索引为日期,列索引为股票代码
    df_raw = raw_factor_dict['Skewness60']
    
    # 3. 因子预处理三步法
    
    # 【第一步】中位数去极值 (MAD)
    # scale=1 表示边界设为 [med - 3 * 1.4826 * MAD, med + 3 * 1.4826 * MAD]
    # axis=1 表示对每一行(即每天的横截面数据)进行处理
    df_winsorized = winsorize_med(df_raw, scale=1, inclusive=True, inf2nan=True, axis=1)
    
    # 【第二步】Z-score 标准化
    # 将去极值后的数据进行标准化,使其均值为0,标准差为1
    df_standardized = standardlize(df_winsorized, inf2nan=True, axis=1)
    
    # 【第三步】行业与市值中性化
    # how 传入中性化基准:'jq_l1' 代表聚宽一级行业,'market_cap' 代表总市值
    # 内部会自动将市值转化为对数市值进行回归
    df_neutralized = neutralize(
        df_standardized, 
        how=['jq_l1', 'market_cap'], 
        date=date_str, 
        axis=1
    )
    
    # 4. 输出处理后的纯净因子值
    log.info("原始因子样例:\n", df_raw.iloc[0].head())
    log.info("预处理后因子样例:\n", df_neutralized.iloc[0].head())
    
    return df_neutralized

三、 注意事项与最佳实践

  1. 顺序不可颠倒:必须先进行去极值,再进行标准化。如果先标准化,极值会严重拉拉大标准差,导致标准化后的非极值数据全部缩水。中性化通常放在最后一步。
  2. 避免未来数据:在回测或模拟盘中,date 参数必须传入当前逻辑日期(如 context.current_dt),切勿跨日期缓存或使用未来日期,否则会引入未来函数。
  3. 停牌股处理:在进行截面预处理前,建议剔除停牌、未上市或退市的股票,以保证截面回归中性化时的样本质量。