{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# LightGBM 回归训练示例 - 使用因子字符串表达式\n", "\n", "使用字符串表达式定义因子,训练 LightGBM 回归模型预测未来5日收益率。\n", "\n", "**Label**: return_5 = (ts_delay(close, -5) / close) - 1 # 未来5日收益率" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. 导入依赖" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:27:36.008131Z", "start_time": "2026-03-07T16:27:36.005668Z" } }, "source": [ "import os\n", "from datetime import datetime\n", "from typing import List\n", "\n", "import polars as pl\n", "\n", "from src.factors import FactorEngine\n", "from src.training import (\n", " DateSplitter,\n", " LightGBMModel,\n", " STFilter,\n", " StandardScaler,\n", " StockFilterConfig,\n", " StockPoolManager,\n", " Trainer,\n", " Winsorizer,\n", " NullFiller,\n", ")\n", "from src.training.config import TrainingConfig" ], "outputs": [], "execution_count": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. 定义辅助函数" ] }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:27:36.020762Z", "start_time": "2026-03-07T16:27:36.011650Z" } }, "cell_type": "code", "source": [ "def create_factors_with_strings(engine: FactorEngine, factor_definitions: dict, label_factor: dict) -> List[str]:\n", " print(\"=\" * 80)\n", " print(\"使用字符串表达式定义因子\")\n", " print(\"=\" * 80)\n", "\n", " # 注册所有特征因子\n", " print(\"\\n注册特征因子:\")\n", " for name, expr in factor_definitions.items():\n", " engine.add_factor(name, expr)\n", " print(f\" - {name}: {expr}\")\n", "\n", " # 注册 label 因子\n", " print(\"\\n注册 Label 因子:\")\n", " for name, expr in label_factor.items():\n", " engine.add_factor(name, expr)\n", " print(f\" - {name}: {expr}\")\n", "\n", " # 从字典自动获取特征列\n", " feature_cols = list(factor_definitions.keys())\n", "\n", " print(f\"\\n特征因子数: {len(feature_cols)}\")\n", " print(f\"Label: {list(label_factor.keys())[0]}\")\n", " print(f\"已注册因子总数: {len(engine.list_registered())}\")\n", "\n", " return feature_cols\n", "\n", "\n", "def prepare_data(\n", " engine: FactorEngine,\n", " feature_cols: List[str],\n", " start_date: str,\n", " end_date: str,\n", ") -> pl.DataFrame:\n", " print(\"\\n\" + \"=\" * 80)\n", " print(\"准备数据\")\n", " print(\"=\" * 80)\n", "\n", " # 计算因子(全市场数据)\n", " print(f\"\\n计算因子: {start_date} - {end_date}\")\n", " factor_names = feature_cols + [\"return_5\"] # 包含 label\n", "\n", " data = engine.compute(\n", " factor_names=factor_names,\n", " start_date=start_date,\n", " end_date=end_date,\n", " )\n", "\n", " print(f\"数据形状: {data.shape}\")\n", " print(f\"数据列: {data.columns}\")\n", " print(f\"\\n前5行预览:\")\n", " print(data.head())\n", "\n", " return data" ], "outputs": [], "execution_count": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. 配置参数\n", "\n", "### 3.1 因子定义" ] }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:27:36.027366Z", "start_time": "2026-03-07T16:27:36.024465Z" } }, "cell_type": "code", "source": [ "# 特征因子定义字典:新增因子只需在此处添加一行\n", "FACTOR_DEFINITIONS = {\n", " # 1. 价格动量因子\n", " \"ma5\": \"ts_mean(close, 5)\",\n", " \"ma10\": \"ts_mean(close, 10)\",\n", " \"ma20\": \"ts_mean(close, 20)\",\n", " \"ma_ratio\": \"ts_mean(close, 5) / ts_mean(close, 20) - 1\",\n", " # 2. 波动率因子\n", " \"volatility_5\": \"ts_std(close, 5)\",\n", " \"volatility_20\": \"ts_std(close, 20)\",\n", " \"vol_ratio\": \"ts_std(close, 5) / (ts_std(close, 20) + 1e-8)\",\n", " # 3. 收益率动量因子\n", " \"return_10\": \"(close / ts_delay(close, 10)) - 1\",\n", " \"return_20\": \"(close / ts_delay(close, 20)) - 1\",\n", " # 4. 收益率变化因子\n", " \"return_diff\": \"(close / ts_delay(close, 5)) - 1 - ((close / ts_delay(close, 10)) - 1)\",\n", " # 5. 成交量因子\n", " \"vol_ma5\": \"ts_mean(vol, 5)\",\n", " \"vol_ma20\": \"ts_mean(vol, 20)\",\n", " \"vol_ratio\": \"ts_mean(vol, 5) / (ts_mean(vol, 20) + 1e-8)\",\n", " # 6. 市值因子(截面排名)\n", " \"market_cap_rank\": \"cs_rank(total_mv)\",\n", " # 7. 价格位置因子\n", " \"high_low_ratio\": \"(close - ts_min(low, 20)) / (ts_max(high, 20) - ts_min(low, 20) + 1e-8)\",\n", " \"n_income\": \"cs_rank(n_income)\",\n", "}\n", "\n", "# Label 因子定义(不参与训练,用于计算目标)\n", "LABEL_FACTOR = {\n", " \"return_5\": \"(ts_delay(close, -5) / close) - 1\", # 未来5日收益率\n", "}" ], "outputs": [], "execution_count": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.2 训练参数配置" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:27:36.035196Z", "start_time": "2026-03-07T16:27:36.031430Z" } }, "source": [ "# 日期范围配置\n", "TRAIN_START = \"20200101\"\n", "TRAIN_END = \"20241231\"\n", "TEST_START = \"20250101\"\n", "TEST_END = \"20251231\"\n", "\n", "# 模型参数配置\n", "MODEL_PARAMS = {\n", " \"objective\": \"regression\",\n", " \"metric\": \"mae\", # 改为 MAE,对异常值更稳健\n", " # 树结构控制(防过拟合核心)\n", " \"num_leaves\": 20, # 从31降为20,降低模型复杂度\n", " \"max_depth\": 4, # 显式限制深度,防止过度拟合噪声\n", " \"min_child_samples\": 50, # 叶子最小样本数,防止学习极端样本\n", " \"min_child_weight\": 0.001,\n", " # 学习参数\n", " \"learning_rate\": 0.01, # 降低学习率,配合更多树\n", " \"n_estimators\": 1000, # 增加树数量,配合早停\n", " # 采样策略(关键防过拟合)\n", " \"subsample\": 0.8, # 每棵树随机采样80%数据(行采样)\n", " \"subsample_freq\": 5, # 每5轮迭代进行一次 subsample\n", " \"colsample_bytree\": 0.8, # 每棵树随机选择80%特征(列采样)\n", " # 正则化\n", " \"reg_alpha\": 0.1, # L1正则,增加稀疏性\n", " \"reg_lambda\": 1.0, # L2正则,平滑权重\n", " # 数值稳定性\n", " \"verbose\": -1,\n", " \"random_state\": 42,\n", "}\n", "\n", "# 数据处理器配置\n", "PROCESSOR_CONFIGS = [\n", " {\"name\": \"winsorizer\", \"params\": {\"lower\": 0.01, \"upper\": 0.99}},\n", " {\"name\": \"cs_standard_scaler\", \"params\": {}},\n", "]\n", "\n", "# 股票池筛选配置\n", "STOCK_FILTER_CONFIG = {\n", " \"exclude_cyb\": True, # 排除创业板\n", " \"exclude_kcb\": True, # 排除科创板\n", " \"exclude_bj\": True, # 排除北交所\n", " \"exclude_st\": True, # 排除ST股票\n", "}\n", "\n", "# 输出配置(相对于本文件所在目录)\n", "OUTPUT_DIR = \"output\"\n", "SAVE_PREDICTIONS = True\n", "PERSIST_MODEL = False" ], "outputs": [], "execution_count": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. 训练流程\n", "\n", "### 4.1 初始化组件" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:27:41.855565Z", "start_time": "2026-03-07T16:27:36.040416Z" } }, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"LightGBM 回归模型训练\")\n", "print(\"=\" * 80)\n", "\n", "# 1. 创建 FactorEngine\n", "print(\"\\n[1] 创建 FactorEngine\")\n", "engine = FactorEngine()\n", "\n", "# 2. 使用字符串表达式定义因子\n", "print(\"\\n[2] 定义因子(字符串表达式)\")\n", "feature_cols = create_factors_with_strings(engine, FACTOR_DEFINITIONS, LABEL_FACTOR)\n", "target_col = \"return_5\"\n", "\n", "# 3. 准备数据(使用模块级别的日期配置)\n", "print(\"\\n[3] 准备数据\")\n", "\n", "data = prepare_data(\n", " engine=engine,\n", " feature_cols=feature_cols,\n", " start_date=TRAIN_START,\n", " end_date=TEST_END,\n", ")\n", "\n", "# 4. 打印配置信息\n", "print(f\"\\n[配置] 训练期: {TRAIN_START} - {TRAIN_END}\")\n", "print(f\"[配置] 测试期: {TEST_START} - {TEST_END}\")\n", "print(f\"[配置] 特征数: {len(feature_cols)}\")\n", "print(f\"[配置] 目标变量: {target_col}\")\n", "\n", "# 5. 创建模型\n", "model = LightGBMModel(params=MODEL_PARAMS)\n", "\n", "# 6. 创建数据处理器\n", "processors = [\n", " NullFiller(strategy=\"mean\"),\n", " Winsorizer(**PROCESSOR_CONFIGS[0][\"params\"]),\n", " StandardScaler(exclude_cols=[\"ts_code\", \"trade_date\", target_col]),\n", "]\n", "\n", "# 7. 创建数据划分器\n", "splitter = DateSplitter(\n", " train_start=TRAIN_START,\n", " train_end=TRAIN_END,\n", " test_start=TEST_START,\n", " test_end=TEST_END,\n", ")\n", "\n", "# 8. 创建股票池管理器\n", "pool_manager = StockPoolManager(\n", " filter_config=StockFilterConfig(**STOCK_FILTER_CONFIG),\n", " selector_config=None, # 暂时不启用市值选择\n", " data_router=engine.router,\n", ")\n", "\n", "# 9. 创建 ST 股票过滤器\n", "st_filter = STFilter(\n", " data_router=engine.router,\n", ")\n", "\n", "# 10. 创建训练器\n", "trainer = Trainer(\n", " model=model,\n", " pool_manager=pool_manager,\n", " processors=processors,\n", " filters=[st_filter],\n", " splitter=splitter,\n", " target_col=target_col,\n", " feature_cols=feature_cols,\n", " persist_model=PERSIST_MODEL,\n", ")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "================================================================================\n", "LightGBM 回归模型训练\n", "================================================================================\n", "\n", "[1] 创建 FactorEngine\n", "\n", "[2] 定义因子(字符串表达式)\n", "================================================================================\n", "使用字符串表达式定义因子\n", "================================================================================\n", "\n", "注册特征因子:\n", " - ma5: ts_mean(close, 5)\n", " - ma10: ts_mean(close, 10)\n", " - ma20: ts_mean(close, 20)\n", " - ma_ratio: ts_mean(close, 5) / ts_mean(close, 20) - 1\n", " - volatility_5: ts_std(close, 5)\n", " - volatility_20: ts_std(close, 20)\n", " - vol_ratio: ts_mean(vol, 5) / (ts_mean(vol, 20) + 1e-8)\n", " - return_10: (close / ts_delay(close, 10)) - 1\n", " - return_20: (close / ts_delay(close, 20)) - 1\n", " - return_diff: (close / ts_delay(close, 5)) - 1 - ((close / ts_delay(close, 10)) - 1)\n", " - vol_ma5: ts_mean(vol, 5)\n", " - vol_ma20: ts_mean(vol, 20)\n", " - market_cap_rank: cs_rank(total_mv)\n", " - high_low_ratio: (close - ts_min(low, 20)) / (ts_max(high, 20) - ts_min(low, 20) + 1e-8)\n", " - n_income: cs_rank(n_income)\n", "\n", "注册 Label 因子:\n", " - return_5: (ts_delay(close, -5) / close) - 1\n", "\n", "特征因子数: 15\n", "Label: return_5\n", "已注册因子总数: 16\n", "\n", "[3] 准备数据\n", "\n", "================================================================================\n", "准备数据\n", "================================================================================\n", "\n", "计算因子: 20200101 - 20251231\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "D:\\PyProject\\ProStock\\src\\data\\financial_loader.py:123: UserWarning: Sortedness of columns cannot be checked when 'by' groups provided\n", " merged = df_price.join_asof(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "数据形状: (7044952, 24)\n", "数据列: ['ts_code', 'trade_date', 'low', 'close', 'vol', 'high', 'total_mv', 'f_ann_date', 'n_income', 'ma5', 'ma10', 'ma20', 'ma_ratio', 'volatility_5', 'volatility_20', 'vol_ratio', 'return_10', 'return_20', 'return_diff', 'vol_ma5', 'vol_ma20', 'market_cap_rank', 'high_low_ratio', 'return_5']\n", "\n", "前5行预览:\n", "shape: (5, 24)\n", "┌───────────┬────────────┬─────────┬─────────┬───┬──────────┬─────────────┬────────────┬───────────┐\n", "│ ts_code ┆ trade_date ┆ low ┆ close ┆ … ┆ vol_ma20 ┆ market_cap_ ┆ high_low_r ┆ return_5 │\n", "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ rank ┆ atio ┆ --- │\n", "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ f64 ┆ --- ┆ --- ┆ f64 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ │\n", "╞═══════════╪════════════╪═════════╪═════════╪═══╪══════════╪═════════════╪════════════╪═══════════╡\n", "│ 000001.SZ ┆ 20200102 ┆ 1806.75 ┆ 1841.69 ┆ … ┆ null ┆ 0.993583 ┆ null ┆ -0.004746 │\n", "│ 000001.SZ ┆ 20200103 ┆ 1847.15 ┆ 1875.53 ┆ … ┆ null ┆ 0.993585 ┆ null ┆ -0.02852 │\n", "│ 000001.SZ ┆ 20200106 ┆ 1846.05 ┆ 1863.52 ┆ … ┆ null ┆ 0.993588 ┆ null ┆ -0.004685 │\n", "│ 000001.SZ ┆ 20200107 ┆ 1850.42 ┆ 1872.26 ┆ … ┆ null ┆ 0.993588 ┆ null ┆ -0.022743 │\n", "│ 000001.SZ ┆ 20200108 ┆ 1815.49 ┆ 1818.76 ┆ … ┆ null ┆ 0.993586 ┆ null ┆ -0.008401 │\n", "└───────────┴────────────┴─────────┴─────────┴───┴──────────┴─────────────┴────────────┴───────────┘\n", "\n", "[配置] 训练期: 20200101 - 20241231\n", "[配置] 测试期: 20250101 - 20251231\n", "[配置] 特征数: 15\n", "[配置] 目标变量: return_5\n" ] } ], "execution_count": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2 执行训练" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:27:48.155192Z", "start_time": "2026-03-07T16:27:41.865012Z" } }, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"开始训练\")\n", "print(\"=\" * 80)\n", "\n", "# 步骤 1: 股票池筛选\n", "print(\"\\n[步骤 1/6] 股票池筛选\")\n", "print(\"-\" * 60)\n", "if pool_manager:\n", " print(\" 执行每日独立筛选股票池...\")\n", " filtered_data = pool_manager.filter_and_select_daily(data)\n", " print(f\" 筛选前数据规模: {data.shape}\")\n", " print(f\" 筛选后数据规模: {filtered_data.shape}\")\n", " print(f\" 筛选前股票数: {data['ts_code'].n_unique()}\")\n", " print(f\" 筛选后股票数: {filtered_data['ts_code'].n_unique()}\")\n", " print(f\" 删除记录数: {len(data) - len(filtered_data)}\")\n", "else:\n", " filtered_data = data\n", " print(\" 未配置股票池管理器,跳过筛选\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "================================================================================\n", "开始训练\n", "================================================================================\n", "\n", "[步骤 1/6] 股票池筛选\n", "------------------------------------------------------------\n", " 执行每日独立筛选股票池...\n", " 筛选前数据规模: (7044952, 24)\n", " 筛选后数据规模: (4532198, 24)\n", " 筛选前股票数: 5678\n", " 筛选后股票数: 3359\n", " 删除记录数: 2512754\n" ] } ], "execution_count": 11 }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:27:48.744530Z", "start_time": "2026-03-07T16:27:48.163043Z" } }, "source": [ "# 步骤 2: 划分训练/测试集\n", "print(\"\\n[步骤 2/6] 划分训练集和测试集\")\n", "print(\"-\" * 60)\n", "if splitter:\n", " train_data, test_data = splitter.split(filtered_data)\n", " print(f\" 训练集数据规模: {train_data.shape}\")\n", " print(f\" 测试集数据规模: {test_data.shape}\")\n", " print(f\" 训练集股票数: {train_data['ts_code'].n_unique()}\")\n", " print(f\" 测试集股票数: {test_data['ts_code'].n_unique()}\")\n", " print(\n", " f\" 训练集日期范围: {train_data['trade_date'].min()} - {train_data['trade_date'].max()}\"\n", " )\n", " print(\n", " f\" 测试集日期范围: {test_data['trade_date'].min()} - {test_data['trade_date'].max()}\"\n", " )\n", "\n", " print(\"\\n 训练集前5行预览:\")\n", " print(train_data.head())\n", " print(\"\\n 测试集前5行预览:\")\n", " print(test_data.head())\n", "else:\n", " train_data = filtered_data\n", " test_data = filtered_data\n", " print(\" 未配置划分器,全部作为训练集\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "[步骤 2/6] 划分训练集和测试集\n", "------------------------------------------------------------\n", " 训练集数据规模: (3760991, 24)\n", " 测试集数据规模: (771207, 24)\n", " 训练集股票数: 3321\n", " 测试集股票数: 3215\n", " 训练集日期范围: 20200102 - 20241231\n", " 测试集日期范围: 20250102 - 20251231\n", "\n", " 训练集前5行预览:\n", "shape: (5, 24)\n", "┌───────────┬────────────┬─────────┬─────────┬───┬──────────┬─────────────┬────────────┬───────────┐\n", "│ ts_code ┆ trade_date ┆ low ┆ close ┆ … ┆ vol_ma20 ┆ market_cap_ ┆ high_low_r ┆ return_5 │\n", "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ rank ┆ atio ┆ --- │\n", "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ f64 ┆ --- ┆ --- ┆ f64 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ │\n", "╞═══════════╪════════════╪═════════╪═════════╪═══╪══════════╪═════════════╪════════════╪═══════════╡\n", "│ 000001.SZ ┆ 20200102 ┆ 1806.75 ┆ 1841.69 ┆ … ┆ null ┆ 0.993583 ┆ null ┆ -0.004746 │\n", "│ 000002.SZ ┆ 20200102 ┆ 4824.87 ┆ 4832.29 ┆ … ┆ null ┆ 0.99492 ┆ null ┆ -0.011057 │\n", "│ 000004.SZ ┆ 20200102 ┆ 90.1 ┆ 90.75 ┆ … ┆ null ┆ 0.057219 ┆ null ┆ -0.000441 │\n", "│ 000005.SZ ┆ 20200102 ┆ 28.82 ┆ 29.1 ┆ … ┆ null ┆ 0.28984 ┆ null ┆ 0.022337 │\n", "│ 000006.SZ ┆ 20200102 ┆ 190.24 ┆ 191.3 ┆ … ┆ null ┆ 0.631551 ┆ null ┆ 0.012964 │\n", "└───────────┴────────────┴─────────┴─────────┴───┴──────────┴─────────────┴────────────┴───────────┘\n", "\n", " 测试集前5行预览:\n", "shape: (5, 24)\n", "┌───────────┬────────────┬─────────┬─────────┬───┬────────────┬────────────┬───────────┬───────────┐\n", "│ ts_code ┆ trade_date ┆ low ┆ close ┆ … ┆ vol_ma20 ┆ market_cap ┆ high_low_ ┆ return_5 │\n", "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ _rank ┆ ratio ┆ --- │\n", "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ f64 ┆ --- ┆ --- ┆ f64 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ │\n", "╞═══════════╪════════════╪═════════╪═════════╪═══╪════════════╪════════════╪═══════════╪═══════════╡\n", "│ 000001.SZ ┆ 20250102 ┆ 1455.46 ┆ 1460.57 ┆ … ┆ 1.2151e6 ┆ 0.991617 ┆ 0.063478 ┆ -0.002622 │\n", "│ 000002.SZ ┆ 20250102 ┆ 1284.65 ┆ 1291.92 ┆ … ┆ 1.2839e6 ┆ 0.970007 ┆ 0.020839 ┆ -0.022509 │\n", "│ 000004.SZ ┆ 20250102 ┆ 54.17 ┆ 57.63 ┆ … ┆ 159807.918 ┆ 0.099106 ┆ 0.131858 ┆ -0.064897 │\n", "│ 000006.SZ ┆ 20250102 ┆ 285.33 ┆ 288.12 ┆ … ┆ 404264.211 ┆ 0.72392 ┆ 0.028423 ┆ -0.048278 │\n", "│ 000007.SZ ┆ 20250102 ┆ 57.49 ┆ 58.15 ┆ … ┆ 88380.2845 ┆ 0.183495 ┆ 0.391829 ┆ 0.015649 │\n", "└───────────┴────────────┴─────────┴─────────┴───┴────────────┴────────────┴───────────┴───────────┘\n" ] } ], "execution_count": 12 }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:27:49.562499Z", "start_time": "2026-03-07T16:27:48.753734Z" } }, "source": [ "# 步骤 3: 训练集数据处理\n", "print(\"\\n[步骤 3/6] 训练集数据处理\")\n", "print(\"-\" * 60)\n", "fitted_processors = []\n", "if processors:\n", " for i, processor in enumerate(processors, 1):\n", " print(\n", " f\" [{i}/{len(processors)}] 应用处理器: {processor.__class__.__name__}\"\n", " )\n", " train_data_before = len(train_data)\n", " train_data = processor.fit_transform(train_data)\n", " train_data_after = len(train_data)\n", " fitted_processors.append(processor)\n", " print(f\" 处理前记录数: {train_data_before}\")\n", " print(f\" 处理后记录数: {train_data_after}\")\n", " if train_data_before != train_data_after:\n", " print(f\" 删除记录数: {train_data_before - train_data_after}\")\n", "\n", "print(\"\\n 训练集处理后前5行预览:\")\n", "print(train_data.head())\n", "print(f\"\\n 训练集特征统计:\")\n", "print(f\" 特征数: {len(feature_cols)}\")\n", "print(f\" 样本数: {len(train_data)}\")\n", "print(f\" 缺失值统计:\")\n", "for col in feature_cols[:5]: # 只显示前5个特征的缺失值\n", " null_count = train_data[col].null_count()\n", " if null_count > 0:\n", " print(\n", " f\" {col}: {null_count} ({null_count / len(train_data) * 100:.2f}%)\"\n", " )" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "[步骤 3/6] 训练集数据处理\n", "------------------------------------------------------------\n", " [1/3] 应用处理器: NullFiller\n", " 处理前记录数: 3760991\n", " 处理后记录数: 3760991\n", " [2/3] 应用处理器: Winsorizer\n", " 处理前记录数: 3760991\n", " 处理后记录数: 3760991\n", " [3/3] 应用处理器: StandardScaler\n", " 处理前记录数: 3760991\n", " 处理后记录数: 3760991\n", "\n", " 训练集处理后前5行预览:\n", "shape: (5, 24)\n", "┌───────────┬────────────┬───────────┬──────────┬───┬──────────┬───────────┬───────────┬───────────┐\n", "│ ts_code ┆ trade_date ┆ low ┆ close ┆ … ┆ vol_ma20 ┆ market_ca ┆ high_low_ ┆ return_5 │\n", "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ p_rank ┆ ratio ┆ --- │\n", "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ f64 ┆ --- ┆ --- ┆ f64 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ │\n", "╞═══════════╪════════════╪═══════════╪══════════╪═══╪══════════╪═══════════╪═══════════╪═══════════╡\n", "│ 000001.SZ ┆ 20200102 ┆ 7.215424 ┆ 7.219817 ┆ … ┆ null ┆ 1.579213 ┆ null ┆ -0.004746 │\n", "│ 000002.SZ ┆ 20200102 ┆ 7.215424 ┆ 7.219817 ┆ … ┆ null ┆ 1.579213 ┆ null ┆ -0.011057 │\n", "│ 000004.SZ ┆ 20200102 ┆ 0.118662 ┆ 0.111432 ┆ … ┆ null ┆ -1.671014 ┆ null ┆ -0.000441 │\n", "│ 000005.SZ ┆ 20200102 ┆ -0.292838 ┆ -0.29447 ┆ … ┆ null ┆ -0.862878 ┆ null ┆ 0.022337 │\n", "│ 000006.SZ ┆ 20200102 ┆ 0.791109 ┆ 0.77345 ┆ … ┆ null ┆ 0.324248 ┆ null ┆ 0.012964 │\n", "└───────────┴────────────┴───────────┴──────────┴───┴──────────┴───────────┴───────────┴───────────┘\n", "\n", " 训练集特征统计:\n", " 特征数: 15\n", " 样本数: 3760991\n", " 缺失值统计:\n", " ma5: 11541 (0.31%)\n", " ma10: 25950 (0.69%)\n", " ma20: 54850 (1.46%)\n", " ma_ratio: 54850 (1.46%)\n", " volatility_5: 11541 (0.31%)\n" ] } ], "execution_count": 13 }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:28:09.621524Z", "start_time": "2026-03-07T16:27:49.566330Z" } }, "source": [ "# 步骤 4: 训练模型\n", "print(\"\\n[步骤 4/6] 训练模型\")\n", "print(\"-\" * 60)\n", "print(f\" 模型类型: LightGBM\")\n", "print(f\" 训练样本数: {len(train_data)}\")\n", "print(f\" 特征数: {len(feature_cols)}\")\n", "print(f\" 目标变量: {target_col}\")\n", "\n", "X_train = train_data.select(feature_cols)\n", "y_train = train_data.select(target_col).to_series()\n", "\n", "print(f\"\\n 目标变量统计:\")\n", "print(f\" 均值: {y_train.mean():.6f}\")\n", "print(f\" 标准差: {y_train.std():.6f}\")\n", "print(f\" 最小值: {y_train.min():.6f}\")\n", "print(f\" 最大值: {y_train.max():.6f}\")\n", "print(f\" 缺失值: {y_train.null_count()}\")\n", "\n", "print(\"\\n 开始训练...\")\n", "model.fit(X_train, y_train)\n", "print(\" 训练完成!\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "[步骤 4/6] 训练模型\n", "------------------------------------------------------------\n", " 模型类型: LightGBM\n", " 训练样本数: 3760991\n", " 特征数: 15\n", " 目标变量: return_5\n", "\n", " 目标变量统计:\n", " 均值: 0.001511\n", " 标准差: 0.062515\n", " 最小值: -0.165141\n", " 最大值: 0.225065\n", " 缺失值: 0\n", "\n", " 开始训练...\n", " 训练完成!\n" ] } ], "execution_count": 14 }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:28:09.687281Z", "start_time": "2026-03-07T16:28:09.625395Z" } }, "source": [ "# 步骤 5: 测试集数据处理\n", "print(\"\\n[步骤 5/6] 测试集数据处理\")\n", "print(\"-\" * 60)\n", "if processors and test_data is not train_data:\n", " for i, processor in enumerate(fitted_processors, 1):\n", " print(\n", " f\" [{i}/{len(fitted_processors)}] 应用处理器: {processor.__class__.__name__}\"\n", " )\n", " test_data_before = len(test_data)\n", " test_data = processor.transform(test_data)\n", " test_data_after = len(test_data)\n", " print(f\" 处理前记录数: {test_data_before}\")\n", " print(f\" 处理后记录数: {test_data_after}\")\n", "else:\n", " print(\" 跳过测试集处理\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "[步骤 5/6] 测试集数据处理\n", "------------------------------------------------------------\n", " [1/3] 应用处理器: NullFiller\n", " 处理前记录数: 771207\n", " 处理后记录数: 771207\n", " [2/3] 应用处理器: Winsorizer\n", " 处理前记录数: 771207\n", " 处理后记录数: 771207\n", " [3/3] 应用处理器: StandardScaler\n", " 处理前记录数: 771207\n", " 处理后记录数: 771207\n" ] } ], "execution_count": 15 }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:28:10.718020Z", "start_time": "2026-03-07T16:28:09.691077Z" } }, "source": [ "# 步骤 6: 生成预测\n", "print(\"\\n[步骤 6/6] 生成预测\")\n", "print(\"-\" * 60)\n", "X_test = test_data.select(feature_cols)\n", "print(f\" 测试样本数: {len(X_test)}\")\n", "print(\" 预测中...\")\n", "predictions = model.predict(X_test)\n", "print(f\" 预测完成!\")\n", "\n", "print(f\"\\n 预测结果统计:\")\n", "print(f\" 均值: {predictions.mean():.6f}\")\n", "print(f\" 标准差: {predictions.std():.6f}\")\n", "print(f\" 最小值: {predictions.min():.6f}\")\n", "print(f\" 最大值: {predictions.max():.6f}\")\n", "\n", "# 保存结果到 trainer\n", "trainer.results = test_data.with_columns([pl.Series(\"prediction\", predictions)])" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "[步骤 6/6] 生成预测\n", "------------------------------------------------------------\n", " 测试样本数: 771207\n", " 预测中...\n", " 预测完成!\n", "\n", " 预测结果统计:\n", " 均值: 0.000635\n", " 标准差: 0.006529\n", " 最小值: -0.125836\n", " 最大值: 0.149914\n" ] } ], "execution_count": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.3 查看结果" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:28:10.746425Z", "start_time": "2026-03-07T16:28:10.723160Z" } }, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"训练结果\")\n", "print(\"=\" * 80)\n", "\n", "results = trainer.results\n", "\n", "print(f\"\\n结果数据形状: {results.shape}\")\n", "print(f\"结果列: {results.columns}\")\n", "print(f\"\\n结果前10行预览:\")\n", "print(results.head(10))\n", "print(f\"\\n结果后5行预览:\")\n", "print(results.tail())\n", "\n", "print(f\"\\n每日预测样本数统计:\")\n", "daily_counts = results.group_by(\"trade_date\").agg(pl.len()).sort(\"trade_date\")\n", "print(f\" 最小: {daily_counts['len'].min()}\")\n", "print(f\" 最大: {daily_counts['len'].max()}\")\n", "print(f\" 平均: {daily_counts['len'].mean():.2f}\")\n", "\n", "# 展示某一天的前10个预测结果\n", "sample_date = results[\"trade_date\"][0]\n", "sample_data = results.filter(results[\"trade_date\"] == sample_date).head(10)\n", "print(f\"\\n示例日期 {sample_date} 的前10条预测:\")\n", "print(sample_data.select([\"ts_code\", \"trade_date\", target_col, \"prediction\"]))" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "================================================================================\n", "训练结果\n", "================================================================================\n", "\n", "结果数据形状: (771207, 25)\n", "结果列: ['ts_code', 'trade_date', 'low', 'close', 'vol', 'high', 'total_mv', 'f_ann_date', 'n_income', 'ma5', 'ma10', 'ma20', 'ma_ratio', 'volatility_5', 'volatility_20', 'vol_ratio', 'return_10', 'return_20', 'return_diff', 'vol_ma5', 'vol_ma20', 'market_cap_rank', 'high_low_ratio', 'return_5', 'prediction']\n", "\n", "结果前10行预览:\n", "shape: (10, 25)\n", "┌───────────┬───────────┬───────────┬───────────┬───┬───────────┬───────────┬───────────┬──────────┐\n", "│ ts_code ┆ trade_dat ┆ low ┆ close ┆ … ┆ market_ca ┆ high_low_ ┆ return_5 ┆ predicti │\n", "│ --- ┆ e ┆ --- ┆ --- ┆ ┆ p_rank ┆ ratio ┆ --- ┆ on │\n", "│ str ┆ --- ┆ f64 ┆ f64 ┆ ┆ --- ┆ --- ┆ f64 ┆ --- │\n", "│ ┆ str ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ f64 │\n", "╞═══════════╪═══════════╪═══════════╪═══════════╪═══╪═══════════╪═══════════╪═══════════╪══════════╡\n", "│ 000001.SZ ┆ 20250102 ┆ 7.215424 ┆ 7.219817 ┆ … ┆ 1.575139 ┆ -1.347097 ┆ -0.002622 ┆ -0.00414 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 1 │\n", "│ 000002.SZ ┆ 20250102 ┆ 7.215424 ┆ 7.219817 ┆ … ┆ 1.500066 ┆ -1.494802 ┆ -0.022509 ┆ -0.00644 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 3 │\n", "│ 000004.SZ ┆ 20250102 ┆ -0.122611 ┆ -0.106629 ┆ … ┆ -1.525498 ┆ -1.110228 ┆ -0.064897 ┆ 0.018069 │\n", "│ 000006.SZ ┆ 20250102 ┆ 1.429646 ┆ 1.41091 ┆ … ┆ 0.645142 ┆ -1.46853 ┆ -0.048278 ┆ -0.00495 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 8 │\n", "│ 000007.SZ ┆ 20250102 ┆ -0.100317 ┆ -0.103205 ┆ … ┆ -1.232326 ┆ -0.209675 ┆ 0.015649 ┆ -0.00123 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 1 │\n", "│ 000008.SZ ┆ 20250102 ┆ -0.063519 ┆ -0.067059 ┆ … ┆ 0.410216 ┆ -1.48541 ┆ -0.066939 ┆ -0.01023 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 3 │\n", "│ 000009.SZ ┆ 20250102 ┆ 0.045333 ┆ 0.039996 ┆ … ┆ 1.197186 ┆ -1.358101 ┆ -0.036045 ┆ 0.002236 │\n", "│ 000010.SZ ┆ 20250102 ┆ -0.293174 ┆ -0.293811 ┆ … ┆ -0.872494 ┆ -1.382331 ┆ 0.092123 ┆ -0.00730 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 3 │\n", "│ 000011.SZ ┆ 20250102 ┆ -0.233141 ┆ -0.235741 ┆ … ┆ -0.098467 ┆ -1.409992 ┆ -0.022094 ┆ -0.00176 │\n", "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 3 │\n", "│ 000012.SZ ┆ 20250102 ┆ 0.54057 ┆ 0.526749 ┆ … ┆ 1.006268 ┆ -1.411495 ┆ -0.029188 ┆ 0.000613 │\n", "└───────────┴───────────┴───────────┴───────────┴───┴───────────┴───────────┴───────────┴──────────┘\n", "\n", "结果后5行预览:\n", "shape: (5, 25)\n", "┌───────────┬───────────┬───────────┬───────────┬───┬───────────┬───────────┬──────────┬───────────┐\n", "│ ts_code ┆ trade_dat ┆ low ┆ close ┆ … ┆ market_ca ┆ high_low_ ┆ return_5 ┆ predictio │\n", "│ --- ┆ e ┆ --- ┆ --- ┆ ┆ p_rank ┆ ratio ┆ --- ┆ n │\n", "│ str ┆ --- ┆ f64 ┆ f64 ┆ ┆ --- ┆ --- ┆ f64 ┆ --- │\n", "│ ┆ str ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ f64 │\n", "╞═══════════╪═══════════╪═══════════╪═══════════╪═══╪═══════════╪═══════════╪══════════╪═══════════╡\n", "│ 605588.SH ┆ 20251231 ┆ -0.150009 ┆ -0.151005 ┆ … ┆ -1.041064 ┆ 0.083361 ┆ null ┆ 0.002801 │\n", "│ 605589.SH ┆ 20251231 ┆ -0.282833 ┆ -0.286372 ┆ … ┆ 1.082326 ┆ 0.586743 ┆ null ┆ 0.003757 │\n", "│ 605598.SH ┆ 20251231 ┆ 0.163451 ┆ 0.166474 ┆ … ┆ 0.865913 ┆ 1.46704 ┆ null ┆ -0.003742 │\n", "│ 605599.SH ┆ 20251231 ┆ -0.360996 ┆ -0.359651 ┆ … ┆ 0.623404 ┆ 1.560273 ┆ null ┆ 0.004761 │\n", "│ 689009.SH ┆ 20251231 ┆ -0.101257 ┆ -0.108012 ┆ … ┆ 1.304467 ┆ -1.339619 ┆ null ┆ -0.000987 │\n", "└───────────┴───────────┴───────────┴───────────┴───┴───────────┴───────────┴──────────┴───────────┘\n", "\n", "每日预测样本数统计:\n", " 最小: 3147\n", " 最大: 3186\n", " 平均: 3173.69\n", "\n", "示例日期 20250102 的前10条预测:\n", "shape: (10, 4)\n", "┌───────────┬────────────┬───────────┬────────────┐\n", "│ ts_code ┆ trade_date ┆ return_5 ┆ prediction │\n", "│ --- ┆ --- ┆ --- ┆ --- │\n", "│ str ┆ str ┆ f64 ┆ f64 │\n", "╞═══════════╪════════════╪═══════════╪════════════╡\n", "│ 000001.SZ ┆ 20250102 ┆ -0.002622 ┆ -0.004141 │\n", "│ 000002.SZ ┆ 20250102 ┆ -0.022509 ┆ -0.006443 │\n", "│ 000004.SZ ┆ 20250102 ┆ -0.064897 ┆ 0.018069 │\n", "│ 000006.SZ ┆ 20250102 ┆ -0.048278 ┆ -0.004958 │\n", "│ 000007.SZ ┆ 20250102 ┆ 0.015649 ┆ -0.001231 │\n", "│ 000008.SZ ┆ 20250102 ┆ -0.066939 ┆ -0.010233 │\n", "│ 000009.SZ ┆ 20250102 ┆ -0.036045 ┆ 0.002236 │\n", "│ 000010.SZ ┆ 20250102 ┆ 0.092123 ┆ -0.007303 │\n", "│ 000011.SZ ┆ 20250102 ┆ -0.022094 ┆ -0.001763 │\n", "│ 000012.SZ ┆ 20250102 ┆ -0.029188 ┆ 0.000613 │\n", "└───────────┴────────────┴───────────┴────────────┘\n" ] } ], "execution_count": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.4 保存结果" ] }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:28:11.060067Z", "start_time": "2026-03-07T16:28:10.751743Z" } }, "cell_type": "code", "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"保存预测结果\")\n", "print(\"=\" * 80)\n", "\n", "# 确保输出目录存在\n", "os.makedirs(OUTPUT_DIR, exist_ok=True)\n", "\n", "# 生成时间戳\n", "start_dt = datetime.strptime(TEST_START, \"%Y%m%d\")\n", "end_dt = datetime.strptime(TEST_END, \"%Y%m%d\")\n", "date_str = f\"{start_dt.strftime('%Y%m%d')}_{end_dt.strftime('%Y%m%d')}\"\n", "\n", "# 保存每日 Top5\n", "print(\"\\n[1/1] 保存每日 Top5 股票...\")\n", "top5_output_path = os.path.join(OUTPUT_DIR, f\"top5_{date_str}.csv\")\n", "\n", "# 按日期分组,取每日 top5\n", "top5_by_date = []\n", "unique_dates = results[\"trade_date\"].unique().sort()\n", "for date in unique_dates:\n", " day_data = results.filter(results[\"trade_date\"] == date)\n", " # 按 prediction 降序排序,取前5\n", " top5 = day_data.sort(\"prediction\", descending=True).head(5)\n", " top5_by_date.append(top5)\n", "\n", "# 合并所有日期的 top5\n", "top5_results = pl.concat(top5_by_date)\n", "\n", "# 格式化日期并调整列顺序:日期、分数、股票\n", "top5_to_save = top5_results.select(\n", " [\n", " pl.col(\"trade_date\").str.slice(0, 4)\n", " + \"-\"\n", " + pl.col(\"trade_date\").str.slice(4, 2)\n", " + \"-\"\n", " + pl.col(\"trade_date\").str.slice(6, 2).alias(\"date\"),\n", " pl.col(\"prediction\").alias(\"score\"),\n", " pl.col(\"ts_code\"),\n", " ]\n", ")\n", "# top5_to_save.write_csv(top5_output_path, include_header=True)\n", "print(f\" 保存路径: {top5_output_path}\")\n", "print(f\" 保存行数: {len(top5_to_save)}({len(unique_dates)}个交易日 × 每日top5)\")\n", "print(f\"\\n 预览(前15行):\")\n", "print(top5_to_save.head(15))" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "================================================================================\n", "保存预测结果\n", "================================================================================\n", "\n", "[1/1] 保存每日 Top5 股票...\n", " 保存路径: output\\top5_20250101_20251231.csv\n", " 保存行数: 1215(243个交易日 × 每日top5)\n", "\n", " 预览(前15行):\n", "shape: (15, 3)\n", "┌────────────┬──────────┬───────────┐\n", "│ trade_date ┆ score ┆ ts_code │\n", "│ --- ┆ --- ┆ --- │\n", "│ str ┆ f64 ┆ str │\n", "╞════════════╪══════════╪═══════════╡\n", "│ 2025-01-02 ┆ 0.129296 ┆ 603007.SH │\n", "│ 2025-01-02 ┆ 0.087661 ┆ 603559.SH │\n", "│ 2025-01-02 ┆ 0.056859 ┆ 000595.SZ │\n", "│ 2025-01-02 ┆ 0.052261 ┆ 600811.SH │\n", "│ 2025-01-02 ┆ 0.046187 ┆ 603366.SH │\n", "│ … ┆ … ┆ … │\n", "│ 2025-01-06 ┆ 0.145456 ┆ 603007.SH │\n", "│ 2025-01-06 ┆ 0.066654 ┆ 603959.SH │\n", "│ 2025-01-06 ┆ 0.06255 ┆ 002691.SZ │\n", "│ 2025-01-06 ┆ 0.054795 ┆ 000638.SZ │\n", "│ 2025-01-06 ┆ 0.047319 ┆ 002713.SZ │\n", "└────────────┴──────────┴───────────┘\n" ] } ], "execution_count": 18 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.5 特征重要性" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:28:11.069209Z", "start_time": "2026-03-07T16:28:11.065068Z" } }, "source": [ "importance = model.feature_importance()\n", "if importance is not None:\n", " print(\"\\n特征重要性:\")\n", " print(importance.sort_values(ascending=False))\n", "\n", "print(\"\\n\" + \"=\" * 80)\n", "print(\"训练完成!\")\n", "print(\"=\" * 80)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "特征重要性:\n", "return_10 3245.995642\n", "ma_ratio 2818.976538\n", "vol_ratio 2701.151667\n", "return_20 2681.762756\n", "high_low_ratio 2469.737874\n", "return_diff 1463.681328\n", "volatility_5 1357.026476\n", "market_cap_rank 722.088673\n", "vol_ma5 653.087969\n", "vol_ma20 631.252641\n", "ma20 548.830554\n", "n_income 495.525785\n", "ma5 469.811824\n", "ma10 305.156890\n", "volatility_20 203.306830\n", "dtype: float64\n", "\n", "================================================================================\n", "训练完成!\n", "================================================================================\n" ] } ], "execution_count": 19 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. 可视化分析\n", "\n", "使用训练好的模型直接绘图。\n", "- **特征重要性图**:辅助特征选择\n", "- **决策树图**:理解决策逻辑" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:28:11.377695Z", "start_time": "2026-03-07T16:28:11.076235Z" } }, "source": [ "# 导入可视化库\n", "import matplotlib.pyplot as plt\n", "import lightgbm as lgb\n", "import pandas as pd\n", "\n", "# 从封装的model中取出底层Booster\n", "booster = model.model\n", "print(f\"模型类型: {type(booster)}\")\n", "print(f\"特征数量: {len(feature_cols)}\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "模型类型: \n", "特征数量: 15\n" ] } ], "execution_count": 20 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.1 绘制特征重要性(辅助特征选择)\n", "\n", "**解读**:\n", "- 重要性高的特征对模型贡献大\n", "- 重要性为0的特征可以考虑删除\n", "- 可以帮助理解哪些因子最有效" ] }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-07T16:28:11.542731Z", "start_time": "2026-03-07T16:28:11.384139Z" } }, "cell_type": "code", "source": [ "print(\"绘制特征重要性...\")\n", "\n", "fig, ax = plt.subplots(figsize=(10, 8))\n", "lgb.plot_importance(\n", " booster, \n", " max_num_features=20,\n", " importance_type='gain',\n", " title='Feature Importance (Gain)',\n", " ax=ax\n", ")\n", "ax.set_xlabel('Importance (Gain)')\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "# 打印重要性排名\n", "importance_gain = pd.Series(\n", " booster.feature_importance(importance_type='gain'),\n", " index=feature_cols\n", ").sort_values(ascending=False)\n", "\n", "print(\"\\n[特征重要性排名 - Gain]\")\n", "print(importance_gain)\n", "\n", "# 识别低重要性特征\n", "zero_importance = importance_gain[importance_gain == 0].index.tolist()\n", "if zero_importance:\n", " print(f\"\\n[低重要性特征] 以下{len(zero_importance)}个特征重要性为0,可考虑删除:\")\n", " for feat in zero_importance:\n", " print(f\" - {feat}\")\n", "else:\n", " print(\"\\n所有特征都有一定重要性\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "绘制特征重要性...\n" ] }, { "data": { "text/plain": [ "
" ], "image/png": "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8847Q50FAwcOtOeee87OOeccW7x4sdumRIkS1r59e7fNoUOHrFWrVu6x3njjDXcMVapUsRNPPNH8litJr2AWp16PkSNH2owZM1zD6YVSL8c999xjLVu2DEzA3bx5c5s3b16K69u2beuee1rs2bPHihUrZlX6vWkJeQr5cJTIbPnikmxMw8N23+I4O3g4V2YfDjIY7Rt8tHGw0b7BRxsHW05s342j20W9vmTJki6brAA60ttvv21du3a1ffv2WZ48/5fDVfD75ptv2pAhQ1yc9vfff1vx4sVDGe4LL7ww2XVHct1111l8fLx7PI+C7zFjxthvv/3mMuSNGze2Jk2aJMt89+vXzxYtWmRffvml+33y5Mnu9rVr17rfldlWjJU3b147Gl7MpSx/eOdBtsxwb9y40b2AahS9SLVr13Yv+qxZs1xJgPeiBcF7773nel/CyzHOOuss69ixY6YeFwAAAICc4fDhwy7AVTCt0vJovEAzPNhevXq1DRs2zAW6v/zyS8z9161b1w4ePGi1atVyiVHFerFoO5WSh1N2+/fff3eZ9sqVK7tt8ufPn2IbZboVNyqonj59unsuih+nTZvmtv/+++/tgQcesLi4OMvRY7h79uzpei70gl111VV2+umnW82aNa1v3772zTffuG3Uu6GSh8KFC7uG79Spk23bti3VTLKy4+Euv/xy6969e+h3Nd6IESOsW7dubr8aL6CG2rFjR+ixVCqxdOnS0H2mTJniOgbUGaAxBNqmTZs2tmXLljQ9V/UilStXLnSZPXu2e4MRcAMAAADw08qVK138ki9fPlcy/v7777sS8kh//vmnDR8+3G677bbQdQp6r732Wpcg1RjpaMqXL+8yze+++667VKxY0cVl3333Xcxjat26tUtKzpkzxxITE+3HH3+0xx9/3N3mxVja5vnnn7dvv/3Wlb8rPtPvCrZ1rKIOAJW/qzNBMZ3ixfHjx7t4z29ZOsOtAfqffPKJKycvVChlebSCW73wXgCscuyEhATXc9G5c2dXtnAsxo0bZ4888ogNHjzY/Xz99de7koWbbrrJvZkGDBjgAvIffvjBdQrI/v373fiGqVOnWu7cuV2pRf/+/e21115L9+O/8MILds0110R97uFvbl3CyxskX+4ki4vL8qMFcBTUtuH/I1ho3+CjjYON9g0+2jjYcmL7KjCV0047zZYs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DQAAAACADwi4AQAAAADwAQE3AAAAAAA+IOAGAAAAAMAHBNwAAAAAAPiAgBsAAAAAAB8QcAMAAAAA4AMCbgAAAAAAfEDADQAAAACADwi4AQAAAADwAQE3AAAAAAA+IOAGAAAAAMAHBNwAAAAAAPiAgBsAAAAAAB8QcAMAAAAA4AMCbgAAAAAAfEDADQCAD+bPn2/t27e3k046yXLlymUffPBBzG1vv/12t8348eNT3DZjxgxr1KiRFShQwEqUKGGXX3556La//vrL2rRp4x4jX758VrFiRbvzzjttz549Rzy+1PYrS5YssZYtW1rx4sXd7a1bt7YVK1aEbj9w4IB1797dateubXny5ElxfwAAkEMC7qFDh1rdunUz+zAAADnIvn377KyzzrKJEyemut37779v33zzjQuaI7377rt2/fXX24033uiC3a+++squu+660O25c+e2Dh062PTp0+3HH3+0KVOm2GeffeYC+NQcab///POPC+RPOeUUW7RokX355ZdWpEgRF3THx8e7bQ4fPuyC9bvuussuuuiio3iFAAAIvjyWDWzdutVGjhzpeuM3b95sZcqUcQH0Pffc43rfg0InMaNGjbKXX37ZPc8zzjjDHn30UXfSk16NRs2xhDyFfDlOZK58cUk2pqFZraGz7ODhXDRHwNC+2d/G0e3c/5dccom7pEbf9b1797ZZs2ZZu3b/u58nISHB7r77bhs7dqzdfPPNoevPPPPM0M/KPN9xxx2h3ytVqmQ9e/Z094klLftdu3at7dy504YNG+ay5vLQQw9ZnTp17Ndff7WqVataoUKFbNKkSe42Bey7du1K0+sDAEBOkuUz3Bs3brT69evb559/7k4OVq5caZ988oldeOGF1qtXLwuSQYMG2X/+8x+bMGGCrV692mUorrjiClu2bFlmHxoAIIMlJia6LPO9995rNWvWTHH7d9995wJyZbHr1atn5cuXdwH8qlWrYu7zjz/+sPfee8+aNWsWc5u07FcdvqVKlbIXXnjBDh06ZP/++6/7uUaNGla5cuUMePYAAOQMWT7gVk+9xrUtXrzYrrrqKjv99NPdiUnfvn1dCZ789ttvrqSucOHCVrRoUevUqZNt27Yt5j6bN2/usuPhNPZMY9E8OqEYMWKEdevWze1XWQOV7O3YsSP0WOrpX7p0aeg+KuXTWDdlKnRSom2Und6y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uu6dd95x2+szpu+RV1991QXdX3/9td12220WFxdnd955Z8zHV7C9ZcsWmz17tvtOu/HGG939Xn/99dBQmg4dOljfvn3ttddec0F+nz597Morr7TvvvvObTNp0iQbOHCgPffcc3bOOefY4sWL7dZbb7USJUpY+/btfX4FAQAAEIiA+++//05x3U8//WR33HGH3XvvvWnejzJDTZo0cdmksWPHWu3atd2JrrJIymYp8AwKdUicdtppLmjQSXo08+bNc89bJ+oJCQn2wAMP2MUXX2yrV69OMRM8EFTKHIcbPXq0ValSxZo1a+Yy3e+++27oNl2vDruuXbu6z0yePHnspptuSnZ/fe4WLlzoOrNiBdxr1qyxTz75xAX7DRo0cNdNmDDB2rZt64L7k046yQXy6ggYMWKE5c79v+Kg/v37uyBc31t58+a1qVOnWo8ePaxz586hx9Y+1XFGwA0AAJDzHFVJeTTVqlVzJ8aR2e8jLS+mE2hlgVSaefrpp1vNmjVdBumbb75x2/z222/uhLZw4cKu1LNTp062bdu2mPts3rx5iszx5Zdfbt27d09WsqqTZmXitV+NSZ8+fbrt2LEj9Fha2mzp0qWh+0yZMsV1DKgzQOWi2qZNmzYuI5YWCqLVqaAZ3vPlyxd1G53w6zj1Gpx11lnuMfX8daIP5ESHDh1ymWoF0fquiEaZZn03KNiORduULFky5u0KyPX59oJtueiii1xgvWjRIve7lkDU7y+99JILvLVPBdjaTsG2HDx40PLnz59s36pW0XecgnIAAADkLBkWcItOeFXamRYaL6kAUxndaNlbnfwmJia6AFjbKvurUs9ffvkllD06FirpVnZ92bJl1q5dO7v++utdAK5MmcpDlTnT71rqLDxLrWyXTrLnz5/vgmFluPzijUtNLVAAguyDDz6wXbt2JeswC/fnn3/a8OHDXel3LCopf/PNN1PdRkNbVIYe+X2mz55uk1NPPdU+/fRTV3miTjN9R/3+++/21ltvhe7TunVre/75510nmb471Gmn3xVs61gBAACQsxxVSbmyweF0YqlM79NPP+2C2LRYv369u1/16tVjbjNnzhxbuXKlGzupsZiiCYiUAVaZprLGR0uloir9FI2t1thL7U8l3zJgwAA777zzXDa9XLly7jqdNE+ePNkF46Ly1GHDhpkf1NmgTL1ez1q1asXc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" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "[特征重要性排名 - Gain]\n", "return_10 3245.995642\n", "ma_ratio 2818.976538\n", "vol_ratio 2701.151667\n", "return_20 2681.762756\n", "high_low_ratio 2469.737874\n", "return_diff 1463.681328\n", "volatility_5 1357.026476\n", "market_cap_rank 722.088673\n", "vol_ma5 653.087969\n", "vol_ma20 631.252641\n", "ma20 548.830554\n", "n_income 495.525785\n", "ma5 469.811824\n", "ma10 305.156890\n", "volatility_20 203.306830\n", "dtype: float64\n", "\n", "所有特征都有一定重要性\n" ] } ], "execution_count": 21 } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.0" } }, "nbformat": 4, "nbformat_minor": 4 }