Python中基于文本相似度度量的AI去重实现方案咨询
学术文献数据去重相似度矩阵实现方案
所有实现完全基于Python本地可离线运行的工具库,无需调用外部接口也无需使用dedupe等受限工具,符合隐私合规要求。
依赖库说明
以下库均可提前下载安装包离线部署,全程不需要联网:
- 数据处理:
pandas、numpy - 文本特征与相似度计算:
scikit-learn内置的TF-IDF、余弦相似度实现 - 可选短文本模糊匹配:
fuzzywuzzy(无法安装时可自行实现莱文斯坦距离替换,无额外依赖) - 可选高精准语义匹配:
sentence-transformers提前下载轻量预训练模型到本地加载使用
实现思路
将不同字段按业务属性分别计算相似度后加权融合,权重可根据实际业务场景调整,参考权重设置如下:
- 长文本(标题+摘要)语义相似度:权重0.5
- 关键词匹配相似度:权重0.2
- 作者名模糊匹配相似度:权重0.2
- 年份差相似度:权重0.1
核心代码实现
import pandas as pd import numpy as np from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity from fuzzywuzzy import fuzz def deduplicate(df: pd.DataFrame) -> pd.DataFrame: # 提取ID作为矩阵的行列索引 ids = df['ID'].tolist() record_num = len(ids) # 初始化相似度矩阵 sim_matrix = np.zeros((record_num, record_num)) # 1. 计算标题+摘要长文本相似度 df['full_text'] = df['Title'] + ' ' + df['Abstract'] tfidf = TfidfVectorizer(stop_words='english') text_tfidf = tfidf.fit_transform(df['full_text']) text_sim = cosine_similarity(text_tfidf) # 2. 计算关键词Jaccard相似度 df['keyword_set'] = df['Keywords'].apply(lambda x: set([k.strip().lower() for k in x.split(',')])) keyword_sim = np.zeros((record_num, record_num)) for i in range(record_num): for j in range(record_num): if i == j: keyword_sim[i][j] = 1 continue set_i, set_j = df.loc[i, 'keyword_set'], df.loc[j, 'keyword_set'] intersection = len(set_i & set_j) union = len(set_i | set_j) keyword_sim[i][j] = intersection / union if union != 0 else 0 # 3. 计算作者名模糊匹配相似度 author_sim = np.zeros((record_num, record_num)) for i in range(record_num): for j in range(record_num): if i == j: author_sim[i][j] = 1 continue author_sim[i][j] = fuzz.ratio(df.loc[i, 'Author'], df.loc[j, 'Author']) / 100 # 4. 计算年份相似度 year_arr = df['Year'].values.reshape(-1, 1) year_diff = np.abs(year_arr - year_arr.T) year_sim = np.where(year_diff == 0, 1, np.where(year_diff == 1, 0.8, 0)) # 加权融合得到总相似度 total_sim = text_sim * 0.5 + keyword_sim * 0.2 + author_sim * 0.2 + year_sim * 0.1 # 转换为带ID索引的DataFrame输出 result = pd.DataFrame(total_sim, index=ids, columns=ids) result.index.name = 'ID' return result
使用示例
# 代入示例数据测试 test_data = [ [5875, "Textual Similarity: A Review", "Textual Similarity has been used for measuring ...", "X, Y, Z", "James Thomas", 2018], [8596, "Natural Language Processing: A Review", "Natural Language Processing has been used for ...", "NLP, AI, BERT", "Rami John", 2015], [4586, "Textual Similarity: Systematic Review", "Text Similarity is being used for", "Y, Z, AI", "J Thomas", 2018] ] test_df = pd.DataFrame(test_data, columns=['ID', 'Title', 'Abstract', 'Keywords', 'Author', 'Year']) sim_matrix = deduplicate(test_df) print(sim_matrix)
输出结果的结构与要求完全一致,对角线值为1,相似记录得分更高。
可选优化方案
如果对语义匹配精度要求更高,可提前将轻量预训练模型(比如all-MiniLM-L6-v2)下载到本地,用sentence-transformers加载本地模型生成文本embedding计算相似度,全程不需要联网,符合隐私要求。
内容的提问来源于stack exchange,提问作者saving_space
相关产品推荐
相关产品推荐

