Initial commit: BTC 1h prediction model (53.10% accuracy)

🎯 项目成果:
- 准确率: 53.10% (2026年测试集)
- 任务类型: 二分类 (预测涨/跌)
- 特征: OHLCV + RSI + MACD (9个特征)
- 训练数据: 2020-2025年BTC小时数据 (52,351序列)
- 测试数据: 2026年1-29日 (484序列)

📊 性能指标:
- 精确率: 51.79%
- 召回率: 49.36%
- F1分数: 0.5054
- 预测分布: 非常平衡 (偏差仅-11个)

🔬 实验历史:
- 尝试了5种方案 (回归/分类, 不同数据划分)
- 分类任务优于回归任务 (53.10% vs 49.5%)
- 全量训练避免了过拟合问题

📦 主要模型文件:
- models/checkpoints/dlinear_classification_2026/
  - best_model.pt (最佳模型)
  - preprocessor.pkl (预处理器)
  - test_2026_results.json (测试结果)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
crypto_predictorandClaude Sonnet 4.5 committed 2026-01-29 21:27:15 +08:00
commit 9bbdc8d42b
82 files changed
+8742

No files matched your search

+244
View File
@@ -0,0 +1,244 @@
"""详细对比二分类和回归任务在加密货币预测中的差异"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import numpy as np
import pandas as pd
from data.fetcher import BinanceDataFetcher
from data.preprocessor import CryptoPreprocessor
def compare_classification_vs_regression():
print("="*80)
print("二分类 vs 回归任务详细对比")
print("="*80)
# 获取少量数据用于演示
print("\n[1/3] 获取示例数据...")
fetcher = BinanceDataFetcher()
df = fetcher.fetch_ohlcv('BTC', '1h', use_cache=True)
df_sample = df.tail(200).copy() # 只取最近200小时
print(f"✓ 样本数据: {len(df_sample)} 行")
print(f"✓ 时间范围: {df_sample['timestamp'].min()} 至 {df_sample['timestamp'].max()}")
# 对比两种任务
print("\n[2/3] 对比两种任务的标签生成...")
# 二分类任务
print("\n" + "="*80)
print("📊 任务1: 二分类(Binary Classification)")
print("="*80)
preprocessor_cls = CryptoPreprocessor(
lookback=24,
forecast_horizon=1,
price_change_threshold=0.0
)
# 创建标签
df_sample['future_price'] = df_sample['close'].shift(-1)
df_sample['future_return'] = (df_sample['future_price'] - df_sample['close']) / df_sample['close']
df_sample['label_classification'] = (df_sample['future_return'] > 0).astype(int)
print(f"\n目标: 预测价格会上涨(1)还是下跌(0)")
print(f"\n标签生成公式:")
print(f" future_return = (未来价格 - 当前价格) / 当前价格")
print(f" label = 1 if future_return > 0 else 0")
print(f"\n具体例子(前10个样本):")
print(f"{'时间':<20} {'当前价格':<12} {'未来价格':<12} {'收益率':<10} {'标签':<8}")
print("-"*80)
for i in range(10):
row = df_sample.iloc[i]
if pd.notna(row['future_return']):
label = "上涨(1)" if row['label_classification'] == 1 else "下跌(0)"
print(f"{str(row['timestamp']):<20} ${row['close']:<11,.2f} ${row['future_price']:<11,.2f} "
f"{row['future_return']*100:>7.2f}% {label:<8}")
print(f"\n标签统计:")
n_up = df_sample['label_classification'].sum()
n_down = len(df_sample) - n_up - df_sample['label_classification'].isna().sum()
print(f" 上涨(1): {n_up} 个")
print(f" 下跌(0): {n_down} 个")
print(f" 比例: {n_up/(n_up+n_down)*100:.1f}% vs {n_down/(n_up+n_down)*100:.1f}%")
print(f"\n模型输出:")
print(f" 格式: 0-1之间的概率值")
print(f" 例如: 0.73 表示 73% 概率上涨")
print(f" 决策: 如果概率 > 0.5 → 预测上涨")
print(f" 如果概率 < 0.5 → 预测下跌")
print(f"\n评估指标:")
print(f" - 准确率 (Accuracy)")
print(f" - 精确率 (Precision)")
print(f" - 召回率 (Recall)")
print(f" - F1分数")
print(f" - 混淆矩阵")
print(f"\n优点:")
print(f" ✅ 简单直观(涨/跌二选一)")
print(f" ✅ 评估指标清晰")
print(f" ✅ 适合交易决策(做多/做空)")
print(f"\n缺点:")
print(f" ❌ 丢失了涨跌幅度信息")
print(f" ❌ 涨0.1%和涨10%被视为一样")
print(f" ❌ 无法评估风险收益比")
# 回归任务
print("\n" + "="*80)
print("📈 任务2: 回归(Regression)")
print("="*80)
df_sample['label_regression'] = df_sample['future_return']
print(f"\n目标: 预测价格变化的百分比")
print(f"\n标签生成公式:")
print(f" label = (未来价格 - 当前价格) / 当前价格")
print(f" 直接预测收益率(可正可负)")
print(f"\n具体例子(前10个样本):")
print(f"{'时间':<20} {'当前价格':<12} {'未来价格':<12} {'收益率(标签)':<15}")
print("-"*80)
for i in range(10):
row = df_sample.iloc[i]
if pd.notna(row['future_return']):
print(f"{str(row['timestamp']):<20} ${row['close']:<11,.2f} ${row['future_price']:<11,.2f} "
f"{row['label_regression']*100:>12.4f}%")
print(f"\n标签统计:")
valid_returns = df_sample['label_regression'].dropna()
print(f" 最小值: {valid_returns.min()*100:.4f}%")
print(f" 最大值: {valid_returns.max()*100:.4f}%")
print(f" 均值: {valid_returns.mean()*100:.4f}%")
print(f" 标准差: {valid_returns.std()*100:.4f}%")
print(f" 中位数: {valid_returns.median()*100:.4f}%")
print(f"\n模型输出:")
print(f" 格式: 连续的数值(收益率)")
print(f" 例如: 0.0235 表示预测上涨 2.35%")
print(f" -0.0178 表示预测下跌 1.78%")
print(f" 决策: 根据预测值大小决定仓位")
print(f" 预测+5% → 大仓位做多")
print(f" 预测+0.5% → 小仓位做多")
print(f"\n评估指标:")
print(f" - RMSE (均方根误差)")
print(f" - MAE (平均绝对误差)")
print(f" - MAPE (平均绝对百分比误差)")
print(f" - 方向准确率 (预测方向是否正确)")
print(f" - R² (决定系数)")
print(f"\n优点:")
print(f" ✅ 保留了涨跌幅度信息")
print(f" ✅ 可以评估风险收益比")
print(f" ✅ 支持动态仓位管理")
print(f" ✅ 提供更精细的预测")
print(f"\n缺点:")
print(f" ❌ 预测难度更高")
print(f" ❌ 容易过拟合")
print(f" ❌ 对异常值敏感")
# 对比分析
print("\n[3/3] 详细对比分析...")
print("\n" + "="*80)
print("🔍 详细对比")
print("="*80)
comparison = [
["维度", "二分类", "回归"],
["-"*30, "-"*40, "-"*40],
["预测目标", "方向(涨/跌)", "具体涨跌幅度"],
["输出范围", "0-1(概率)", "-∞ to +∞(收益率)"],
["输出示例", "0.73(73%概率上涨)", "+0.0235(预测涨2.35%)"],
["标签类型", "离散(0或1)", "连续(实数)"],
["损失函数", "BCEWithLogitsLoss", "MSELoss / MAELoss"],
["评估指标", "准确率、F1分数", "RMSE、MAE、MAPE"],
["决策方式", "二元(做多/做空)", "连续(仓位大小)"],
["信息量", "少(只有方向)", "多(方向+幅度)"],
["预测难度", "中等", "困难"],
["适用场景", "简单交易策略", "精细化资金管理"],
]
for row in comparison:
print(f"{row[0]:<30} {row[1]:<40} {row[2]:<40}")
# 实际应用对比
print("\n" + "="*80)
print("💰 实际交易应用对比")
print("="*80)
print("\n场景1: 预测未来1小时BTC会上涨")
print("\n二分类模型:")
print(" 输出: 0.68 (68%概率上涨)")
print(" 决策: 概率>0.5,买入BTC")
print(" 行动: 全仓做多(或固定仓位如50%)")
print(" 问题: 不知道预期涨多少,无法评估风险")
print("\n回归模型:")
print(" 输出: +0.0023 (预测上涨0.23%)")
print(" 决策: 预测值>0,买入BTC")
print(" 行动: 根据预测幅度调整仓位(0.23%很小,可能只用10%仓位)")
print(" 优势: 知道预期收益,可以计算风险收益比")
print("\n场景2: 预测未来1小时BTC大涨")
print("\n二分类模型:")
print(" 输出: 0.72 (72%概率上涨)")
print(" 决策: 买入BTC")
print(" 问题: 72%概率可能是涨0.1%,也可能是涨5%,无法区分")
print("\n回归模型:")
print(" 输出: +0.0480 (预测上涨4.8%)")
print(" 决策: 买入BTC")
print(" 行动: 预期涨幅大,可以加大仓位(如80%)")
print(" 优势: 可以根据预期收益调整风险敞口")
# 性能对比
print("\n" + "="*80)
print("📊 当前项目的实际性能对比")
print("="*80)
print("\n二分类任务(当前已实现):")
print(" 准确率: 49.76%(接近随机)")
print(" F1分数: 0.3898")
print(" 召回率: 31.85%")
print(" 问题: 预测能力极弱")
print("\n回归任务(未实现):")
print(" 预期性能: 可能更差")
print(" 原因: 预测具体数值比预测方向更难")
print(" 但优势: 即使方向准确率50%,如果能准确预测幅度,仍可盈利")
# 建议
print("\n" + "="*80)
print("💡 建议")
print("="*80)
print("\n选择二分类的情况:")
print(" ✅ 初学者或概念验证")
print(" ✅ 简单的做多/做空策略")
print(" ✅ 预测周期较长(1天以上)")
print(" ✅ 只关心方向,不关心幅度")
print("\n选择回归的情况:")
print(" ✅ 需要精细化资金管理")
print(" ✅ 需要评估风险收益比")
print(" ✅ 有足够多的训练数据")
print(" ✅ 想要更丰富的预测信息")
print("\n对于1小时BTC预测:")
print(" 当前结论: 两者都很难!")
print(" 二分类: 准确率49.76%(已验证)")
print(" 回归: 预计MAPE会很高(未验证,但大概率也很差)")
print("\n 核心问题: 1小时价格变化接近随机游走")
print(" 建议: 延长预测周期到24小时或更长")
print("\n" + "="*80)
print("✓ 对比分析完成")
print("="*80)
if __name__ == "__main__":
compare_classification_vs_regression()