分析新旧因子相关性

计算一组新因子、并分析它们与已有因子间的相关性

  • 1. 导入库和初始化环境
    • 功能
    • 代码解析
    • 数据加载
  • 2. 定义新因子计算函数
    • 功能
    • 代码解析
      • 因子 1:波动率过滤器(`filter_001_1`)
      • 因子 2:ATR 过滤器(`filter_001_2`)
      • 因子 3:凯尔特纳通道(`filter_001_3`)
      • 其他因子
    • 因子映射
  • 3. 计算新因子并添加到数据框
    • 功能
    • 代码解析
  • 4. 计算相关系数矩阵
    • 功能
    • 代码解析
  • 5. 高相关性因子分析
    • 功能
    • 代码解析
    • 输出高相关性表格
  • 6. 相关性热力图可视化
    • 功能
    • 代码解析
  • 7. 加载同质异质分离数据(可选)
    • 功能
    • 代码解析
  • 8. 程序完成提示
    • 功能
    • 代码解析
  • 总结
    • 逻辑清晰性
  • 完整代码

程序的目标是计算一组新因子,并分析它们与已有因子(旧因子)之间的相关性,以评估新因子的独特性。


1. 导入库和初始化环境

功能

这一部分导入了必要的 Python 库,设置了工作环境,并加载了数据服务和因子数据,为后续计算和分析做准备。

代码解析

import sys
sys.path.append('/public/src')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from tqdm import tqdm
import joblib
import os
import warnings
warnings.filterwarnings('ignore')from factor_evaluation_server import FactorEvaluation, DataService
  • sys.path.append('/public/src'):将 /public/src 目录添加到 Python 的模块搜索路径,确保可以导入自定义模块(如 factor_evaluation_server)。
  • 导入库
    • numpypandas:用于数值计算和数据处理。
    • matplotlib.pyplotseaborn:用于数据可视化(如热力图)。
    • tqdm:显示进度条,方便监控循环进度。
    • joblib:用于加载/保存序列化数据。
    • os:用于文件路径操作。
    • warnings.filterwarnings('ignore'):忽略运行过程中的警告信息,以保持输出简洁。
  • 自定义模块:从 factor_evaluation_server 导入 FactorEvaluationDataService,可能是自定义的数据处理和因子评估工具。

数据加载

# 初始化数据服务
ds = DataService()
df = ds['ETHUSDT_15m_2020_2025']['2021-10-01':]# 读取已有因子数据
factor_path = "/public/data/factor_data/ETHUSDT_15m_2020_2025_factor_data.pkl"
factors = pd.read_pickle(factor_path)
  • DataService:初始化数据服务,加载 ETHUSDT_15m_2020_2025 数据集(可能是以太坊对美元的 15 分钟 K 线数据),并从 2021-10-01 开始切片。
  • factors:从 .pkl 文件加载已有因子数据,存储为 pandas.DataFrame
  • 时间索引处理
    if isinstance(factors.index, pd.DatetimeIndex) or factors.index.dtype == 'datetime64[ns]':factors = factors.reset_index(drop=True)
    
    检查因子数据是否具有时间索引,若有则重置为整数索引,确保后续计算时索引对齐。
  • 记录旧因子
    original_columns = factors.columns.tolist()
    print(f"加载了 {len(original_columns)} 个旧因子")
    
    保存旧因子的列名,并打印旧因子的数量。

2. 定义新因子计算函数

功能

这一部分定义了 20 个新因子计算函数,每个函数基于输入的 K 线数据(如 closehighlowvolume 等)生成一个新的因子。这些因子涵盖了波动率、成交量、价格位置、买卖压力等多个维度,用于量化交易策略的研究。

代码解析

以下是几个代表性因子的定义和解释(完整代码包含 20 个因子,这里仅解析部分以展示逻辑):

