机器学习与深度学习——基于潜在语义分析(LSA)的文档相似度计算

机器学习与深度学习——基于潜在语义分析(LSA)的文档相似度计算

基于潜在语义分析(LSA)是一种使用数学和统计方法来分析文本数据的技术。该技术可用于发现文本之间的关系,以及为文本提供有关其含义的更深层次的信息。

下面是LDA模型的详细描述:

收集语料库:首先需要收集一个包含大量文本数据的语料库。这些文本可以是任何类型的,例如新闻文章、博客、论文等等。

构建词汇表:然后从语料库中提取所有不同的单词,并构建一份称为“词汇表”的列表。此外,还需要将每个单词映射到唯一的ID上。

创建文档-词频矩阵:接下来,需要将文本数据转换为数字形式。为此,可以创建一个称为“文档 - 词频”矩阵的矩阵,其中每行表示一个文档,每列表示一个单词。每个元素表示该单词在该文档中出现的次数。

进行奇异值分解(SVD):接下来,需要对文档 - 词频矩阵进行奇异值分解(SVD)。SVD是一种数学技术,可将矩阵分解为三个矩阵的乘积。这些矩阵包括一个表示文档的矩阵、一个表示主题的矩阵和一个表示单词的矩阵。

选择主题数量:选择要提取的主题数量,该数量通常是根据实验和经验来确定的。

提取主题:使用前面步骤中计算得到的主题矩阵和单词矩阵,可以提取文本数据中存在的主题。每个主题都表示一组相关联的单词,可以用于理解文本含义。

应用模型:基于提取的主题,可以应用该模型来进行各种任务,例如文本聚类、分类和信息检索等。

LDA模型使用SVD技术将文本数据转换为数字形式,并提供有关文本数据之间的相似性和含义的更深层次的见解。

下面我们通过一个案例来更进一步了解和学习LSA。

目的

  1. 使用Jieba库对句子进行中文分词,并输出分词结果
  2. 基于潜在语义分析(LSA)对18个docx文档进行文本相似度分析

基本思路

1、读取文档集合:从指定目录中读取所有的.docx文件,并将它们的内容存储在docs列表中。
2、对于每个文档,执行预处理操作(例如去除停用词、分词和词干提取等),并使用gensim库创建文档-单词矩阵
3、创建文档-单词矩阵:使用CountVectorizer将文档集合转换为文档-单词矩阵表示形式,其中每个元素表示相应文档中的单词出现次数。
4、训练 LSA 模型:使用TruncatedSVD进行降维操作,将文档-单词矩阵转换为潜在语义空间表示形式。
5、创建索引和相似度矩阵:使用MatrixSimilarity创建相似度矩阵,用于计算文档之间的相似度。
6、使用相似度矩阵计算文档相似度:选择一个目标文档,并计算该文档与其他文档的相似度。
7、输出与目标文档最相似的文档:打印目标文档的内容,然后按相似度从高到低的顺序,打印最相似的前10篇文档的索引、内容和相似度得分。

程序代码

使用LSA模型和相似度矩阵,对给定的18个docx文档集合进行相似度分析

import os
import docx
from gensim import corpora, models, similarities

#定义 docx_analysis 类(读取指定docx文件中的内容,并分析其中每个句子中包含的单词及其出现频率。)

class docx_analysis:
    def __init__(self, docx_path):
        self.docx_path = docx_path
        self.wds_freq = {
    
    }
        
    def local_record_wds(self, words):
        for wd in words:
            if wd in self.wds_freq:
                self.wds_freq[wd] += 1
            else:
                self.wds_freq[wd] = 1

    def analyze(self):
        doc = docx.Document(self.docx_path)
        for para in doc.paragraphs:
            sentences = para.text.split("。")
            for sent in sentences:
                words = sent.strip().split()
                self.local_record_wds(words)
                
# 读取文档集合
doc_dir = r'C:\Users\l\Desktop\机器学习与深度学习\LSA\lsa'
docs = []
for file in os.listdir(doc_dir):
    if file.endswith('.docx'):
        with open(os.path.join(doc_dir, file), 'rb') as f:
            doc = docx.Document(f)
            text = '\n'.join([para.text for para in doc.paragraphs])
            docs.append(text)

# 预处理文本,去除停用词、进行分词和词干提取等
stoplist = set('for a of the and to in'.split())
texts = [[word for word in doc.lower().split() if word not in stoplist] for doc in docs]

# 创建词典和文档-单词矩阵
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]

# 训练 LSA 模型
lsi = models.LsiModel(corpus, id2word=dictionary, num_topics=10)

# 将文档映射到潜在语义空间中
corpus_lsi = lsi[corpus]

# 创建索引和相似度矩阵
index = similarities.MatrixSimilarity(corpus_lsi)

# 使用相似度矩阵计算文档相似度
doc_id = 0  # 选择第一个docx作为目标文档
sims = index[lsi[corpus[doc_id]]]
sims = sorted(enumerate(sims), key=lambda item: -item[1])


# 输出与目标文档最相似的文档
print(f'选择目标文档为第{doc_id+1}个docx :\n{docs[doc_id]}')
# 对目标文档进行分析和统计词频
target_doc_path = os.path.join(doc_dir, os.listdir(doc_dir)[doc_id])
da = docx_analysis(target_doc_path)
da.analyze()


# 输出目标文档的词频统计结果
print('\n目标文档词频统计结果:')
for word, freq in da.wds_freq.items():
    print(f'词语: {word}, 词频: {freq}')
print('\n相似文档:')
for doc_idx, sim_score in sims[1:11]:  # 最相似的前10篇文档
    print(f'相似文档索引——{doc_idx}: \n{docs[doc_idx]}文档相似度: {sim_score}')

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

基于潜在语义分析(LSA)的优点和缺点。
优点:

  • LSA假设隐藏在词语中的隐含意思 (也就是潜在语义空间的这些语义维)可以更好地刻画文本真实含义。
  • LSA利用潜在的语义结构表示词条和文本,将词条和文本映射到同一个k维的语义空间内,均表示为k个因子的形式,向量的含义发生了很大的变化。它反映的不再是简单的词条出现频率和分布关系,而是强化的语义关系。在保持了原始的大部分信息的同时,克服了传统向量空间表示方法时产生的多义词、同义词和单词依赖的现象。

缺点:

  • LSA不是概率模型,缺乏严谨的数理统计基础。
  • LSA解决部分一词多义和一义多词问题,也可以用于降维,但LSA不是概率模型,缺乏严谨的数理统计基础。建议考虑隐含狄利克雷分布(Latent Dirichlet allocation,简称LDA),一种主题模型,它可以将文档集中每篇文档的主题按照概率分布的形式给出。

猜你喜欢

转载自blog.csdn.net/Myx74270512/article/details/131284058