基于TF-IDF+语义相似度的长文本相似度计算

本文介绍如何使用word2vec进行词向量训练,包括数据预处理、模型训练及相似度计算,并展示了关键词提取与向量化过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要步骤流程:

文本预处理:分词

训练词向量

tf-idf提取关键词并写入文档 前20个词

word2vec读取提取的关键词并转为词向量

相似度计算。

前面对word2vec的理论进行了介绍,接下来进入实战环节。实践主要分为三部分,word2vec训练,相似度计算以及训练结果展示三部分。

词向量的训练:

词向量的训练主要分为两部分:

1、对中文语料进行数据预处理;

2、利用gensim模块训练词向量。

中文语料处理:

在用语料库进行训练词向量之前需要对中文句子进行分词,这里采用jieba中文分词工具对句子进行分词。具体代码如下:

import GrobalParament
import jieba
import pandas as pd

#去掉回车换行
def delete_r_n(line):
    return line.replace("\r","").replace("\n","").strip()

#读取停用词
def get_stop_words(stop_words_dir):
    stop_words = []

    with open(stop_words_dir, "r", encoding=GrobalParament.encoding) as f_reader:
        for line in f_reader:
            line = delete_r_n(line)
            stop_words.append(line)

    stop_words = set(stop_words)
    return stop_words


#结巴精准分词
def jieba_cut(content, stop_words):
    word_list = []

    if content != "" and content is not None:
        seg_list = jieba.cut(content)
        for word in seg_list:
            if word not in stop_words:
                word_list.append(word)

    return word_list

#结巴索索引擎分词
def jieba_cut_for_search(content, stop_words):
    word_list = []

    if content != "" and content is not None:
        seg_list = jieba.cut_for_search(content)
        for word in seg_list:
            if word not in stop_words:
                word_list.append(word)

    return word_list

#清除不在词汇表中的词语
def clear_word_from_vocab(word_list, vocab):
    new_word_list = []

    for word in word_list:
        if word in vocab:
            new_word_list.append(word)

    return new_word_list

#文本预处理
def preprocessing_text_pd(text_dir, after_process_text_dir, stop_words_dir):
    stop_words = get_stop_words(stop_words_dir)
    setences = []
    df = pd.read_csv(text_dir)
    for index, row in df.iterrows():
        print(index)
        title = delete_r_n(row['title'])
        word_list = jieba_cut(title, stop_words)
        df.loc[index,'title'] = " ".join(word_list)
        setences.append(word_list)
    df.to_csv(after_process_text_dir,encoding=GrobalParament.encoding, index=False)
    return setences

#文本预处理第二种方式
def preprocessing_text(text_dir, after_process_text_dir, stop_words_dir):
    stop_words = get_stop_words(stop_words_dir)
    setences = []
    f_writer = open(after_process_text_dir,"w", encoding=GrobalParament.encoding)
    count = 0
    with open(text_dir, "r", encoding=GrobalParament.encoding) as f_reader:
        for line in f_reader:
            line_list = line.split(",")
            if len(line_list) == 2:
                line_list[1] = delete_r_n(line_list[1])
                word_list = jieba_cut(line_list[1], stop_words)
                setences.append(word_list)
                f_writer.write(line_list[0] + "," + " ".join(word_list) + "\n")
                f_writer.flush()
                count = count + 1
                print(count)
            else:
                pass
                # print(line)

    f_writer.close()
    return setences


if __name__ == "__main__":
    stop_words = get_stop_words(GrobalParament.stop_word_dir)
    setences = preprocessing_text(GrobalParament.test_set_dir, GrobalParament.test_after_process_text_dir, GrobalParament.stop_word_dir)
    # setences = preprocessing_text_pd(GrobalParament.train_set_dir, GrobalParament.train_after_process_text_dir, GrobalParament.stop_word_dir)
    #print(setences[:10])

最后将处理后的语料存入txt文档中,处理后的语料如下图所示:

                                   

向量化训练:

