基于Word2vec加TextRank算法生成中文新闻摘要(附python代码)

24 篇文章 0 订阅
3 篇文章 0 订阅

转自

# https://blog.csdn.net/qq_36910634/article/details/97764251
import numpy as np
import pandas as pd
import re, os, jieba
from itertools import chain


# 本文要处理的新闻一共3篇,都是关于证监会主席易会满同志新官上任的报道,新闻的大致内容是易会满
# 同志怎么对中国资本市场的改革指点江山。
#
# 文档的原网页(看到百家号,不要鄙视我):
#
# https://baijiahao.baidu.com/s?id=1626615436040775944&wfr=spider&for=pc
# https://baijiahao.baidu.com/s?id=1626670136476331971&wfr=spider&for=pc
# http://finance.sina.com.cn/roll/2019-02-28/doc-ihrfqzka9798377.shtml

"""第一步:把文档划分成句子"""

# 文档所在的文件夹
c_root = os.getcwd() + os.sep + "cnews" + os.sep

sentences_list = []
for file in os.listdir(c_root):
    fp = open(c_root + file, 'r', encoding="utf8")
    for line in fp.readlines():
        if line.strip():
            # 把元素按照[。!;?]进行分隔,得到句子。
            line_split = re.split(r'[。!;?]', line.strip())
            # [。!;?]这些符号也会划分出来,把它们去掉。
            line_split = [line.strip() for line in line_split if
                          line.strip() not in ['。', '!', '?', ';'] and len(line.strip()) > 1]
            sentences_list.append(line_split)
sentences_list = list(chain.from_iterable(sentences_list))
print("前10个句子为:\n")
print(sentences_list[:10])

"""第二步:文本预处理,去除停用词和非汉字字符,并进行分词"""

# 创建停用词列表
stopwords = [line.strip() for line in open('./stopwords.txt', encoding='UTF-8').readlines()]


# 对句子进行分词
def seg_depart(sentence):
    # 去掉非汉字字符
    sentence = re.sub(r'[^\u4e00-\u9fa5]+', '', sentence)
    sentence_depart = jieba.cut(sentence.strip())
    word_list = []
    for word in sentence_depart:
        if word not in stopwords:
            word_list.append(word)
            # 如果句子整个被过滤掉了,如:'02-2717:56'被过滤,那就返回[],保持句子的数量不变
    return word_list


sentence_word_list = []
for sentence in sentences_list:
    line_seg = seg_depart(sentence)
    sentence_word_list.append(line_seg)
print("一共有", len(sentences_list), '个句子。\n')
print("前10个句子分词后的结果为:\n", sentence_word_list[:10])

# 保证处理后句子的数量不变,我们后面才好根据textrank值取出未处理之前的句子作为摘要。
if len(sentences_list) == len(sentence_word_list):
    print("\n数据预处理后句子的数量不变!")

"""第三步:准备词向量"""

word_embeddings = {}
# f = open('./sgns.financial.char', encoding='utf-8')
f = open('sgns.financial.word', encoding='utf-8')
for line in f:
    # 把第一行的内容去掉
    if '467389 300\n' not in line:
        values = line.split()
        # 第一个元素是词语
        word = values[0]
        embedding = np.asarray(values[1:], dtype='float32')
        word_embeddings[word] = embedding
f.close()
print("一共有" + str(len(word_embeddings)) + "个词语/字。")

"""第四步:得到词语的embedding,用WordAVG作为句子的向量表示"""

sentence_vectors = []
for i in sentence_word_list:
    if len(i) != 0:
        # 如果句子中的词语不在字典中,那就把embedding设为300维元素为0的向量。
        # 得到句子中全部词的词向量后,求平均值,得到句子的向量表示
        v = sum([word_embeddings.get(w, np.zeros((300,))) for w in i]) / (len(i))
    else:
        # 如果句子为[],那么就向量表示为300维元素为0个向量。
        v = np.zeros((300,))
    sentence_vectors.append(v)

"""第五步:计算句子之间的余弦相似度,构成相似度矩阵"""
sim_mat = np.zeros([len(sentences_list), len(sentences_list)])

