# Summary Area Under the [[ROC]] Curve **AUC = 0.75** 意味着: - 随机选择一个有病的患者(如张三) - 随机选择一个没病的患者(如钱七) - 模型给有病患者的预测分数 > 没病患者分数的概率是75% **AUC的核心价值**: 1. **不受类别不平衡影响**:即使正负样本比例悬殊也能正确评估 2. **考虑所有可能的阈值**:不需要预先设定决策阈值 3. **直观的概率解释**:正样本得分高于负样本的概率 4. **适合排序任务**:不仅关心分类对错,还关心排序质量 **实际应用建议**: - AUC < 0.6:模型基本无用 - AUC 0.6-0.7:有一定效果,但需改进 - AUC 0.7-0.8:效果不错 - AUC 0.8-0.9:效果很好 - AUC > 0.9:效果优秀(但要注意是否过拟合) # Cues # Notes 我来用几个实际例子详细介绍AUC(Area Under the ROC Curve)。 ## 什么是AUC? AUC是**ROC曲线下的面积**,用于评估二分类模型的性能。取值范围是[0,1],越接近1表示模型越好。 ## 实例1:医院诊断系统 ### 场景设定 医院开发了一个AI系统,根据血液检查结果预测患者是否患有糖尿病。 ```python # 10个患者的真实情况和AI预测 patients = [ # (姓名, AI预测概率, 真实情况) ("张三", 0.95, 1), # 1表示有病 ("李四", 0.85, 1), ("王五", 0.75, 0), # 0表示没病 ("赵六", 0.65, 1), ("钱七", 0.55, 0), ("孙八", 0.45, 0), ("周九", 0.35, 0), ("吴十", 0.25, 1), ("郑一", 0.15, 0), ("陈二", 0.05, 0), ] ``` ### 计算AUC的过程 #### 步骤1:按预测概率排序 ```python # 按AI预测概率从高到低排序 sorted_patients = [ ("张三", 0.95, 1), # ✓ 预测高,确实有病 ("李四", 0.85, 1), # ✓ 预测高,确实有病 ("王五", 0.75, 0), # ✗ 预测高,但没病(假阳性) ("赵六", 0.65, 1), # ✓ 预测较高,确实有病 ("钱七", 0.55, 0), # ✓ 预测中等,确实没病 ("孙八", 0.45, 0), # ✓ 预测较低,确实没病 ("周九", 0.35, 0), # ✓ 预测较低,确实没病 ("吴十", 0.25, 1), # ✗ 预测低,但有病(假阴性) ("郑一", 0.15, 0), # ✓ 预测低,确实没病 ("陈二", 0.05, 0), # ✓ 预测低,确实没病 ] ``` #### 步骤2:计算不同阈值下的TPR和FPR ```python # 如果我们设置不同的阈值 thresholds = [1.0, 0.95, 0.85, 0.75, 0.65, 0.55, 0.45, 0.35, 0.25, 0.15, 0.05, 0] # 阈值=0.5时的混淆矩阵 """ 预测概率 >= 0.5 → 预测为有病 预测概率 < 0.5 → 预测为没病 结果: - 真阳性(TP): 张三、李四、赵六 = 3 - 假阳性(FP): 王五、钱七 = 2 - 真阴性(TN): 孙八、周九、郑一、陈二 = 4 - 假阴性(FN): 吴十 = 1 TPR = TP/(TP+FN) = 3/4 = 0.75 FPR = FP/(FP+TN) = 2/6 = 0.33 """ ``` #### 步骤3:绘制ROC曲线 ```python import matplotlib.pyplot as plt # ROC曲线上的点 fpr = [0, 0.17, 0.33, 0.33, 0.5, 0.67, 0.83, 1.0] tpr = [0, 0.5, 0.5, 0.75, 0.75, 0.75, 0.75, 1.0] plt.figure(figsize=(8, 6)) plt.plot(fpr, tpr, 'b-', linewidth=2, label='ROC曲线') plt.plot([0, 1], [0, 1], 'k--', label='随机猜测') plt.fill_between(fpr, tpr, alpha=0.3) plt.xlabel('假阳性率 (FPR)') plt.ylabel('真阳性率 (TPR)') plt.title('糖尿病诊断系统的ROC曲线') plt.legend() plt.grid(True, alpha=0.3) ``` ### AUC的直观理解 **AUC = 0.75** 意味着: - 随机选择一个有病的患者(如张三) - 随机选择一个没病的患者(如钱七) - 模型给有病患者的预测分数 > 没病患者分数的概率是75% ## 实例2:银行信用卡欺诈检测 ### 场景 银行需要识别信用卡交易是否为欺诈。 ```python # 交易数据示例 transactions = pd.DataFrame({ 'transaction_id': range(1000), 'amount': [100, 5000, 50, 10000, ...], # 交易金额 'time': ['凌晨3点', '下午2点', ...], # 交易时间 'location': ['异地', '本地', ...], # 交易地点 'fraud_score': [0.92, 0.15, 0.78, ...], # AI预测的欺诈概率 'is_fraud': [1, 0, 1, 0, ...] # 实际是否欺诈 }) ``` ### 不同AUC值的实际含义 ```python # AUC = 0.5(随机猜测) """ 银行场景:AI系统完全没用,和抛硬币一样 后果:大量欺诈交易被放过,正常交易被误拦 """ # AUC = 0.7(一般) """ 银行场景:能识别出一些明显的欺诈模式 - 凌晨大额异地交易 → 高概率欺诈 - 白天小额本地交易 → 低概率欺诈 后果:减少了一些损失,但仍有改进空间 """ # AUC = 0.9(优秀) """ 银行场景:能准确识别复杂的欺诈模式 - 考虑用户历史行为 - 识别异常消费模式 - 检测设备异常 后果:显著减少欺诈损失,用户体验良好 """ # AUC = 0.99(极好) """ 银行场景:几乎能识别所有欺诈 后果:欺诈损失降到最低,很少误报 """ ``` ## 实例3:电商推荐系统 ### 场景 电商平台预测用户是否会购买推荐的商品。 ```python # 用户-商品推荐数据 recommendations = [ # (用户, 商品, 预测购买概率, 实际是否购买) ("用户A", "iPhone", 0.88, 1), # 高收入用户看了多次 ("用户B", "充电线", 0.72, 1), # 刚买了手机 ("用户C", "冰箱", 0.68, 0), # 上个月刚买过 ("用户D", "零食", 0.61, 1), # 经常买零食 ("用户E", "奢侈品包", 0.45, 0), # 收入不匹配 # ... 更多数据 ] ``` ### AUC在业务中的应用 ```python # 计算不同推荐策略的AUC strategies = { "随机推荐": 0.50, # 完全随机 "基于浏览历史": 0.65, # 看过就推荐 "协同过滤": 0.75, # 相似用户买过 "深度学习模型": 0.85, # 综合多种特征 } # 业务影响 for strategy, auc in strategies.items(): if auc == 0.50: print(f"{strategy}: 转化率≈2%,收入低") elif auc == 0.65: print(f"{strategy}: 转化率≈5%,有一定效果") elif auc == 0.75: print(f"{strategy}: 转化率≈10%,效果不错") elif auc == 0.85: print(f"{strategy}: 转化率≈20%,效果显著") ``` ## 实例4:简历筛选系统 ### 场景 HR系统自动筛选简历,预测候选人是否适合某职位。 ```python # 候选人数据 candidates = pd.DataFrame({ 'name': ['小明', '小红', '小刚', ...], 'education': ['985硕士', '普通本科', '211本科', ...], 'experience_years': [5, 2, 8, ...], 'skill_match': [0.9, 0.6, 0.8, ...], 'ai_score': [0.92, 0.45, 0.78, ...], # AI综合评分 'hired': [1, 0, 1, ...] # 最终是否录用 }) ``` ### AUC的实际意义 ```python # 假设AUC = 0.8 """ 这意味着: - 如果随机选一个最终被录用的候选人(小明) - 再随机选一个没被录用的候选人(小红) - AI给小明的分数 > 小红的概率是80% 实际效果: - HR可以优先面试高分候选人 - 节省80%的筛选时间 - 减少错过优秀人才的概率 """ ``` ## 为什么AUC比准确率更好? ### 实例:疾病筛查 ```python # 罕见疾病:1000人中只有10人患病 total = 1000 sick = 10 healthy = 990 # 模型A:全部预测为健康 model_A_accuracy = 990/1000 = 0.99 # 99%准确率! model_A_auc = 0.5 # 但AUC只有0.5(随机水平) # 模型B:能识别出8个病人,但误报了50个 model_B_accuracy = (8 + 940)/1000 = 0.948 # 94.8%准确率 model_B_auc = 0.85 # AUC达到0.85 # 结论:模型B虽然准确率低,但AUC高,实际更有用 ``` ## AUC的计算代码 ```python from sklearn.metrics import roc_auc_score, roc_curve import numpy as np # 实际计算AUC def calculate_auc_manually(y_true, y_scores): """ 手动计算AUC,帮助理解原理 """ # 获取正负样本 positives = [(score, 1) for score, label in zip(y_scores, y_true) if label == 1] negatives = [(score, 0) for score, label in zip(y_scores, y_true) if label == 0] # 计算每对正负样本的比较结果 total_pairs = len(positives) * len(negatives) correct_pairs = 0 for pos_score, _ in positives: for neg_score, _ in negatives: if pos_score > neg_score: correct_pairs += 1 elif pos_score == neg_score: correct_pairs += 0.5 auc = correct_pairs / total_pairs return auc # 使用sklearn计算 y_true = [1, 1, 0, 1, 0, 0, 0, 1, 0, 0] y_scores = [0.95, 0.85, 0.75, 0.65, 0.55, 0.45, 0.35, 0.25, 0.15, 0.05] auc = roc_auc_score(y_true, y_scores) print(f"AUC = {auc:.3f}") ``` ## 总结