当前位置: 首页 > news >正文

用Python快速上手5种文本相似度计算:从TF-IDF到Sentence-BERT的保姆级代码示例

Python实战:5种文本相似度算法从原理到代码落地

当我们需要在海量文本中快速找到相似内容时,文本相似度计算就像一把精准的尺子。想象一下电商平台自动推荐相似商品描述,或是新闻APP为你聚合相关报道背后的技术支撑。本文将用最精简的代码带您掌握五种主流方法,每种方法都附带可直接运行的代码块和可视化对比。

1. 环境准备与数据示例

在开始前,我们先配置一个轻量级实验环境。推荐使用Python 3.8+和以下库组合:

pip install scikit-learn gensim transformers rank_bm25 python-Levenshtein matplotlib

准备两组对比数据:英文新闻标题和中文商品描述。我们将用同样的数据测试不同算法:

english_corpus = [ "Global warming causes unprecedented heat waves", "Scientists warn about climate change impacts", "New study reveals rising global temperatures", "Tech giant announces breakthrough in AI chips" ] chinese_corpus = [ "新款智能手机配备4800万像素摄像头", "旗舰手机搭载高分辨率摄影系统", "智能手表支持血氧监测和心率检测", "无线耳机降噪功能升级版发布" ]

2. 基于词频统计的TF-IDF方法

TF-IDF是自然语言处理的"瑞士军刀",通过统计词频和逆文档频率构建文本向量。其核心思想是:一个词在当前文档出现次数越多,同时在所有文档出现次数越少,就越能代表该文档特征。

from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity import matplotlib.pyplot as plt def tfidf_similarity(texts): vectorizer = TfidfVectorizer() tfidf_matrix = vectorizer.fit_transform(texts) similarities = cosine_similarity(tfidf_matrix) plt.figure(figsize=(8,6)) plt.imshow(similarities, cmap='hot', interpolation='nearest') plt.colorbar() plt.title("TF-IDF Similarity Matrix") plt.show() return similarities # 英文示例 tfidf_en = tfidf_similarity(english_corpus) print(f"最高相似度配对:{tfidf_en[0][1]:.2f}")

典型输出结果中,前三条气候相关标题的相似度在0.4-0.6之间,而它们与AI芯片新闻的相似度接近0。TF-IDF的优势在于计算效率高,适合千万级以下文本的快速匹配。

3. 字符串编辑距离实战

当需要处理拼写检查或短文本精确匹配时,Levenshtein距离能直接计算字符级差异。这个算法计算将一个字符串转换成另一个字符串所需的最少单字符编辑(插入、删除或替换)次数。

from Levenshtein import distance as levenshtein_distance import numpy as np def normalize_edit_distance(s1, s2): max_len = max(len(s1), len(s2)) return 1 - (levenshtein_distance(s1, s2) / max_len) def edit_similarity(texts): n = len(texts) sim_matrix = np.zeros((n, n)) for i in range(n): for j in range(i, n): sim = normalize_edit_distance(texts[i], texts[j]) sim_matrix[i][j] = sim_matrix[j][i] = sim plt.matshow(sim_matrix, cmap='Blues') plt.title("Normalized Edit Distance") plt.show() return sim_matrix # 中文示例 edit_cn = edit_similarity(chinese_corpus) print(f"'手机'配对相似度:{edit_cn[0][1]:.2f}")

在商品描述案例中,两款手机描述的归一化相似度约为0.35,而手机与耳机的相似度不足0.1。编辑距离对词序敏感,适合检测文本重组或轻微修改的场景。

4. 词向量平均算法实现

Word2Vec通过神经网络将词汇映射到稠密向量空间,使得语义相似的词距离相近。我们可以通过平均词向量获得整个文本的表示:

from gensim.models import Word2Vec from gensim.utils import simple_preprocess import numpy as np def train_word2vec(corpus): tokenized = [simple_preprocess(text) for text in corpus] model = Word2Vec(tokenized, vector_size=100, window=5, min_count=1, workers=4) return model def word2vec_similarity(model, texts): vectors = [] for text in texts: words = simple_preprocess(text) text_vec = np.mean([model.wv[word] for word in words if word in model.wv], axis=0) vectors.append(text_vec) norms = np.linalg.norm(vectors, axis=1, keepdims=True) norm_vectors = vectors / norms similarities = np.dot(norm_vectors, norm_vectors.T) plt.figure(figsize=(10,8)) plt.scatter(norm_vectors[:,0], norm_vectors[:,1]) for i, text in enumerate(texts): plt.annotate(f"Text {i+1}", (norm_vectors[i,0], norm_vectors[i,1])) plt.title("Word2Vec Text Vector Projection") plt.show() return similarities # 训练并测试英文数据 w2v_model = train_word2vec(english_corpus) w2v_sim = word2vec_similarity(w2v_model, english_corpus) print(f"语义相似度:{w2v_sim[0][1]:.2f}")

词向量方法能捕捉到"global warming"和"climate change"这类语义关联,在示例中显示出0.7以上的相似度。对于专业领域,建议使用预训练模型或领域数据微调。

5. BM25检索算法应用

BM25源自信息检索领域,考虑了词频饱和度和文档长度归一化,特别适合问答系统和搜索引擎场景:

from rank_bm25 import BM25Okapi import jieba def bm25_similarity(corpus): tokenized = [list(jieba.cut(text)) for text in corpus] bm25 = BM25Okapi(tokenized) similarity = np.zeros((len(corpus), len(corpus))) for i, query in enumerate(tokenized): scores = bm25.get_scores(query) similarity[i] = scores / np.max(scores) # 归一化 plt.figure(figsize=(8,6)) plt.plot(similarity[0], 'r-', label='Query1') plt.plot(similarity[1], 'b--', label='Query2') plt.legend() plt.title("BM25 Normalized Scores") plt.show() return similarity # 中文数据测试 bm25_cn = bm25_similarity(chinese_corpus) print(f"手机描述相关性:{bm25_cn[0][1]:.2f}")