from sklearn.metrics.pairwise import cosine_similarity

for i in range(len(sentences_list)):
    for j in range(len(sentences_list)):
        if i != j:
            sim_mat[i][j] = cosine_similarity(sentence_vectors[i].reshape(1, 300), sentence_vectors[j].reshape(1, 300))[
                0, 0]
print("句子相似度矩阵的形状为:", sim_mat.shape)

"""第六步:迭代得到句子的textrank值,排序并取出摘要"""
import networkx as nx

# 利用句子相似度矩阵构建图结构,句子为节点,句子相似度为转移概率
nx_graph = nx.from_numpy_array(sim_mat)

# 得到所有句子的textrank值
scores = nx.pagerank(nx_graph)

# 根据textrank值对未处理的句子进行排序
ranked_sentences = sorted(((scores[i], s) for i, s in enumerate(sentences_list)), reverse=True)

# 取出得分最高的前10个句子作为摘要
sn = 10
for i in range(sn):
    print("第" + str(i + 1) + "条摘要:\n\n", ranked_sentences[i][1], '\n')
以下是基于Word2Vec的消歧算法Python代码: ```python import gensim # 载预训练好的Word2Vec模型 model = gensim.models.KeyedVectors.load_word2vec_format('path/to/word2vec/model.bin', binary=True) def disambiguate(word, context): """ 通过Word2Vec模型消歧单词 :param word: 待消歧的单词 :param context: 上下文信息,可以是一个字符串或列表 :return: 消歧后的单词 """ # 获取候选词列表 candidates = get_candidates(word, context) # 计算每个候选词与上下文的相似度 similarity_scores = [(candidate, get_similarity_score(word, candidate, context)) for candidate in candidates] # 按照相似度从高到低排序 similarity_scores.sort(key=lambda x: x[1], reverse=True) # 返回相似度最高的候选词 return similarity_scores[0][0] def get_candidates(word, context): """ 获取候选词列表 :param word: 待消歧的单词 :param context: 上下文信息,可以是一个字符串或列表 :return: 候选词列表 """ # 从Word2Vec模型获取与待消歧单词相似的单词 similar_words = model.similar_by_word(word) # 选择与上下文相关的单词作为候选词 candidates = [similar_word[0] for similar_word in similar_words if similar_word[0] in context] # 如果候选词列表为空,则将相似度最高的单词作为候选词 if not candidates: candidates.append(similar_words[0][0]) return candidates def get_similarity_score(word, candidate, context): """ 计算单词与上下文的相似度 :param word: 待消歧的单词 :param candidate: 候选词 :param context: 上下文信息,可以是一个字符串或列表 :return: 相似度得分 """ # 计算单词与候选词的余弦相似度 similarity_score = model.similarity(word, candidate) # 如果上下文信息是一个字符串,则将其转换为列表 if isinstance(context, str): context = context.split() # 计算候选词与上下文所有单词的平均相似度 context_similarity_scores = [model.similarity(candidate, context_word) for context_word in context] avg_context_similarity_score = sum(context_similarity_scores) / len(context_similarity_scores) # 将单词与候选词的相似度得分与候选词与上下文的平均相似度得分相作为最终得分 final_score = similarity_score + avg_context_similarity_score return final_score ``` 以上代码实现了一个基于Word2Vec的消歧算法,包括以下几个函数: - `disambiguate(word, context)`:消歧函数,接受待消歧的单词和上下文信息作为参数,返回消歧后的单词。 - `get_candidates(word, context)`:获取候选词列表的函数,接受待消歧的单词和上下文信息作为参数,返回候选词列表。 - `get_similarity_score(word, candidate, context)`:计算单词与上下文的相似度得分的函数,接受待消歧的单词、候选词和上下文信息作为参数,返回相似度得分。 其,`disambiguate(word, context)`函数是最主要的函数,它首先调用`get_candidates(word, context)`函数获取候选词列表,然后遍历候选词列表,调用`get_similarity_score(word, candidate, context)`函数计算每个候选词与上下文的相似度得分,最后返回相似度得分最高的候选词作为消歧结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值