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

基于同Dir_Id的电影Plot余弦相似度计算异常排查

同导演电影Plot余弦相似度计算问题分析与解决

问题背景

现有电影数据结构如下:

Movie_Id  Dir_Id  Genre            Production_House   Plot
        1231      14      Drama               Columbia      Text blob
        1232      16      Romance             Paramount     Text blob
        1233      14      Thriller            Miramax       Text blob
        1234      15      Comedy              Warner Bros.  Text blob
        1235      16      Romantic Comedy     Paramount     Text blob
        1236      16      Drama               Columbia      Text blob
         .         .      .                       .             .
         .         .      .                       .             .

需求:针对指定Movie_Id,仅计算与同Dir_Id电影在Plot列的余弦相似度,且支持动态切换目标Movie_Id(如查询1234时仅考虑Dir_Id为15的电影)。

现有代码与问题

尝试了以下代码:

index = index_from_movie_id(df, movie_id) # 获取原DataFrame中目标电影的索引
director = dir_from_movie_id(df, movie_id) # 获取目标电影的导演ID
in_dir_df = df[df['Dir_Id'] == director]
tf_idf_dir = TfidfVectorizer(stop_words='english')
tf_idf_dir_matrix = tf_idf_dir.fit_transform(in_dir_df['Plot'])
cosine_similarity_dir_matrix = cosine_similarity(tf_idf_dir_matrix, tf_idf_dir_matrix)
similarity_scores = list(enumerate(cosine_similarity_dir_matrix[index]))

执行print(similarity_scores)时,得到了其他Dir_Id电影的索引,不符合预期。

问题根源

核心错误是混淆了原DataFrame的行索引和子集的位置索引:

  1. index是原完整DataFrame中目标电影的行索引(比如原DataFrame中Movie_Id=1234的索引可能是3)
  2. in_dir_df是原DataFrame的子集,它的行索引继承自原DataFrame,但余弦相似度矩阵cosine_similarity_dir_matrix的维度是子集的行数,其索引是子集内部的0-based位置索引(比如子集只有1部电影时,索引是0)
  3. 用原DataFrame的index去访问余弦矩阵的行,会取到错误的位置(甚至越界),导致结果包含无关电影的索引。

修正方案

需要先获取目标电影在子集内部的位置索引,再用该索引访问余弦矩阵,最后关联子集的原索引/Movie_Id:

# 获取目标电影的导演ID
director = dir_from_movie_id(df, movie_id)
# 筛选同导演的电影子集
in_dir_df = df[df['Dir_Id'] == director].copy()

# 关键:获取目标电影在子集内部的位置索引(0-based)
# 方法1:先找到目标电影在子集的原索引,再转成位置索引
target_original_idx = in_dir_df[in_dir_df['Movie_Id'] == movie_id].index[0]
target_subset_idx = in_dir_df.index.get_loc(target_original_idx)

# 方法2:更简洁的方式(如果子集内Movie_Id唯一)
target_subset_idx = in_dir_df[in_dir_df['Movie_Id'] == movie_id].iloc[0].name
target_subset_idx = in_dir_df.index.get_loc(target_subset_idx)

# 构建TF-IDF矩阵
tf_idf_dir = TfidfVectorizer(stop_words='english')
tf_idf_dir_matrix = tf_idf_dir.fit_transform(in_dir_df['Plot'])
# 计算余弦相似度
cosine_sim_matrix = cosine_similarity(tf_idf_dir_matrix, tf_idf_dir_matrix)

# 获取同导演电影的相似度分数,关联原DataFrame的索引
similarity_scores = list(zip(in_dir_df.index, cosine_sim_matrix[target_subset_idx]))

# 可选:直接关联Movie_Id,更直观
similarity_scores_with_movie_id = [
    (in_dir_df.loc[idx, 'Movie_Id'], score) 
    for idx, score in similarity_scores
]

关键说明

  • 必须用子集内部的位置索引访问余弦矩阵,才能确保只获取同导演电影的相似度
  • 通过zip(in_dir_df.index, ...)可以把相似度分数和原DataFrame的行索引绑定,进而映射到对应的Movie_Id,得到符合需求的结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:05:33