#!/usr/bin/env python
# coding=utf-8
"""
Step3: 分析原因 - 对比模型预估值与真实值，找出偏差来源
"""
import pandas as pd
from pathlib import Path
import glob

# 读取并合并数据
data_dir = Path(__file__).parent / "output" / "step3_原因分析"
all_files = glob.glob(str(data_dir / "*.csv"))
df = pd.concat([pd.read_csv(f) for f in all_files], ignore_index=True)

print("=" * 70)
print("Step3: 分析原因")
print("=" * 70)

# 1. 数据概览
print("\n【1. 数据概览】")
print(f"样本数: {len(df)} 条")
print(f"视频数: {df['vid'].nunique()}")
print(f"日期范围: {df['dt'].min()} ~ {df['dt'].max()}")

# 2. 计算各分项偏差
df['str_bias'] = df['pred_str'] - df['real_str']
df['ros_bias'] = df['pred_ros'] - df['real_ros']
df['vor_bias'] = df['pred_vor'] - df['real_vor']

# 百分比偏差（避免除0）
df['str_bias_pct'] = df.apply(lambda x: (x['pred_str'] - x['real_str']) / x['real_str'] * 100 if x['real_str'] > 0 else None, axis=1)
df['ros_bias_pct'] = df.apply(lambda x: (x['pred_ros'] - x['real_ros']) / x['real_ros'] * 100 if pd.notna(x['real_ros']) and x['real_ros'] > 0 else None, axis=1)
df['vor_bias_pct'] = df.apply(lambda x: (x['pred_vor'] - x['real_vor']) / x['real_vor'] * 100 if pd.notna(x['real_vor']) and x['real_vor'] > 0 else None, axis=1)

# 3. 整体偏差分析
print("\n【2. 各分项偏差统计】")
print(f"str 偏差: 平均 {df['str_bias'].mean():+.6f} ({df['str_bias_pct'].mean():+.1f}%)")
print(f"ros 偏差: 平均 {df['ros_bias'].mean():+.4f} ({df['ros_bias_pct'].mean():+.1f}%)")
print(f"vor 偏差: 平均 {df['vor_bias'].mean():+.4f} ({df['vor_bias_pct'].mean():+.1f}%)")

# 4. 按视频汇总
print("\n【3. 按视频汇总偏差】")
vid_stats = df.groupby('vid').agg({
    'sample_cnt': 'sum',
    'pred_str': 'mean',
    'real_str': 'mean',
    'str_bias_pct': 'mean',
    'pred_ros': 'mean',
    'real_ros': 'mean',
    'ros_bias_pct': 'mean',
    'pred_vor': 'mean',
    'real_vor': 'mean',
    'vor_bias_pct': 'mean',
    'real_vov': 'mean'
}).round(4)
vid_stats.columns = ['样本数', '预估str', '真实str', 'str偏差%', '预估ros', '真实ros', 'ros偏差%', '预估vor', '真实vor', 'vor偏差%', '真实vov']
vid_stats = vid_stats.reset_index()
print(vid_stats.to_string(index=False))

# 5. 找出主要偏差来源
print("\n【4. 主要偏差来源分析】")
avg_str_bias = abs(df['str_bias_pct'].mean())
avg_ros_bias = abs(df['ros_bias_pct'].mean())
avg_vor_bias = abs(df['vor_bias_pct'].mean())

biases = [('str', avg_str_bias), ('ros', avg_ros_bias), ('vor', avg_vor_bias)]
biases.sort(key=lambda x: x[1], reverse=True)

print(f"偏差排序: {biases[0][0]}({biases[0][1]:.1f}%) > {biases[1][0]}({biases[1][1]:.1f}%) > {biases[2][0]}({biases[2][1]:.1f}%)")
print(f"\n主要偏差来源: {biases[0][0].upper()}")

# 6. 详细分析主要偏差
main_bias = biases[0][0]
if main_bias == 'ros':
    print("\n【5. ROS 偏差详细分析】")
    print("ros 预估偏高的可能原因:")
    print("  1. XGB 模型使用历史 ros 作为特征，但头部视频的 ros 会随时间衰减")
    print("  2. 模型训练样本偏向高分享场景，导致对低分享场景预估偏高")
    print("  3. 头部视频的分享用户结构变化（早期核心用户 → 后期普通用户）")
elif main_bias == 'str':
    print("\n【5. STR 偏差详细分析】")
    print("str 预估偏差的可能原因:")
    print("  1. FM 模型采样率校正有偏差")
    print("  2. 头部视频的分享行为与训练样本分布不同")
elif main_bias == 'vor':
    print("\n【5. VOR 偏差详细分析】")
    print("vor 预估偏差的可能原因:")
    print("  1. vor 使用 24h 统计量，存在滞后性")
    print("  2. 头部视频的裂变效率在快速变化")

# 保存结果
print("\n" + "=" * 70)
print("【Step3 结论】")
print("=" * 70)
print(f"主要偏差来源: {biases[0][0].upper()} (平均偏差 {biases[0][1]:+.1f}%)")
print(f"次要偏差来源: {biases[1][0].upper()} (平均偏差 {biases[1][1]:+.1f}%)")

# 保存到文件
output_dir = Path(__file__).parent / "output"

# 保存合并后的数据
df.to_csv(output_dir / "step3_预估vs真实_合并.csv", index=False)

# 保存视频汇总
vid_stats.to_csv(output_dir / "step3_按视频汇总.csv", index=False)

# 保存结论
with open(output_dir / "step3_结论.txt", 'w', encoding='utf-8') as f:
    f.write("=" * 70 + "\n")
    f.write("Step3: 分析原因\n")
    f.write("=" * 70 + "\n\n")

    f.write("【各分项偏差统计】\n")
    f.write(f"str 偏差: 平均 {df['str_bias'].mean():+.6f} ({df['str_bias_pct'].mean():+.1f}%)\n")
    f.write(f"ros 偏差: 平均 {df['ros_bias'].mean():+.4f} ({df['ros_bias_pct'].mean():+.1f}%)\n")
    f.write(f"vor 偏差: 平均 {df['vor_bias'].mean():+.4f} ({df['vor_bias_pct'].mean():+.1f}%)\n\n")

    f.write("【主要偏差来源】\n")
    f.write(f"排序: {biases[0][0]}({biases[0][1]:.1f}%) > {biases[1][0]}({biases[1][1]:.1f}%) > {biases[2][0]}({biases[2][1]:.1f}%)\n")
    f.write(f"结论: {biases[0][0].upper()} 是主要偏差来源\n")

print(f"\n结果已保存到 output/ 目录")