因子 1:波动率过滤器(filter_001_1

def calculate_filter_001_1(df):'''衡量当前波动率高低的过滤器'''log_ratio = np.log(df['close'] / df['close'].shift(1))hv = log_ratio.rolling(20).std()return hv
  • 功能:计算历史波动率(Historical Volatility, HV),基于收盘价的对数收益率在 20 个周期内的标准差。
  • 意义:衡量价格波动的剧烈程度,高波动率可能预示市场活跃或不稳定。

因子 2:ATR 过滤器(filter_001_2

def calculate_filter_001_2(df):'''ATR过滤器'''high_low = df['high'] - df['low']high_close = abs(df['high'] - df['close'].shift(1))low_close = abs(df['low'] - df['close'].shift(1))true_range = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)atr = true_range.rolling(14).mean()return atr
  • 功能:计算平均真实波幅(Average True Range, ATR),基于 14 个周期的真实波幅均值。
  • 意义:ATR 是衡量价格波动范围的常用指标,可用于设置止损或判断趋势强度。

因子 3:凯尔特纳通道(filter_001_3

def calculate_filter_001_3_keltner_channels(df, ema_period=20, atr_period=10, multiplier=2):'''凯尔特纳通道:基于ATR的波动通道'''ema = df['close'].ewm(span=ema_period, adjust=False).mean()high_low = df['high'] - df['low']high_close = abs(df['high'] - df['close'].shift(1))low_close = abs(df['low'] - df['close'].shift(1))true_range = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)atr = true_range.ewm(span=atr_period, adjust=False).mean()channel_width = multiplier * atrreturn (df['close'] - (ema - channel_width)) / (2 * channel_width)
  • 功能:计算凯尔特纳通道(Keltner Channels),基于指数移动平均线(EMA)和 ATR,衡量价格相对于通道的位置。
  • 意义:标准化后的值(范围 0-1)表示价格在通道中的相对位置,可用于判断超买或超卖。

其他因子

  • filter_002_1:成交量偏差,衡量当前成交量相对于 20 周期均值的偏离程度。
  • filter_002_2_obv:能量潮指标(On-Balance Volume, OBV),基于价格方向和成交量的累积指标。
  • filter_010_1:相对强弱指数(RSI),衡量价格超买或超卖状态。
  • filter_011:MACD,衡量短期和长期趋势的差异。
  • 更多因子:包括量价趋势、阿隆指标、Chaikin 资金流等,涵盖了技术分析的多个方面。

因子映射

factor_calculators = {'filter_001_1': calculate_filter_001_1,'filter_001_2': calculate_filter_001_2,# ... 其他因子映射
}
  • 将因子名称与对应的计算函数映射,方便后续批量计算。

3. 计算新因子并添加到数据框

功能

这一部分遍历所有新因子计算函数,计算因子值并将其添加到因子数据框中,同时处理可能的长度不匹配或计算错误。

代码解析

print("\n开始计算新因子...")
for factor_name, calculator in tqdm(factor_calculators.items(), desc="计算因子"):try:factor_values = calculator(df)if isinstance(factor_values, pd.Series):if len(factor_values) != len(factors):factor_values = factor_values.iloc[:len(factors)].reset_index(drop=True)factors[factor_name] = factor_values.valueselse:if len(factor_values) != len(factors):factor_values = factor_values[:len(factors)]factors[factor_name] = factor_valuesexcept Exception as e:print(f"计算因子 {factor_name} 时出错: {str(e)}")factors[factor_name] = np.nan
  • 遍历计算:使用 tqdm 显示进度条,逐个调用因子计算函数。
  • 长度对齐
    • 如果计算结果是 pd.Series,确保其长度与 factors 一致,必要时截断并重置索引。
    • 如果是 numpy 数组,同样截断以匹配长度。
  • 错误处理:捕获异常并打印错误信息,将出错的因子列填充为 NaN,避免程序中断。
  • 索引重置
    factors = factors.reset_index(drop=True)
    
    确保因子数据框使用整数索引,统一数据结构。

4. 计算相关系数矩阵

功能

计算所有因子(包括新旧因子)之间的相关系数矩阵,并提取新因子与旧因子之间的相关性,用于后续分析。

代码解析

print("\n计算相关系数矩阵...")
corr_matrix = factors.corr()
new_factors = list(factor_calculators.keys())
old_factors = original_columns
new_to_old_corr = corr_matrix.loc[new_factors, old_factors]
  • factors.corr():计算因子数据框的皮尔逊相关系数矩阵。
  • new_to_old_corr:提取新因子(行)与旧因子(列)的相关性子矩阵,聚焦于新因子与旧因子的关系。

5. 高相关性因子分析

功能

筛选出新因子与旧因子之间绝对相关系数超过阈值(0.7)的因子对,记录并输出高相关性信息。

代码解析

threshold = 0.7
high_corr_records = []print(f"\n高相关性因子分析 (新因子与旧因子, |corr| > {threshold}):")
for new_factor in new_factors:corr_series = new_to_old_corr.loc[new_factor]high_corr = corr_series[abs(corr_series) > threshold]if not high_corr.empty:print(f"\n🔍 {new_factor} 与以下旧因子有高相关性:")for factor, corr_value in high_corr.items():strength = "强" if abs(corr_value) > 0.8 else "中等"direction = "正" if corr_value > 0 else "负"print(f"  - {factor}: {corr_value:.4f} ({strength}{direction}相关)")high_corr_records.append({'新因子': new_factor,'旧因子': factor,'相关系数': corr_value,'相关强度': strength,'相关方向': direction})
  • 阈值设置:相关系数绝对值大于 0.7 被认为是高相关。
  • 筛选高相关性:对于每个新因子,检查其与旧因子的相关系数是否超过阈值。
  • 记录信息:将高相关性因子对的信息(新因子、旧因子、相关系数、强度、方向)存储在 high_corr_records 列表中。
  • 强度与方向
    • 相关系数绝对值 > 0.8:强相关。
    • 相关系数绝对值 0.7-0.8:中等相关。
    • 正/负相关:根据相关系数的正负判断。

输出高相关性表格

if high_corr_records:high_corr_df = pd.DataFrame(high_corr_records)print("\n📊 高相关性因子汇总表 (新因子 vs 旧因子):")display(high_corr_df[['新因子', '旧因子', '相关系数', '相关强度', '相关方向']].sort_values(by='相关系数', key=abs, ascending=False).style.background_gradient(cmap='coolwarm', subset=['相关系数']).format({'相关系数': "{:.4f}"}).set_caption(f"高相关性因子汇总 (|corr| > {threshold})"))
else:print(f"\n✅ 未发现高相关性新因子与旧因子 (|corr| > {threshold})")
  • 表格生成:将高相关性记录转换为 pd.DataFrame
  • 美化输出
    • 按相关系数绝对值降序排序。
    • 使用 coolwarm 颜色映射突出相关系数的大小。
    • 格式化相关系数保留 4 位小数。
  • 空结果处理:如果没有高相关性因子对,输出提示信息。

6. 相关性热力图可视化

功能

通过热力图可视化新因子与旧因子之间的相关系数,直观展示相关性强弱。

代码解析

plt.figure(figsize=(18, 12))
sns.heatmap(new_to_old_corr,annot=True,fmt=".2f",cmap='coolwarm',center=0,vmin=-1,vmax=1,linewidths=0.5
)
plt.title('新因子与旧因子的相关性热力图', fontsize=16, pad=20)
plt.xlabel('旧因子', fontsize=12)
plt.ylabel('新因子', fontsize=12)
plt.xticks(rotation=90, fontsize=8)
plt.yticks(rotation=0, fontsize=8)
cbar = plt.gcf().axes[-1]
cbar.set_ylabel('相关系数', rotation=270, labelpad=20)
plt.tight_layout()
plt.show()
  • sns.heatmap:绘制相关系数热力图。
    • annot=True:在格子中显示相关系数数值(保留 2 位小数)。
    • cmap='coolwarm':使用红蓝渐变色,正相关为红色,负相关为蓝色。
    • center=0:以 0 为中心,区分正负相关。
    • vmin=-1, vmax=1:设置相关系数范围为 [-1, 1]。
  • 美化设置
    • 图表标题、轴标签、字体大小等优化显示效果。
    • X 轴标签旋转 90 度,Y 轴标签保持水平,增强可读性。
  • 显示:在 Jupyter Notebook 中直接展示热力图。

7. 加载同质异质分离数据(可选)

功能

尝试加载同质/异质因子分离数据(可能是预处理的分组信息),为后续分析提供参考。

代码解析

homo_hetero_path = "/public/data/factor_data/ETHUSDT_15m_2020_2025_homo_heter_split.joblib"
if os.path.exists(homo_hetero_path):try:homo_hetero_data = joblib.load(homo_hetero_path)print("\n加载同质异质分离数据成功!")except Exception as e:print(f"\n加载同质异质分离数据时出错: {str(e)}")
else:print("\n未找到同质异质分离数据文件")
  • 文件检查:使用 os.path.exists 检查文件是否存在。
  • 加载数据:使用 joblib.load 加载 .joblib 文件,存储同质/异质因子分组信息。
  • 错误处理:捕获加载过程中的异常并打印错误信息。
  • 备注:代码中未进一步使用 homo_hetero_data,可能是为后续分析预留的扩展点。

8. 程序完成提示

功能

输出程序完成的信息,提示分析任务结束。

代码解析

print("\n🎉 因子相关性分析完成!")
  • 打印完成信息,带有 emoji 增加友好性。

总结

该程序是一个完整的因子分析工作流,主要功能包括:

  1. 数据准备:加载 K 线数据和旧因子数据,统一索引格式。
  2. 新因子计算:定义并计算 20 个新因子,涵盖波动率、成交量、技术指标等。
  3. 相关性分析:计算新因子与旧因子的相关系数,筛选高相关性因子对(阈值 0.7)。
  4. 结果展示
    • 输出高相关性因子表格,包含相关系数、强度和方向。
    • 绘制相关性热力图,直观展示新旧因子之间的关系。
  5. 扩展性:支持加载同质/异质因子数据,为进一步分析预留空间。

逻辑清晰性

  • 模块化设计:因子计算函数独立定义,便于维护和扩展。
  • 错误处理:对数据长度、计算错误等进行了健壮处理。
  • 可视化:通过表格和热力图直观展示分析结果,方便用户理解。

完整代码

# %%
import sys
sys.path.append('/public/src')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from tqdm import tqdm
import joblib
import os
import warnings
warnings.filterwarnings('ignore')from factor_evaluation_server import FactorEvaluation, DataService# 初始化数据服务
ds = DataService()
df = ds['ETHUSDT_15m_2020_2025']['2021-10-01':]# 读取已有因子数据
factor_path = "/public/data/factor_data/ETHUSDT_15m_2020_2025_factor_data.pkl"
factors = pd.read_pickle(factor_path)# 检查是否有时间索引,如果有则重置为整数索引
if isinstance(factors.index, pd.DatetimeIndex) or factors.index.dtype == 'datetime64[ns]':factors = factors.reset_index(drop=True)# 保存原始列名(旧因子)
original_columns = factors.columns.tolist()
print(f"加载了 {len(original_columns)} 个旧因子")
# 定义所有新因子计算函数
def calculate_filter_001_1(df):'''衡量当前波动率高低的过滤器'''log_ratio = np.log(df['close'] / df['close'].shift(1))hv = log_ratio.rolling(20).std()return hvdef calculate_filter_001_2(df):'''ATR过滤器'''high_low = df['high'] - df['low']high_close = abs(df['high'] - df['close'].shift(1))low_close = abs(df['low'] - df['close'].shift(1))true_range = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)atr = true_range.rolling(14).mean()return atrdef calculate_filter_001_3_keltner_channels(df, ema_period=20, atr_period=10, multiplier=2):'''凯尔特纳通道:基于ATR的波动通道'''ema = df['close'].ewm(span=ema_period, adjust=False).mean()# 计算ATRhigh_low = df['high'] - df['low']high_close = abs(df['high'] - df['close'].shift(1))low_close = abs(df['low'] - df['close'].shift(1))true_range = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)atr = true_range.ewm(span=atr_period, adjust=False).mean()# 计算通道宽度channel_width = multiplier * atrreturn (df['close'] - (ema - channel_width)) / (2 * channel_width)def calculate_filter_002_1(df):'''衡量当前成交量高低的过滤器'''volume_mean = df['volume'].rolling(20).mean()volume_deviation = (df['volume'] - volume_mean) / volume_meanreturn volume_deviationdef calculate_filter_002_2_obv(df):'''能量潮指标:累积成交量平衡'''obv = (np.sign(df['close'].diff()) * df['volume'])obv = obv.cumsum()return obvdef calculate_filter_002_3_vwap(df):'''成交量加权平均价'''typical_price = (df['high'] + df['low'] + df['close']) / 3vwap = (typical_price * df['volume']).cumsum() / df['volume'].cumsum()return vwapdef calculate_filter_003(df):'''衡量当前相对位置高低的过滤器'''up = df['high'].rolling(20).max()down = df['low'].rolling(20).min()price_position = (df['close'] - down) / (up - down)return price_positiondef calculate_filter_004(df):'''衡量短期价格波动快慢的过滤器'''std_5 = df['close'].rolling(5).std()std_30 = df['close'].rolling(30).std()price_fluctuation = std_5 / std_30return price_fluctuationdef calculate_filter_005(df):'''衡量买卖压力的比例的过滤器'''imbalance = 2 * df['taker_buy_volume'] / df['volume'] - 1return imbalancedef calculate_filter_006(df):'''衡量平均交易量的过滤器'''average_trade_size = df['volume'] / df['trade_count']return average_trade_sizedef calculate_filter_007(df):'''衡量 candle body 相对价格范围的大小的过滤器'''body = abs(df['close'] - df['open'])range_ = df['high'] - df['low']body_to_range_ratio = body / range_return body_to_range_ratiodef calculate_filter_008(df):'''衡量上影线相对价格范围的大小的过滤器'''upper_wick = df['high'] - df[['open', 'close']].max(axis=1)range_ = df['high'] - df['low']upper_wick_ratio = upper_wick / range_return upper_wick_ratiodef calculate_filter_009(df):'''衡量下影线相对价格范围的大小的过滤器'''lower_wick = df[['open', 'close']].min(axis=1) - df['low']range_ = df['high'] - df['low']lower_wick_ratio = lower_wick / range_return lower_wick_ratiodef calculate_filter_010_1(df, period=14):'''衡量RSI的过滤器'''delta = df['close'].diff()gain = delta.where(delta > 0, 0)loss = -delta.where(delta < 0, 0)avg_gain = gain.ewm(alpha=1/period, adjust=False).mean()avg_loss = loss.ewm(alpha=1/period, adjust=False).mean()rs = avg_gain / avg_loss.replace([np.inf, -np.inf], np.nan).fillna(0)rsi = 100 - (100 / (1 + rs))return rsidef calculate_filter_010_2_mfi(df, period=14):'''资金流量指数:结合价格和成交量的RSI变体'''typical_price = (df['high'] + df['low'] + df['close']) / 3raw_money_flow = typical_price * df['volume']money_flow_direction = np.where(typical_price > typical_price.shift(1), 1, -1)positive_flow = raw_money_flow.where(money_flow_direction > 0, 0)negative_flow = raw_money_flow.where(money_flow_direction < 0, 0)money_ratio = positive_flow.rolling(period).sum() / negative_flow.rolling(period).sum()money_ratio = money_ratio.replace([np.inf, -np.inf], np.nan).fillna(1)mfi = 100 - (100 / (1 + money_ratio))return mfidef calculate_filter_011(df, short_period=12, long_period=26):'''衡量MACD的过滤器'''short_ema = df['close'].ewm(span=short_period, adjust=False).mean()long_ema = df['close'].ewm(span=long_period, adjust=False).mean()macd = short_ema - long_emareturn macddef calculate_filter_012_aroon_up(df, period=14):'''阿隆上升指标:衡量价格创新高的能力'''high_idx = df['high'].rolling(period).apply(lambda x: x.argmax(), raw=True)aroon_up = 100 * (period - high_idx) / periodreturn aroon_updef calculate_filter_013_aroon_down(df, period=14):'''阿隆下降指标:衡量价格创新低的能力'''low_idx = df['low'].rolling(period).apply(lambda x: x.argmin(), raw=True)aroon_down = 100 * (period - low_idx) / periodreturn aroon_downdef calculate_filter_014_aroon_oscillator(df, period=14):'''阿隆震荡器:衡量趋势强度'''aroon_up = calculate_filter_012_aroon_up(df, period)aroon_down = calculate_filter_013_aroon_down(df, period)return aroon_up - aroon_downdef calculate_filter_015_chaikin_money_flow(df, period=20):'''Chaikin资金流(CMF)'''money_flow_multiplier = ((df['close'] - df['low']) - (df['high'] - df['close'])) / (df['high'] - df['low'])money_flow_multiplier = money_flow_multiplier.replace([np.inf, -np.inf], 0).fillna(0)money_flow_volume = money_flow_multiplier * df['volume']cmf = money_flow_volume.rolling(period).sum() / df['volume'].rolling(period).sum()return cmfdef calculate_filter_020_volume_price_trend(df):'''量价趋势指标:结合价格变动和成交量'''price_change = df['close'].pct_change()vpt = (price_change * df['volume']).cumsum()return vpt
# 所有新因子计算函数的映射
factor_calculators = {'filter_001_1': calculate_filter_001_1,'filter_001_2': calculate_filter_001_2,'filter_001_3': lambda df: calculate_filter_001_3_keltner_channels(df),'filter_002_1': calculate_filter_002_1,'filter_002_2': calculate_filter_002_2_obv,'filter_002_3': calculate_filter_002_3_vwap,'filter_003': calculate_filter_003,'filter_004': calculate_filter_004,'filter_005': calculate_filter_005,'filter_006': calculate_filter_006,'filter_007': calculate_filter_007,'filter_008': calculate_filter_008,'filter_009': calculate_filter_009,'filter_010_1': lambda df: calculate_filter_010_1(df, 14),'filter_010_2': lambda df: calculate_filter_010_2_mfi(df, 14),'filter_011': lambda df: calculate_filter_011(df, 12, 26),'filter_012': lambda df: calculate_filter_012_aroon_up(df, 14),'filter_013': lambda df: calculate_filter_013_aroon_down(df, 14),'filter_014': lambda df: calculate_filter_014_aroon_oscillator(df, 14),'filter_015': lambda df: calculate_filter_015_chaikin_money_flow(df, 20),'filter_020': calculate_filter_020_volume_price_trend
}
# 计算并添加所有新因子
print("\n开始计算新因子...")
for factor_name, calculator in tqdm(factor_calculators.items(), desc="计算因子"):try:# 计算因子值并转换为pandas Seriesfactor_values = calculator(df)if isinstance(factor_values, pd.Series):# 确保长度与factors一致if len(factor_values) != len(factors):# 截断或填充以匹配长度factor_values = factor_values.iloc[:len(factors)].reset_index(drop=True)factors[factor_name] = factor_values.valueselse:# 处理numpy数组if len(factor_values) != len(factors):factor_values = factor_values[:len(factors)]factors[factor_name] = factor_valuesexcept Exception as e:print(f"计算因子 {factor_name} 时出错: {str(e)}")# 添加空列以保持数据结构factors[factor_name] = np.nan# 确保索引对齐
factors = factors.reset_index(drop=True)
# 计算相关系数矩阵
print("\n计算相关系数矩阵...")
corr_matrix = factors.corr()# 提取新因子与旧因子的相关系数
new_factors = list(factor_calculators.keys())
old_factors = original_columns
new_to_old_corr = corr_matrix.loc[new_factors, old_factors]
# 设置相关性阈值
threshold = 0.7
high_corr_records = []  # 用于存储高相关性记录print(f"\n高相关性因子分析 (新因子与旧因子, |corr| > {threshold}):")
for new_factor in new_factors:# 只考虑与旧因子的相关性corr_series = new_to_old_corr.loc[new_factor]# 找出相关性绝对值超过阈值的因子high_corr = corr_series[abs(corr_series) > threshold]if not high_corr.empty:print(f"\n🔍 {new_factor} 与以下旧因子有高相关性:")for factor, corr_value in high_corr.items():# 判断相关性强弱和方向strength = "强" if abs(corr_value) > 0.8 else "中等"direction = "正" if corr_value > 0 else "负"print(f"  - {factor}: {corr_value:.4f} ({strength}{direction}相关)")high_corr_records.append({'新因子': new_factor,'旧因子': factor,'相关系数': corr_value,'相关强度': strength,'相关方向': direction})
# 在Notebook中直接显示高相关性因子表格
if high_corr_records:high_corr_df = pd.DataFrame(high_corr_records)# 美化显示表格print("\n📊 高相关性因子汇总表 (新因子 vs 旧因子):")display(high_corr_df[['新因子', '旧因子', '相关系数', '相关强度', '相关方向']].sort_values(by='相关系数', key=abs, ascending=False).style.background_gradient(cmap='coolwarm', subset=['相关系数']).format({'相关系数': "{:.4f}"}).set_caption(f"高相关性因子汇总 (|corr| > {threshold})"))
else:print(f"\n✅ 未发现高相关性新因子与旧因子 (|corr| > {threshold})")
# 可视化:新因子与旧因子的相关性热力图
plt.figure(figsize=(18, 12))
sns.heatmap(new_to_old_corr,annot=True,fmt=".2f",cmap='coolwarm',center=0,vmin=-1,vmax=1,linewidths=0.5
)
plt.title('新因子与旧因子的相关性热力图', fontsize=16, pad=20)
plt.xlabel('旧因子', fontsize=12)
plt.ylabel('新因子', fontsize=12)
plt.xticks(rotation=90, fontsize=8)
plt.yticks(rotation=0, fontsize=8)# 添加颜色条说明
cbar = plt.gcf().axes[-1]
cbar.set_ylabel('相关系数', rotation=270, labelpad=20)# 直接在Notebook中显示图表
plt.tight_layout()
plt.show()
# 加载同质异质分离数据(如果存在)
homo_hetero_path = "/public/data/factor_data/ETHUSDT_15m_2020_2025_homo_heter_split.joblib"
if os.path.exists(homo_hetero_path):try:homo_hetero_data = joblib.load(homo_hetero_path)print("\n加载同质异质分离数据成功!")# 这里可以添加对同质异质数据的分析代码except Exception as e:print(f"\n加载同质异质分离数据时出错: {str(e)}")
else:print("\n未找到同质异质分离数据文件")print("\n🎉 因子相关性分析完成!")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914166.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity Demo——3D平台跳跃游戏笔记

