企业社会责任报告CSRR——文本相似性计算

一、相关概念

相似性是指两个文本之间内容的相似程度。

现有关于文本相似性度量的研究,主要采用以下方法:词频-逆文档频率(Term Frequency–Inverse Document Frequency,TF-IDF)、潜在狄利克雷分布(Latent Dirichlet Allocation,LDA)主题模型、Word2vec词向量模型。

TF-IDF是一种用以评估词对文档集或语料库中文件重要程度的统计方法。

LDA是一种描述文档-主题-词之间关系的概率生成模型,能够在一定程度上捕捉文档的语义信息。

Word2vec词向量模型是根据上下文语义信息,将词表示成多维向量的神经网络语义模型。它通过词嵌入方式训练得到稠密词向量,不仅可定量地研究文本之间的关系、捕获文本语义层面的信息,还能够考虑词对整个文本的影响。

二、研究设计

        尽管TF-IDF和LDA在文本相似性计算中有广泛应用,但它们仍存在以下不足:词语顺序与上下文信息的忽略、缺乏深层次语义理解、无法处理同义词与多义词、对长文本的效果较差、对噪音词的敏感性等。因此,在实际应用中,通常需结合其它方面来弥补这些不足,以提高文本相似性计算的准确性和鲁棒性。

        基于上述分析,笔者采用“TF-IDF + Word2vec词向量模型”思路,来更准确地计算文本相似性。基本步骤如下:1)对文本进行分词处理,并对分词结果中的停用词、标点符号、图片表格进行剔除;2)计算文本中已分好的词的TF-IDF值;3)基于财经文本语料库,训练Word2vec词向量模型;4)从训练好的Word2vec模型中获取每个词的词向量,并进行TF-IDF加权处理,得到单个文本的向量;5)通过余弦函数,计算两个文本之间的相似性。其中,相似性的数值越大,表明两个文本之间内容的相似程度越高;反之亦然。

三、案例分析

        由于笔者的研究方向处于经管领域,故以自身所使用的数据进行案例阐述。下文以计算企业社会责任报告之间的相似性进行分析:

1、导入第三方库

import jieba
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from gensim.models import Word2Vec

需说明的是,计算两个向量的相似性,有许多数学公式,如曼哈顿距离、欧式距离、皮尔逊相关系数等。然而,笔者使用的是被广泛应用的余弦函数。

2、加载文本数据

# 加载数据
texts_path = [r"C:\Users\22892\Desktop\草稿\000001_平安银行_2012年度社会责任报告.txt",
              r"C:\Users\22892\Desktop\草稿\000001_平安银行_2013年度社会责任报告.txt",
              ]
texts_list = []

for i in range(len(texts_path)):
    with open(texts_path[i], mode='r', encoding='utf-8') as file:
        text = file.read()
        texts_list.append(text)

3、分词并删除停用词、标点符号、图片表格

# 分词
words_1 = jieba.lcut(texts_list[0])
words_2 = jieba.lcut(texts_list[1])

# 删除停用词
stop_words = open(r"C:\Users\22892\Desktop\停用词.txt", mode='r', encoding='utf-8')
stop_words_list = stop_words.read().splitlines()

clean_words_1 = [word for word in words_1 if word not in stop_words_list and word.strip() and word.isalnum()]
clean_words_2 = [word for word in words_2 if word not in stop_words_list and word.strip() and word.isalnum()]

其中,word.strip() 表示删除空白字符,并过滤掉空元素和空行;word.isalnum() 表示仅保留词、字母、数字。

4、计算每个文本的TF-IDF值

# 计算TF-IDF值
documents = [' '.join(clean_words_1), ' '.join(clean_words_2)]
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(documents)
features = vectorizer.get_feature_names_out()

注意,documents 列表是二维的,第一维表示每个文本,第二维表示文本分好的词。

5、训练Word2vec词向量模型,并对词向量进行加权处理

