You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何基于TF-IDF与成对相似度实现文档搜索?(pandas/sklearn实践)

基于TF-IDF与成对相似度实现文档搜索的后续步骤

你已经搞定了语料库构建、预处理和TF-IDF模型训练这些基础工作,接下来几步就能把搜索功能搭起来,我一步步给你拆解:

1. 生成待搜索文本的TF-IDF向量

⚠️ 这里有个关键注意点:必须用你之前训练好的TfidfVectorizer实例来转换待搜索文本,绝对不能重新调用fit方法!否则会生成新的词汇表,和语料库的TF-IDF矩阵维度不匹配,相似度计算就完全失效了。

示例代码:

# 假设你之前训练的TF-IDF向量器叫tfidf_vectorizer
# 待搜索文本的预处理后的DataFrame叫search_df,预处理列命名为'processed_text'
search_tfidf = tfidf_vectorizer.transform(search_df['processed_text'])

2. 计算成对相似度(优先用余弦相似度)

文本场景下最常用的相似度算法就是余弦相似度,它能衡量两个TF-IDF向量在空间中的夹角,值越接近1代表文档越相似。sklearn的cosine_similarity可以直接帮你计算待搜索文本和整个语料库的相似度矩阵。

示例代码:

from sklearn.metrics.pairwise import cosine_similarity

# 假设语料库的TF-IDF矩阵叫corpus_tfidf
similarity_scores = cosine_similarity(search_tfidf, corpus_tfidf)[0]
# 这里取[0]是因为如果search_df只有一条待搜索文本,结果是(1, N)的矩阵,第一行就是每个语料库文档的相似度分数

3. 关联分数与原语料库,排序取Top N结果

把相似度分数和你的语料库DataFrame绑定,然后按分数降序排列,就能得到最相关的文档列表。

示例代码:

# 假设你的语料库DataFrame叫corpus_df,包含原始文本、文档ID等信息
corpus_df['similarity_score'] = similarity_scores

# 按相似度降序排序,取前5个最相关的文档
top_results = corpus_df.sort_values(by='similarity_score', ascending=False).head(5)

# 打印核心结果看看
print(top_results[['document_id', 'original_text', 'similarity_score']])

4. 封装成可复用的搜索函数

把上面的步骤打包成函数,以后输入搜索词就能直接得到结果,用起来更方便:

def search_documents(query_text, tfidf_vectorizer, corpus_tfidf, corpus_df, top_n=5):
    # 预处理查询文本(必须和你预处理语料库的逻辑完全一致!)
    processed_query = preprocess_text(query_text)  # 假设你有一个preprocess_text预处理函数
    # 转换为TF-IDF向量
    query_tfidf = tfidf_vectorizer.transform([processed_query])
    # 计算相似度
    similarity_scores = cosine_similarity(query_tfidf, corpus_tfidf)[0]
    # 关联分数并排序
    corpus_df['similarity_score'] = similarity_scores
    top_results = corpus_df.sort_values(by='similarity_score', ascending=False).head(top_n)
    return top_results

# 使用示例
query = "你的搜索关键词或完整句子"
results = search_documents(query, tfidf_vectorizer, corpus_tfidf, corpus_df)
print(results)

一些实用优化技巧

  • 预处理一致性:待搜索文本的预处理逻辑(分词、去停用词、小写化、词干/词形还原等)必须和语料库的预处理完全相同,否则会严重影响相似度计算的准确性。
  • 阈值过滤:如果结果太多,可以设置最低相似度分数(比如0.3),过滤掉不相关的文档:
    filtered_results = top_results[top_results['similarity_score'] > 0.3]
    
  • 调整TF-IDF参数:比如设置ngram_range=(1,2)加入二元词组、用max_df/min_df过滤太常见或太罕见的词,能进一步提升搜索效果。
  • 尝试其他相似度算法:除了余弦相似度,也可以试试欧氏距离(值越小越相似),不过余弦相似度在文本场景下表现最优。

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

火山引擎 最新活动