今天是一个3D平台跳跃游戏的笔记。我们按照以下分类来对这个项目的代码进行学习&#xff1a;核心游戏系统 (Core Game Systems)核心游戏系统是IkunOdyssey项目的基础&#xff0c;负责所有游戏对象&#xff08;如玩家、敌人、道具等&#xff09;的通用行为和物理交互。它通过实体…

【C语言】回调函数、转移表、qsort 使用与基于qsort改造冒泡排序

文章目录数组指针/指针数组函数指针函数指针数组函数指针数组用途(转移表)回调函数qsort函数基于qsort改造冒泡排序源码数组指针/指针数组 int arr1[5] { 1,2,3,4,5 };int (*p1)[5] &arr1; //p1是数组指针变量int* arr2[5] { 0 }; //arr2是指针数组指针数组是存放指…

vue3 uniapp 使用ref更新值后子组件没有更新 ref reactive的区别?使用from from -item执行表单验证一直提示没有值

遇到这样一个问题&#xff0c;我有个1个页面A&#xff0c;一个from表单组件&#xff0c;一个form-item组件&#xff0c; 使用是这样的&#xff0c;我在父组件A中使用 &#xff0c;执行表单验证一直提示没有值咱们先来讲一讲ref 和reactive的区别 ref 用来创建一个基本类型或单…

