PySpark中两个DataFrame文本列的余弦相似度计算问题求助
余弦相似度分析实现方案
实现前提
你已完成停用词移除、词干提取等文本预处理操作,待处理的两个DataFrame结构如下:
- df1:仅1行数据,包含词干提取后的文本列,内容为
every solut catch except new - df2:共4条测试数据,包含
colum_num、词干提取后的文本列两个字段
输出要求
- 为df2的每一行新增列,显示该行与df1文本的余弦相似度值
- 输出相似度最高的匹配结果,包含
df1原始文本、最高相似度匹配文本、对应相似度值三个字段
原有代码问题说明
你编写的手动计算函数本身逻辑正确,结果不符合预期大概率是缺失正则变量WORD定义、列名匹配错误等调用环节问题。以下提供两种可直接运行的实现方案,结果完全一致,可按需选择:
完整实现代码
依赖导入
import math import pandas as pd from collections import Counter import re from sklearn.feature_extraction.text import CountVectorizer from sklearn.metrics.pairwise import cosine_similarity # 补全你原有代码缺失的正则匹配规则 WORD = re.compile(r"\w+")
模拟测试数据(实际使用时替换为你自己的df1、df2即可)
# 假设预处理后的文本列统一命名为processed_text,可替换为你的实际列名 df1 = pd.DataFrame({'processed_text': ['every solut catch except new']}) df2 = pd.DataFrame({ 'colum_num': [1,2,3,4], 'processed_text': [ 'every solut catch old problem', 'new solut except error', 'every catch new test case', 'random text no match' ] })
方案1:沿用自定义计算函数实现
def text_to_vector(text): words = WORD.findall(text) return Counter(words) def get_cosine(vec1, vec2): intersection = set(vec1.keys()) & set(vec2.keys()) numerator = sum([vec1[x] * vec2[x] for x in intersection]) sum1 = sum([vec1[x] ** 2 for x in list(vec1.keys())]) sum2 = sum([vec2[x] ** 2 for x in list(vec2.keys())]) denominator = math.sqrt(sum1) * math.sqrt(sum2) if not denominator: return 0.0 else: return float(numerator) / denominator # 提取df1的文本与向量 df1_text = df1['processed_text'].iloc[0] vec1 = text_to_vector(df1_text) # 第一部分输出:df2全量数据带相似度值 df2['cosine_similarity'] = df2['processed_text'].apply(lambda x: get_cosine(vec1, text_to_vector(x))) print("=== df2全量相似度结果 ===") print(df2[['colum_num', 'processed_text', 'cosine_similarity']]) # 第二部分输出:最高相似度匹配结果 max_row = df2.loc[df2['cosine_similarity'].idxmax()] max_result = pd.DataFrame({ 'df1原始文本': [df1_text], '最高相似度匹配文本': [max_row['processed_text']], '对应相似度值': [max_row['cosine_similarity']] }) print("\n=== 最高相似度匹配结果 ===") print(max_result)
方案2:用sklearn工具库实现(更适合大规模数据)
# 合并文本构建词袋 all_text = pd.concat([df1['processed_text'], df2['processed_text']]) vectorizer = CountVectorizer().fit(all_text) # 文本转向量 df1_vec = vectorizer.transform(df1['processed_text']) df2_vec = vectorizer.transform(df2['processed_text']) # 批量计算相似度 similarities = cosine_similarity(df1_vec, df2_vec).flatten() # 第一部分输出:df2全量数据带相似度值 df2['cosine_similarity'] = similarities print("=== df2全量相似度结果 ===") print(df2[['colum_num', 'processed_text', 'cosine_similarity']]) # 第二部分输出:最高相似度匹配结果 max_idx = similarities.argmax() max_result = pd.DataFrame({ 'df1原始文本': [df1['processed_text'].iloc[0]], '最高相似度匹配文本': [df2['processed_text'].iloc[max_idx]], '对应相似度值': [similarities[max_idx]] }) print("\n=== 最高相似度匹配结果 ===") print(max_result)
内容的提问来源于stack exchange,提问作者Morello
相关产品推荐
相关产品推荐

