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

在PySpark中基于评分集求解基线预测器并计算单元格偏差

解决PySpark中基线预测器的偏差计算问题

嘿,我来帮你搞定这个基线预测的计算!首先咱们得明确,基线预测的核心逻辑是全局平均评分 + 用户偏差 + 物品偏差(等价于用户平均评分 + 物品平均评分 - 全局平均评分)。你的DataFrame现在是宽格式(用户为行,物品为列),这种格式不太方便做分组统计,所以咱们先转成长格式,一步步计算各个偏差项,最后再转回宽格式就能得到你想要的结果啦。

步骤1:转换宽格式为长格式

首先把你的宽表转成(user_code, item_id, rating)的长格式,这样方便后续计算用户和物品的平均评分:

from pyspark.sql import functions as F

# 假设你的原始DataFrame名为ratings_df
long_df = ratings_df.select(
    F.col("user_code"),
    # 把所有物品列拆成(item_id, rating)的结构体,再炸开
    F.explode(F.array(
        *[F.struct(F.lit(col).alias("item_id"), F.col(col).alias("rating")) 
          for col in ratings_df.columns if col != "user_code"]
    )).alias("temp")
).select(
    "user_code",
    F.col("temp.item_id"),
    F.col("temp.rating")
)

步骤2:计算核心统计量

接下来计算全局平均评分、用户偏差和物品偏差:

# 1. 计算全局平均评分μ
global_mean = long_df.select(F.avg(F.col("rating"))).first()[0]

# 2. 计算用户偏差:b_u = 用户平均评分 - 全局均值
user_bias = long_df.groupBy("user_code")\
    .agg(F.avg("rating").alias("user_avg"))\
    .withColumn("b_u", F.col("user_avg") - global_mean)\
    .drop("user_avg")

# 3. 计算物品偏差:b_i = 物品平均评分 - 全局均值
item_bias = long_df.groupBy("item_id")\
    .agg(F.avg("rating").alias("item_avg"))\
    .withColumn("b_i", F.col("item_avg") - global_mean)\
    .drop("item_avg")

步骤3:生成所有(user, item)组合的基线预测

因为原始数据里有null(未评分的单元格),所以我们需要生成所有用户和物品的组合,再计算每个组合的基线值:

# 获取所有唯一的用户和物品
users = long_df.select("user_code").distinct()
items = long_df.select("item_id").distinct()

# 交叉连接得到所有可能的(user, item)组合
all_combinations = users.crossJoin(items)

# 合并偏差数据,计算基线值:baseline = μ + b_u + b_i
baseline_df = all_combinations.join(user_bias, on="user_code", how="left")\
    .join(item_bias, on="item_id", how="left")\
    .withColumn("baseline", global_mean + F.col("b_u") + F.col("b_i"))\
    .select("user_code", "item_id", "baseline")

步骤4:转回宽格式匹配期望输出

最后把长格式的基线数据转回宽格式,就得到你想要的矩阵形式了:

final_baseline = baseline_df.groupBy("user_code")\
    .pivot("item_id")\
    .agg(F.first("baseline"))\
    .withColumnRenamed("user_code", "user/item")

# 查看结果
final_baseline.show()

举个例子,用你提供的原始数据计算:

  • 全局均值μ = (1+1+1+1+2+1+2)/7 ≈ 1.2857
  • 用户975072的偏差b_u = (1+1)/2 - 1.2857 ≈ -0.2857
  • 物品56691的偏差b_i = (1+1+2)/3 - 1.2857 ≈ 0.0476
  • 该单元格的基线值 = 1.2857 + (-0.2857) + 0.0476 ≈ 1.0476(和你给出的1.083略有差异,可能是四舍五入或者计算方式微调,但核心逻辑一致)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:43:20