PyQt5布局管理(QBoxLayout(框布局))

QBoxLayout&#xff08;框布局&#xff09; 采用QBoxLayout类可以在水平和垂直方向上排列控件&#xff0c;QHBoxLayout和 QVBoxLayout类继承自QBoxLayout类。 QHBoxLayout&#xff08;水平布局&#xff09; 采用QHBoxLayout类&#xff0c;按照从左到右的顺序来添加控件。QHBoxL…

Grok 4作战图刷爆全网,80%华人横扫硅谷!清华上交校友领衔,95后站C位

来源 | 新智元短短两年&#xff0c;马斯克Grok 4的横空出世&#xff0c;让xAI团队一举站上AI之巅。昨日一小时发布会&#xff0c;Grok 4让所有人大开眼界&#xff0c;直接刷爆了AIME 2025、人类最后的考试&#xff08;HLE&#xff09;两大基准。这是狂堆20万GPU才换来的惊人成果…

AI大模型(七)Langchain核心模块与实战(二)

Langchain核心模块与实战&#xff08;二&#xff09;Langchian向量数据库检索Langchian构建向量数据库和检索器批量搜索返回与之相似度最高的第一个检索器和模型结合得到非笼统的答案LangChain构建代理通过代理去调用Langchain构建RAG的对话应用包含历史记录的对话生成Langchia…

