You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何绘制推荐系统的Precision-Recall曲线?

推荐系统Precision-Recall曲线可视化解决方案

问题分析

你遇到的核心问题有三个:

  • 未正确初始化SparkRankingEvaluation评估器,导致precision_at_k()和recall_at_k()调用失败
  • Scikit-learn的precision_recall_curve和PrecisionRecallDisplay仅支持本地数据(如Pandas DataFrame/Numpy数组),无法直接处理Spark DataFrame
  • 推荐系统排序任务的Precision-Recall曲线,是基于不同Top-K阈值下的precision和recall值绘制,而非二分类任务的阈值曲线

解决方案步骤

1. 修正评估器初始化

首先需要正确创建SparkRankingEvaluation实例,关联真实标签与预测结果数据:

# 初始化排序评估器
spark_rank_eval = SparkRankingEvaluation(
    dfs_true,
    dfs_pred,
    **HEADER
)

2. 定义正例规则(可选)

排序任务需明确正样本定义,比如将评分≥3标记为正例(可根据业务调整),评估器默认按此逻辑计算,也可通过rating_threshold参数修改阈值。

3. 计算多k值下的precision和recall

选择一系列k值(如1到10),遍历计算每个k对应的precision@k和recall@k:

import matplotlib.pyplot as plt

# 定义要计算的k值范围
k_values = range(1, 11)
precisions = []
recalls = []

for k in k_values:
    prec = spark_rank_eval.precision_at_k(k=k)
    rec = spark_rank_eval.recall_at_k(k=k)
    precisions.append(prec)
    recalls.append(rec)

4. 绘制Precision-Recall曲线

用Matplotlib将计算出的precision和recall值绘制成曲线:

plt.figure(figsize=(8, 6))
plt.plot(recalls, precisions, marker='o', linestyle='-', color='b')
plt.xlabel('Recall@k')
plt.ylabel('Precision@k')
plt.title('推荐系统Precision-Recall曲线')
plt.grid(True)
plt.show()

完整可运行代码

import pandas as pd
import pyspark
import sklearn
import matplotlib.pyplot as plt
from recommenders.utils.spark_utils import start_or_get_spark
from recommenders.evaluation.spark_evaluation import SparkRankingEvaluation, SparkRatingEvaluation

COL_USER = "UserId"
COL_ITEM = "MovieId"
COL_RATING = "Rating"
COL_PREDICTION = "Rating"

HEADER = {
    "col_user": COL_USER, 
    "col_item": COL_ITEM, 
    "col_rating": COL_RATING, 
    "col_prediction": COL_PREDICTION
}

df_true = pd.DataFrame(
    {
        COL_USER: [1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
        COL_ITEM: [1, 2, 3, 1, 4, 5, 6, 7, 2, 5, 6, 8, 9, 10, 11, 12, 13, 14],
        COL_RATING: [5, 4, 3, 5, 5, 3, 3, 1, 5, 5, 5, 4, 4, 3, 3, 3, 2, 1],
    }
)
df_pred = pd.DataFrame(
    {
        COL_USER: [1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
        COL_ITEM: [3, 10, 12, 10, 3, 5, 11, 13, 4, 10, 7, 13, 1, 3, 5, 2, 11, 14],
        COL_PREDICTION: [14, 13, 12, 14, 13, 12, 11, 10, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5]
    }
)

# 初始化Spark环境
spark = start_or_get_spark("EvaluationTesting", "local")

# 转为Spark DataFrame
dfs_true = spark.createDataFrame(df_true)
dfs_pred = spark.createDataFrame(df_pred)

# 初始化排序评估器
spark_rank_eval = SparkRankingEvaluation(
    dfs_true,
    dfs_pred,
    **HEADER,
    rating_threshold=3  # 自定义正例阈值,评分≥3视为正样本
)

# 计算多k值下的precision和recall
k_values = range(1, 11)
precisions = []
recalls = []

for k in k_values:
    precisions.append(spark_rank_eval.precision_at_k(k=k))
    recalls.append(spark_rank_eval.recall_at_k(k=k))

# 绘制Precision-Recall曲线
plt.figure(figsize=(8, 6))
plt.plot(recalls, precisions, marker='o', linestyle='-', color='#1f77b4')
plt.xlabel('Recall@k')
plt.ylabel('Precision@k')
plt.title('推荐系统Precision-Recall曲线')
plt.grid(alpha=0.3)
plt.show()

关键说明

  • 推荐系统的Precision-Recall曲线与二分类任务不同:它展示的是不同Top-K推荐列表长度下,模型的精准度和召回率变化趋势,而非分类阈值的影响
  • 若需要更平滑的曲线,可以增加k值的密度(如k从1到20)
  • rating_threshold参数可根据业务场景调整,比如将评分≥4视为正样本

内容的提问来源于stack exchange,提问作者Rachel Tran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:02:04