🚀 AI 一键生成 joinquant 策略代码

JoinQuant 因子预处理教程:如何对因子数据进行 Z-Score 标准化?

joinquant | 发布时间: 2025/12/18
以下内容由 EasyQuant 生成。

问题描述

如何对我的因子数据进行Z-Score标准化处理?

解决方案

在聚宽(JoinQuant)平台中,对因子数据进行 Z-Score 标准化(即去均值后除以标准差,使数据均值为0,标准差为1),最直接且推荐的方法是使用 jqfactor 库中的 standardlize 函数。

Z-Score 标准化方法

1. 使用 jqfactor.standardlize 函数(推荐)

这是聚宽专门为因子处理提供的函数,能够自动处理 inf(无穷大)值,并支持按行(截面)或按列(时间序列)进行标准化。

函数说明:
standardlize(data, inf2nan=True, axis=1)

  • data: 输入的 pd.Seriespd.DataFrame
  • inf2nan: 是否将 inf 替换为 NaN(默认为 True,推荐开启以避免计算错误)。
  • axis:
    • 1:对每行做标准化(通常用于截面标准化,即同一时间点下不同股票间的标准化)。
    • 0:对每列做标准化(通常用于时间序列标准化,即同一股票在不同时间点间的标准化)。

2. 代码示例

以下代码展示了如何获取沪深300成分股的市值数据,并对其进行 Z-Score 标准化处理。

# -*- coding: utf-8 -*-
from jqdata import *
from jqfactor import standardlize
import pandas as pd
import numpy as np

def initialize(context):
    # 设定基准
    set_benchmark('000300.XSHG')
    # 运行函数
    run_daily(factor_process, '09:30')

def factor_process(context):
    # 1. 获取数据:以沪深300成分股的“总市值”为例
    stocks = get_index_stocks('000300.XSHG')
    
    # 获取市值数据 (market_cap)
    q = query(
        valuation.code,
        valuation.market_cap
    ).filter(
        valuation.code.in_(stocks)
    )
    
    df = get_fundamentals(q, date=context.previous_date)
    
    # 将股票代码设为索引,方便处理
    if not df.empty:
        df.set_index('code', inplace=True)
        
        # 获取因子序列 (Series类型)
        raw_factor = df['market_cap']
        
        # 2. 执行 Z-Score 标准化
        # 对于 Series,standardlize 会直接计算 (x - mean) / std
        std_factor = standardlize(raw_factor, inf2nan=True)
        
        # 打印结果对比
        print("--- 原始因子前5行 ---")
        print(raw_factor.head())
        print("\n--- Z-Score标准化后前5行 ---")
        print(std_factor.head())
        
        # 验证标准化结果(均值应接近0,标准差应接近1)
        print(f"\n标准化后均值: {std_factor.mean():.4f}")
        print(f"标准化后标准差: {std_factor.std():.4f}")
    else:
        print("未获取到数据")

补充说明:手动实现

如果你不想使用 jqfactor 库,也可以利用 pandas 原生方法实现 Z-Score 标准化,公式为 $z = \frac{x - \mu}{\sigma}$。

# 手动实现 Z-Score (针对 Series)
mean_val = raw_factor.mean()
std_val = raw_factor.std()
z_score_factor = (raw_factor - mean_val) / std_val

但在聚宽环境中,建议优先使用 jqfactor.standardlize,因为它额外处理了边界情况(如无穷大值),在量化回测中更加稳健。


Q&A

Q: 为什么要对因子进行 Z-Score 标准化?
A: 不同因子的量纲(单位)和数量级差异很大(例如股价可能是几十元,而市值可能是几百亿)。标准化可以将不同分布的因子转换为同一尺度(均值为0,标准差为1),从而使它们具有可比性,便于后续进行多因子合成或机器学习模型训练。

Q: standardlize 函数中的 axis=1axis=0 有什么区别?
A: 当输入数据是 DataFrame 时:

  • axis=1 表示截面标准化(Cross-sectional),即在同一时间点上,对所有股票的因子值进行标准化。这是多因子选股中最常用的方式。
  • axis=0 表示时间序列标准化(Time-series),即对单只股票在一段时间内的因子值进行标准化。

Q: 标准化之前需要去极值吗?
A: 通常建议先去极值,再标准化。因为 Z-Score 使用均值和标准差,这两个统计量对异常值(Outliers)非常敏感。如果数据中存在极端的异常值,会拉大标准差,导致正常数据的标准化值被压缩在很小的范围内。可以使用 jqfactor.winsorize 先进行去极值处理。