Flutter基础(前端教程①-容器和控件位置)

一个红色背景的 Container垂直排列的 Column 布局中央的 ElevatedButton按钮下方的白色文本import package:flutter/material.dart;void main() {runApp(const MyApp()); }class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);overrideWidget bu…

CSS flex

目录 flex-box和flex-item 主轴和副轴 ​编辑 flex-box的属性 flex-direction flex-wrap flex-flow justify-content ​编辑​align-items align-content flex-item的属性 flex-basis flex-grow flex-shrink flex flex-box和flex-item 当把一个块级元素的displ…

【JMeter】执行系统命令

步骤如下&#xff1a; 添加JSP233 Sampler&#xff1a;右击线程组>添加>取样器>JSR223 Sampler2.填写脚本&#xff0c;执行后查看日志。res "ipconfig".execute().text log.info(res)res "python -c \"print(11)\"".execute().text l…

AI Agent开发学习系列 - langchain之memory(1):内存中的短时记忆

内存中的短时记忆&#xff0c;在 LangChain 中通常指 ConversationBufferMemory 这类“对话缓冲记忆”工具。它的作用是&#xff1a;在内存中保存最近的对话历史&#xff0c;让大模型能理解上下文&#xff0c;实现连续对话。 对话缓冲记忆”工具 主要特点 只保留最近的对话内容…