# 训练Word2vec模型
model = Word2Vec(sentences=[clean_words_1, clean_words_2], vector_size=100, window=5, min_count=1, workers=4)

# 定义函数,通过对词向量进行TF-IDF加权,获得文档向量
def get_weighted_doc_vector(words, model, tfidf_vector):
    doc_vector = np.zeros((model.vector_size, ))   # 一维向量,100维
    for word in words:
        if word in model.wv:
            word_index = vectorizer.vocabulary_.get(word)
            if word_index is not None:
                doc_vector += model.wv[word] * tfidf_vector[word_index]

    return doc_vector

# 获取每个文档的TF-IDF向量
tfidf_1 = tfidf_matrix.toarray()[0]
tfidf_2 = tfidf_matrix.toarray()[1]

# 通过对词向量进行TF-IDF加权来获取文档向量
doc_vector_1 = get_weighted_doc_vector(words=clean_words_1, model=model, tfidf_vector=tfidf_1)
doc_vector_2 = get_weighted_doc_vector(words=clean_words_2, model=model, tfidf_vector=tfidf_2)

这里Word2vec模型的输入可换成自己的特定类型的语料库进行训练。

6、根据余弦函数计算文本相似性

# 计算两个文档向量之间的余弦相似度
cosine_sim = cosine_similarity(X=[doc_vector_1], Y=[doc_vector_2])[0][0]

注意,cosine_similarity() 的输入X、Y都必须是二维数据,否则程序会报错!最后,得到上述两个文本之间的相似度为0.9931。

7、整个代码

import jieba
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from gensim.models import Word2Vec


# 加载数据
texts_path = [r"C:\Users\22892\Desktop\草稿\000001_平安银行_2012年度社会责任报告.txt",
              r"C:\Users\22892\Desktop\草稿\000001_平安银行_2013年度社会责任报告.txt"]
texts_list = []

for i in range(len(texts_path)):
    with open(texts_path[i], mode='r', encoding='utf-8') as file:
        text = file.read()
        texts_list.append(text)

# 分词
words_1 = jieba.lcut(texts_list[0])
words_2 = jieba.lcut(texts_list[1])

# 删除停用词
stop_words = open(r"C:\Users\22892\Desktop\停用词.txt", mode='r', encoding='utf-8')
stop_words_list = stop_words.read().splitlines()

clean_words_1 = [word for word in words_1 if word not in stop_words_list and word.strip() and word.isalnum()]
clean_words_2 = [word for word in words_2 if word not in stop_words_list and word.strip() and word.isalnum()]

# 计算TF-IDF值
documents = [' '.join(clean_words_1), ' '.join(clean_words_2)]
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(documents)
features = vectorizer.get_feature_names_out()

# 训练Word2vec模型
model = Word2Vec(sentences=[clean_words_1, clean_words_2], vector_size=100, window=5, min_count=1, workers=4)

# 定义函数,通过对词向量进行TF-IDF加权,获得文档向量
def get_weighted_doc_vector(words, model, tfidf_vector):
    doc_vector = np.zeros((model.vector_size, ))   # 一维向量,100维
    for word in words:
        if word in model.wv:
            word_index = vectorizer.vocabulary_.get(word)
            if word_index is not None:
                doc_vector += model.wv[word] * tfidf_vector[word_index]

    return doc_vector

# 获取每个文档的TF-IDF向量
tfidf_1 = tfidf_matrix.toarray()[0]
tfidf_2 = tfidf_matrix.toarray()[1]

# 通过对词向量进行TF-IDF加权来获取文档向量
doc_vector_1 = get_weighted_doc_vector(words=clean_words_1, model=model, tfidf_vector=tfidf_1)
doc_vector_2 = get_weighted_doc_vector(words=clean_words_2, model=model, tfidf_vector=tfidf_2)

# 计算两个文档向量之间的余弦相似度
cosine_sim = cosine_similarity(X=[doc_vector_1], Y=[doc_vector_2])[0][0]
print(cosine_sim)



  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值