BM25对"像素"和"分辨率"这类相关但不同的术语有较好的区分能力,在商品匹配场景中表现出色。算法参数k1和b需要根据数据特点调整,通常k1∈[1.2,2.0],b∈[0.5,0.8]。

6. 预训练模型Sentence-BERT实战

对于需要深度语义理解的场景,基于Transformer的Sentence-BERT提供了最先进的解决方案:

from sentence_transformers import SentenceTransformer from sklearn.metrics.pairwise import cosine_similarity def sbert_similarity(corpus): model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') embeddings = model.encode(corpus) similarities = cosine_similarity(embeddings) plt.figure(figsize=(10,8)) plt.scatter(embeddings[:,0], embeddings[:,1]) for i, text in enumerate(corpus[:4]): # 只标注前四个点 plt.annotate(f"Text {i+1}", (embeddings[i,0], embeddings[i,1])) plt.title("SBERT Embedding Space") plt.show() return similarities # 多语言测试 sbert_sim = sbert_similarity(chinese_corpus + english_corpus) print(f"跨语言相似度示例:{sbert_sim[0][4]:.2f}")

Sentence-BERT不仅能处理多语言混合场景,还能识别"智能手机"和"AI芯片"之间的弱关联。模型下载后首次运行需要联网获取词表,生产环境建议提前缓存。

7. 算法对比与选型指南

我们将五种方法在相同数据上的表现进行横向对比:

算法类型英文相似度范围中文相似度范围计算速度语义理解适用场景
TF-IDF0.3-0.60.2-0.5★★★★★★★☆☆☆快速原型、中等规模文本
编辑距离0.1-0.40.3-0.6★★★★☆★☆☆☆☆拼写检查、短文本匹配
Word2Vec平均0.5-0.80.4-0.7★★★☆☆★★★★☆语义搜索、推荐系统
BM250.4-0.70.5-0.8★★★★☆★★★☆☆搜索引擎、问答系统
Sentence-BERT0.6-0.90.5-0.9★★☆☆☆★★★★★跨语言匹配、精准语义

实际项目中,可以组合多种方法实现分层过滤:先用TF-IDF快速筛选候选集,再用SBERT进行精细排序。对于百万级文本,建议结合近似最近邻(ANN)算法提升性能。

http://www.rkmt.cn/news/1446947.html

相关文章:

  • 告别AXI时序烦恼:手把手教你用米联客FDMA IP在安路FPGA上实现高效DDR数据搬运
  • 2026年实测AI写作辅助软件榜单(安全合规版)
  • 科研绘图实战手册:工具选型、AI赋能与规范化表达 - 品牌2026
  • 汽车电子工程师必看:LIN总线唤醒/睡眠机制详解与AUTOSAR LinSM状态机实战
  • Elden Ring帧率解锁与游戏优化技术深度解析:内存实时补丁实现原理
  • vcomp140.dll 报错先看程序加载阶段,别急着复制文件
  • 当音乐被锁在ncm格式中,你该如何重获自由?
  • 华硕笔记本终极控制神器:5分钟上手GHelper,彻底告别Armoury Crate臃肿烦恼
  • 4C 参数对钻石回收影响,海口门店统一测评 - 合扬奢侈品交易中心
  • 3个颠覆性特性:OnmyojiAutoScript如何重构你的阴阳师游戏体验
  • 手把手教你设计AXI接口的FPGA HyperRAM控制器(附资源占用分析)
  • 告别基站依赖?手把手解析PPP/PPP-RTK技术如何用单台接收机实现高精度定位(含最新进展)
  • 别让PCB布局毁了你的Buck电路!手把手教你避开DCDC转换器设计的5个常见坑
  • 从B站孙老师视频到动手实践:手把手教你用MOS管和电感打造一个高效的12V转5V DC-DC模块
  • 5分钟快速上手:用Python轻松实现手机号查询QQ号工具
  • 宁波市鄞州姜山豫见建材店:首南街道专业的水泥配送公司 - LYL仔仔
  • 3大难题破解:轻松实现B站8K超高清视频下载的完整方案
  • Blink应用设计解析:从动态序列捕捉到极简交互的移动摄影创新
  • 如何快速追踪Elsevier投稿状态:科研工作者的终极自动化解决方案
  • 3PEAK思瑞浦 TPA6581-SC5R SOT353 运算放大器
  • Python之rhelkick包语法、参数和实际应用案例
  • YOLO全系列可视化标注训练工具
  • ADS仿真指南:如何将Matlab算出的EF2类功放参数快速变成理想电路模型
  • AutoX.js实战:模拟京东领券的完整脚本解析与优化思路(附避坑指南)
  • Python之antibuddy包语法、参数和实际应用案例
  • 云原生技术02-containerd、CRI-O、Podman:2026年容器runtime怎么选?
  • 2026年保定修蹄用品全套落地对策:从蹄病预防到修蹄后护理的专业选型方略 - 企业名录优选推荐
  • Arduino光敏传感器洗手定时器:从电路设计到趣味化实现
  • 计算机毕业设计SpringBoot+Vue.js校园二手交易平台 推荐算法+支付+可视化(源码+LW+PPT+讲解)
  • 给xv6内核页表动手术:手把手教你为每个进程创建独立内核页表(MIT6.S081 Lab3实战)