uniapp实现微信小程序端图片保存到相册

效果图展示 安装插件海报画板导入到项目里面&#xff0c;在页面直接使用 <template><view><button click"saveToAlbum" class"save-button">保存到相册</button><image :src"path" mode"widthFix" v-if&qu…

Java生产带文字、带边框的二维码

Java 生成带文字、带边框的二维码1、Java 生成带文字的二维码1.1、导入jar包1.2、普通单一的二维码1.2.1、代码示例1.2.2、效果1.3、带文字的二维码1.&#xff13;.&#xff11;、代码示例1.3.2、效果2、带边框的二维码2.1、代码示例2.2、带边框的二维码效果 1、Java 生成带文字…

ARM单片机启动流程(三)(栈空间综合理解及相关实际应用)

文章目录1、引出栈空间问题2、解决问题2.1、RAM空间2.2、RAM空间具体分布2.3、关于栈空间的使用2.4、栈溢出2.5、变量的消亡2.6、回到关键字static2.7、合法性的判断1、引出栈空间问题 从static关键字引出该部分内容。 为什么能从static引出来&#xff1f; 在使用该关键字的…

【RK3568+PG2L50H开发板实验例程】FPGA部分 | 键控LED实验

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 1.实验简介 实验目的&#xff1a; 从创建工程到编写代码&#xff0c;完成引脚约束&#xff0c;最后生成 bit 流下载到…

