#!/usr/bin/env python
# coding=utf-8
"""
V2 Step2: 统一口径分析
在同一张表上验证：预估值 vs 真实值
"""
import pandas as pd
import numpy as np
from pathlib import Path

output_dir = Path(__file__).parent / "output"

# 读取数据（合并多天）
import glob
data_dir = output_dir / "v2_step2_统一口径"
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("V2 Step2: 统一口径分析")
print("=" * 70)

print(f"\n数据量: {len(df)} 个视频")

# 1. 整体偏差统计
print("\n【1. 整体偏差统计】")
print(f"ROS 偏差均值: {df['ros_bias_pct'].mean():+.1f}%")
print(f"ROS 偏差中位数: {df['ros_bias_pct'].median():+.1f}%")
print(f"STR 偏差均值: {df['str_bias_pct'].mean():+.1f}%")
print(f"STR 偏差中位数: {df['str_bias_pct'].median():+.1f}%")

# 2. COPC（整体）
print("\n【2. 整体 COPC】")
ros_copc = df['real_ros'].sum() / df['pred_ros'].sum()
str_copc = df['real_str'].sum() / df['pred_str'].sum()
print(f"ROS COPC = {ros_copc:.4f} (1.0为理想)")
print(f"STR COPC = {str_copc:.4f}")

# 3. 按曝光量分组（头部 vs 尾部）
print("\n【3. 按曝光量分组】")
df['exp_group'] = pd.qcut(df['total_exp'], q=3, labels=['低曝光', '中曝光', '高曝光'])
group_stats = df.groupby('exp_group', observed=True).agg({
    'ros_bias_pct': ['mean', 'median'],
    'str_bias_pct': ['mean', 'median'],
    'vid': 'count'
}).round(1)
print(group_stats)

# 4. 按真实ROS分组（验证回归均值问题）
print("\n【4. 按真实ROS分组】")
df['real_ros_group'] = pd.cut(df['real_ros'], bins=[0, 2, 4, 6, 100], labels=['<2', '2-4', '4-6', '>6'])
ros_group_stats = df.groupby('real_ros_group', observed=True).agg({
    'pred_ros': 'mean',
    'real_ros': 'mean',
    'ros_bias_pct': ['mean', 'count']
}).round(2)
ros_group_stats.columns = ['预估ROS', '真实ROS', '偏差%', '样本数']
print(ros_group_stats)

# 5. 核心验证：预估score高但真实score低的视频
print("\n【5. 核心问题验证】")
# 计算预估排名和真实排名
df['pred_rank'] = df['pred_score'].rank(ascending=False)
df['real_rank'] = df['real_score'].rank(ascending=False)
df['rank_diff'] = df['real_rank'] - df['pred_rank']  # 正数表示真实排名比预估差

# 预估Top10但真实排名差的视频
pred_top10 = df[df['pred_rank'] <= 10].copy()
print(f"预估排名Top10的视频:")
print(f"  真实排名均值: {pred_top10['real_rank'].mean():.1f}")
print(f"  排名差距均值: {pred_top10['rank_diff'].mean():.1f}")

# 问题视频：预估Top10但真实排名 > 20
problem_vids = pred_top10[pred_top10['real_rank'] > 15]
print(f"  预估Top10但真实排名>15: {len(problem_vids)} 个 ({len(problem_vids)/10*100:.0f}%)")

# 6. 预估排名 vs 真实排名 相关性
rank_corr = df['pred_rank'].corr(df['real_rank'])
print(f"\n预估排名与真实排名相关系数: {rank_corr:.4f}")
print(f"（1.0为完美，越低说明排序越不准）")

# 7. 详细看问题视频
if len(problem_vids) > 0:
    print("\n【6. 问题视频详情】")
    print("预估排名靠前但真实排名差的视频:")
    for _, row in problem_vids.iterrows():
        print(f"  vid={row['vid']}: 预估rank={int(row['pred_rank'])}, 真实rank={int(row['real_rank'])}")
        print(f"    ROS偏差={row['ros_bias_pct']:+.1f}%, STR偏差={row['str_bias_pct']:+.1f}%")

# 8. 结论
print("\n" + "=" * 70)
print("【V2 Step2 结论】")
print("=" * 70)
print(f"""
口径统一后的发现:
  1. ROS 整体 COPC = {ros_copc:.2f} ({'偏高' if ros_copc < 1 else '偏低' if ros_copc > 1 else '正常'})
  2. STR 整体 COPC = {str_copc:.2f}
  3. 预估排名与真实排名相关系数 = {rank_corr:.2f}
  4. 预估Top10中，{len(problem_vids)/10*100:.0f}% 真实排名 > 15

结论:
  - 相关系数 {rank_corr:.2f} {'较高，排序整体合理' if rank_corr > 0.7 else '偏低，排序有改进空间' if rank_corr > 0.5 else '较低，排序问题明显'}
""")

# 保存
df.to_csv(output_dir / "v2_step2_统一口径_分析.csv", index=False)
