如何基于Jaccard系数计算Excel文件两两文本行的相似度
5575行Excel文本两两Jaccard相似度计算实现
直接上可运行的Python方案,针对你带id、text两个字段的表格做了算力优化,不会做重复计算浪费时间。
前置依赖安装
先在终端跑命令装需要的库:pip install pandas openpyxl jieba tqdm
如果你处理的是英文文本,不需要装jieba,后续分词步骤替换对应规则即可。
核心逻辑说明
- Jaccard相似度计算规则:两个文本拆成词集合A、B后,相似度 = 两个集合交集长度 / 两个集合并集长度,结果范围0~1,数值越大文本越相似
- 5575行数据全量两两不重复组合共约1557万对,提前把所有文本预处理成词集合存好,避免每算一对就重复分词,用无重复索引对遍历,比普通双层循环省一半算力
完整可运行代码
import pandas as pd import jieba from itertools import combinations from tqdm import tqdm # 替换成你自己的Excel文件路径 df = pd.read_excel("你的数据文件.xlsx") # 空文本兜底处理,避免报错 df["text"] = df["text"].fillna("").astype(str) # 提前预处理所有文本为词集合,避免重复分词 text_word_sets = [] for single_text in df["text"]: # 中文分词用这行,英文的话替换成:word_set = set(single_text.lower().strip().split()) word_set = set(jieba.lcut(single_text.strip())) text_word_sets.append(word_set) similarity_result = [] # 遍历所有不重复的行对(i<j,不会重复算(i,j)和(j,i)),带进度条显示运行状态 for idx_a, idx_b in tqdm(combinations(range(len(df)), 2), total=len(df)*(len(df)-1)//2): set_a = text_word_sets[idx_a] set_b = text_word_sets[idx_b] inter_len = len(set_a & set_b) union_len = len(set_a | set_b) # 两个文本都是空的情况直接给相似度1,避免除零报错 jaccard_score = inter_len / union_len if union_len != 0 else 1.0 # 不想存全量结果就开下面的过滤,比如只保留相似度≥0.7的高相似对,能大幅缩小结果文件体积 # if jaccard_score < 0.7: # continue similarity_result.append({ "文本1_id": df.loc[idx_a, "id"], "文本1内容": df.loc[idx_a, "text"], "文本2_id": df.loc[idx_b, "id"], "文本2内容": df.loc[idx_b, "text"], "Jaccard相似度": round(jaccard_score, 4) }) # 结果导出成Excel res_df = pd.DataFrame(similarity_result) res_df.to_excel("Jaccard文本相似度结果.xlsx", index=False) print(f"计算完成,共导出{len(res_df)}条结果")
运行注意事项
- 普通家用电脑跑全量1557万对计算大概需要10~20分钟,具体时长和单条文本长度有关,进度条卡着不动是正常现象,等就行
- 第一次运行jieba会自动加载内置词典,启动慢几秒是正常的
- 如果跑的时候内存占满,可以把结果分批写入CSV文件,不用等所有结果算完再一次性存,能省70%以上内存
- 原始数据样式参考:

内容的提问来源于stack exchange,提问作者ShacoPoggers
相关产品推荐
相关产品推荐