【Python练习】039. 编写一个函数,反转一个单链表

039. 编写一个函数,反转一个单链表 039. 编写一个函数,反转一个单链表方法 1:迭代实现运行结果代码解释方法 2:递归实现运行结果代码解释选择方法迭代法与递归法的区别039. 编写一个函数,反转一个单链表 在 Python 中,可以通过迭代或递归的方式反转一个单链表。 方法 1…

BERT代码简单笔记

参考视频&#xff1a;BERT代码(源码)从零解读【Pytorch-手把手教你从零实现一个BERT源码模型】_哔哩哔哩_bilibili 一、BertTokenizer BertTokenizer 是基于 WordPiece 算法的 BERT 分词器&#xff0c;继承自 PreTrainedTokenizer。 继承的PretrainedTokenizer&#xff0c;具…

PID控制算法理论学习基础——单级PID控制

这是一篇我在学习PID控制算法的过程中的学习记录。在一开始学习PID的时候&#xff0c;我也看了市面上许多的资料&#xff0c;好的资料固然有&#xff0c;但是更多的是不知所云。&#xff08;有的是写的太过深奥&#xff0c;有的则是照搬挪用&#xff0c;对原理则一问三不知&…

【Elasticsearch】function_score与rescore

它们俩都是用来“**干涉评分**”的&#xff0c;但**工作阶段不同、性能开销不同、能做的事也不同**。一句话总结&#xff1a;> **function_score** 在 **第一次算分** 时就动手脚&#xff1b; > **rescore** 在 **拿到 Top-N 结果后** 再“重新打分”。下面把“能干嘛”…

无广告纯净体验 WPS2016 精简版:移除联网模块 + 非核心组件,古董电脑也能跑

各位办公小能手们&#xff01;今天给你们介绍一款超神的办公软件——WPS2016精简版&#xff01;它有多小呢&#xff1f;才33MB&#xff0c;简直就是软件界的小不点儿&#xff01;别看它个头小&#xff0c;功能可一点儿都不含糊&#xff0c;文字、表格、演示这三大功能它全都有。…

《PyWin32:Python与Windows的桥梁,解锁系统自动化新姿势》

什么是 PyWin32在 Windows 平台的 Python 开发领域中&#xff0c;PyWin32 是一个举足轻重的库&#xff0c;它为 Python 开发者打开了一扇直接通往 Windows 操作系统底层功能的大门。简单来说&#xff0c;PyWin32 是用于 Python 访问 Windows API&#xff08;Application Progra…