利用gensim模块训练词向量。之前有详细介绍训练方法和参数设置,这里不再累赘。

import GrobalParament
import utils
from gensim.models import word2vec

#训练word2vec
def train(sentences, model_out_put_path):
    print("开始训练")
    model = word2vec.Word2Vec(sentences = sentences, size = GrobalParament.train_size, window = GrobalParament.train_window, min_count = 20)
    model.save(model_out_put_path)
    print("训练完成")

if __name__ == "__main__":
    # sentences = utils.preprocessing_text(GrobalParament.train_set_dir, GrobalParament.train_after_process_text_dir, GrobalParament.stop_word_dir)
    # train(sentences, GrobalParament.model_output_path)
    model = word2vec.Word2Vec.load(GrobalParament.model_output_path)
    vocab = list(model.wv.vocab.keys())
    for e in model.most_similar(positive = ['漏水'], topn = 10):
        print(e[0],e[1])
    print(len(vocab))

word2vec计算文本相似度:

Word2vec计算文本相似度的基本方法是:提取文本中的关键词,接着将关键词向量化,然后将得到的各个词向量相加,最后得到的一个词向量总和代表文本向量化表示,利用总的向量计算网页相似度。包括的步骤是:1、关键词提取,2、关键词向量化,3、相似度计算。

关键词提取

这里采用的是jieba工具包中tf-idf关键词提取算法。提取结果如下:

关键词向量化

从txt文件中读取关键词,利用之前训练好的词向量获取关键词的词向量。

相似度计算

通过余弦相似度计算向量的相似度,并返回top10。

训练结果:

### TF-IDF语义相似度的概念 #### TF-IDF概念 TF-IDF(Term Frequency-Inverse Document Frequency),即词频-逆文档频率,是信息检索和文本挖掘领域常用的加权技术。该方法通过统计词语在单篇文档内的出现频率以及在整个文档集合中的分布情况来衡量词语的重要性[^1]。 对于给定的一个词t,在某一篇特定的文章d里: - **TF(t,d)** 表示这个词在这篇文章里的出现次数除以这篇文章总字数; - **IDF(t,D)** 则反映了这个词在整个文档集D中相对稀有的程度,定义为log(总数/含有该词的文档数量)[^3]。 两者相乘得到的结果能够有效突出那些既频繁出现在当前文档又不常见于其他文档的关键术语。 #### 语义相似度概念 相比之下,“语义相似度”关注的是两个表达之间意义层面的一致性或接近度,而不仅仅是基于表面形式上的匹配。它试图捕捉更深层次的语言结构特性,比如同义替换、上下位关系等。为了实现这一点,现代自然语言处理通常会借助预训练好的大规模语言模型如BERT, RoBERTa等来进行编码表示学习,从而获得更加贴近人类认知习惯的理解方式[^4]。 ### 关系区别联系 尽管二者都可用于评估文本间的关联强度,但在具体应用场景和技术手段上存在显著差异: - **计算基础不同**: 如前所述,TF-IDF依赖于简单的统计规律;而语义相似度则更多依靠复杂的神经网络架构去建模句子间潜在的意义连接。 - **适用范围各异**: 当面对主题明确的小规模封闭域问题时,采用TF-IDF往往已经足够高效准确;但对于涉及广泛背景知识的大规模开放型任务而言,则可能需要引入更为先进的语义分析工具才能取得理想效果。 然而值得注意的是,随着研究进展,目前也有不少工作尝试融合这两种思路的优势,例如利用TF-IDF作为初始筛选机制后再进一步运用深度学习框架做精细化调整优化,以此达到兼顾效率与质量的目的。 ```python from sklearn.feature_extraction.text import TfidfVectorizer import numpy as np def calculate_tfidf_similarity(documents): vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(documents) cosine_similarities = (X * X.T).A return cosine_similarities documents = ["这是一句话", "这是另一句话"] print(calculate_tfidf_similarity(documents)) ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Steven灬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值