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

基于内容的图书推荐系统分块处理遇Shape不匹配ValueError求助

问题分析

报错ValueError: Shape of passed values is (2, 5000), indices imply (2, 1)的核心原因是数据中存在重复的书名:

  • 当chunk_df里有重复的Title时,indices = pd.Series(chunk_df.index, index=chunk_df["Title"])会让相同书名对应多个行索引。
  • 调用indices[title]会返回包含多个索引的Series,而非单个整数索引,此时cosine_sim[book_index]会提取多行相似度数据(形状为[n, 5000],n是重复书名的数量)。
  • 用这个二维数组创建DataFrame并指定单列["score"]时,就会出现形状不匹配的错误。

另外还有一个潜在问题:每个chunk单独调用tfidf.fit_transform会重新构建词汇表,导致不同chunk的TF-IDF向量维度不一致,跨chunk的推荐逻辑不成立(当前报错是单chunk内的问题,先优先解决)。

解决方案

1. 处理重复书名

方案A:修改推荐函数,兼容重复书名

直接在推荐函数中判断并取第一个匹配的索引:

def content_based_recommender(title, cosine_sim, chunk_df):
    indices = pd.Series(chunk_df.index, index=chunk_df["Title"])
    # 处理重复书名:若返回多个索引则取第一个
    book_index = indices[title].iloc[0] if isinstance(indices[title], pd.Series) else indices[title]
    similarity_scores = pd.DataFrame(cosine_sim[book_index], columns=["score"])
    book_indices = similarity_scores.sort_values("score", ascending=False)[1:11].index
    return chunk_df['Title'].iloc[book_indices].tolist()

方案B:提前去重或标记重复书名

在读取chunk时先处理重复数据,避免后续逻辑出错:

for chunk_number, data_chunk in enumerate(data_chunks, start=1):
    print(f"Processing Chunk {chunk_number}")
    # 方案1:保留每个书名的第一条数据
    data_chunk = data_chunk.drop_duplicates(subset="Title", keep="first")
    # 方案2:给重复书名加序号区分(如"书名 (1)")
    # data_chunk["Title"] = data_chunk["Title"] + " (" + data_chunk.groupby("Title").cumcount().astype(str) + ")"
    
    # 后续代码不变
    tfidf_matrix = tfidf.fit_transform(data_chunk['Blurb'].fillna(''))
    cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)
    
    for title in data_chunk['Title']:
        recommendations = content_based_recommender(title, cosine_sim, data_chunk)
        recommendations_dict['Title'].append(title)
        recommendations_dict['Recommendations'].append(recommendations)

2. 修复TF-IDF词汇表一致性(可选但重要)

如果希望跨chunk的推荐有意义,不能每个chunk都重新训练TF-IDF,应该先全局构建词汇表,再转换每个chunk的数据:

# 第一步:遍历所有chunk,收集文本并训练TF-IDF词汇表
all_blurbs = []
for data_chunk in pd.read_csv("books_with_blurbs.csv", chunksize=chunk_size):
    all_blurbs.extend(data_chunk['Blurb'].fillna('').tolist())

tfidf = TfidfVectorizer(stop_words='english')
tfidf.fit(all_blurbs)

# 第二步:重新读取chunk,用已训练好的TF-IDF转换数据
data_chunks = pd.read_csv("books_with_blurbs.csv", chunksize=chunk_size)
recommendations_dict = {'Title': [], 'Recommendations': []}

for chunk_number, data_chunk in enumerate(data_chunks, start=1):
    print(f"Processing Chunk {chunk_number}")
    # 先处理重复书名(可选)
    data_chunk = data_chunk.drop_duplicates(subset="Title", keep="first")
    
    # 使用transform而非fit_transform,复用全局词汇表
    tfidf_matrix = tfidf.transform(data_chunk['Blurb'].fillna(''))
    cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)
    
    for title in data_chunk['Title']:
        recommendations = content_based_recommender(title, cosine_sim, data_chunk)
        recommendations_dict['Title'].append(title)
        recommendations_dict['Recommendations'].append(recommendations)
验证

修改后运行代码,先确认重复书名的情况是否被处理,再检查TF-IDF词汇表是否全局一致,即可解决报错并优化推荐逻辑的合理性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:31:35