【NLP】使用Word Embedding实现中文自动摘要

news2024/11/27 6:21:52

使用Word Embedding实现中文自动摘要

  • 主要步骤
  • 中文语料库
    • 数据预处理
    • 生成词向量
    • 把文档的词转换为词向量
    • 生成各主题的关键词
    • 检查运行结果
  • 参考资料

本文通过一个实例介绍如何使用Word Embedding实现中文自动摘要,使用 Gensim中的word2vec模型来生成Word Embedding。

主要步骤

1)导入一个中文语料库
2)基于这个中文语料库,搭建word2vec模型,训练得到各单词的词向量;
3)导入一个文档,包括各主题及其概要描述信息,预处理该文档,并转换为词向量;
4)用聚类的方法,生成各主题的若干个关键词。

中文语料库

本文采用的是搜狗实验室的搜狗新闻语料库,数据链接https://github.com/garfieldkai/word2vec/blob/master/data/corpus.txt
下载下来的文件名为: news_sohusite_xml.smarty.tar.gz

数据预处理

1)解压并查看原始数据
cd 到原始文件目录下,执行解压命令:

tar -zvxf news_sohusite_xml.smarty.tar.gz

得到文件news_sohusite_xml.dat, 用vim打开该文件,

vim news_sohusite_xml.smarty.dat

得到如下结果:
数据内容
2)取出内容
取出<content> </content> 中的内容,执行如下命令:

cat news_sohusite_xml.smarty.dat | iconv -f gbk -t utf-8 -c | grep "<content>"  > corpus.txt 

windows下可以使用

type news_sohusite_xml.smarty.dat | iconv -f gbk -t utf-8 -c | findstr "<content>"  > corpus.txt 

得到文件名为corpus.txt的文件,可以通过vim 打开

vim corpus.txt

得到如下效果:
corpus
3)分词
利用jieba分词,过滤停用词等,代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/7/8 11:39
# @Author  : Alvaro Pang
# @File    : cutWord.py
# @Software: PyCharm

import jieba
import numpy as np

filePath = 'corpus.txt'
fileSeqWordDonePath = 'corpusSeqDone_1.txt'


# 打印中文列表
def PrintListChinese(list):
    for i in range(len(list)):
        print(list[i])


# 打印文件内容到列表
fileTrainRead = []
with open(filePath, 'r', encoding='utf-8') as fileTrainRaw:
    for line in fileTrainRaw:  # 按行读取文件
        fileTrainRead.append(line)

# jieba分词后保存在列表中
fileTrainSeq = []
for i in range(len(fileTrainRead)):
    fileTrainSeq.append([' '.join(list(jieba.cut(fileTrainRead[i][9:-11], cut_all=False)))])
    if i % 10000 == 0:
        print(i)

# 保存分词结果到文件中
with open(fileSeqWordDonePath, 'w', encoding='utf-8') as fW:
    for i in range(len(fileTrainSeq)):
        fW.write(fileTrainSeq[i][0])
        fW.write('\n')

可以得到文件名为 corpusSegDone_1.txt 的文件,需要注意的是,对于读入文件的每一行,使用结巴分词的时候并不是从0到结尾的全部都进行分词,而是对[9:-11]分词 (如行22中所示: fileTrainRead[i][9:-11] ),这样可以去掉每行(一篇新闻稿)起始的 和结尾的。得到如下图所示的结果:
分词结果

生成词向量

使用Gensim word2vec库生成词向量,代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/7/10 1:07
# @Author  : Alvaro Pang
# @File    : wordvectors.py
# @Software: PyCharm

import warnings
import logging
import os.path
import sys
import multiprocessing

import gensim
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence

# 忽略警告
warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')

if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])  # 读取当前文件的文件名
    logger = logging.getLogger(program)
    logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s', level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))

    # inp为输入语料,outp1为输出模型,outp2为vector格式的模型
    inp = './corpusSeqDone_1.txt'
    out_model = './corpusSeqDone_1.model'
    out_vector = './corpusSeqDone_1.vector'

    # 训练skip-gram模型
    model = Word2Vec(LineSentence(inp), vector_size=50, window=5, min_count=5, workers=multiprocessing.cpu_count())

    # 保存模型
    model.save(out_model)
    # 保存词向量
    model.wv.save_word2vec_format(out_vector, binary=False)

把文档的词转换为词向量

对数据进行预处理,并用Skip-gram模型将其转换为词向量:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/7/13 21:10
# @Author  : Alvaro Pang
# @File    : textvectors.py
# @Software: PyCharm
# 采用word2vec词聚类方法抽取关键词1——获取文本词向量表示
import sys, codecs
import pandas as pd
import numpy as np
import jieba
import jieba.posseg
import gensim
import warnings

warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')  # 忽略警告


# 返回特征词向量
def getWordVec(wordList, model):
    name, vecs = [], []
    for word in wordList:
        word = word.replace('\n', '')
        try:
            if word in model:  # 模型中存在该词的向量表示
                name.append(word)
                vecs.append(model[word])
        except KeyError:
            continue
    a = pd.DataFrame(name, columns=['word'])
    b = pd.DataFrame(np.array(vecs, dtype='float'))
    return pd.concat([a, b], axis=1)


# 数据预处理操作:分词、去停用词、词性筛选
def dataPrepos(text, stopkey):
    l = []
    pos = ['n', 'nz', 'v', 'vd', 'vn', 'l', 'a', 'd']  # 定义选取的词性
    seq = jieba.posseg.cut(text)  # 分词
    for i in seq:
        if i.word not in l and i.word not in stopkey and i.flag in pos:  # 去重+去停用词+词性筛选
            l.append(i.word)
    return l


# 根据数据获取候选关键词词向量
def buildAllWordsVecs(data, stopkey, model):
    idList, titleList, abstractList = data['id'], data['title'], data['abstract']
    for index in range(len(idList)):
        id = idList[index]
        title = titleList[index]
        abstract = abstractList[index]
        l_ti = dataPrepos(title, stopkey)  # 处理标题
        l_ab = dataPrepos(abstract, stopkey)  # 处理摘要
        # 获取候选关键词的词向量
        words = np.append(l_ti, l_ab)  # 拼接数组元素
        words = list(set(words))  # 数组元素去重,得到候选关键词列表
        wordvecs = getWordVec(words, model)  # 获取候选关键词的词向量表示
        # 词向量写入csv文件,每个词400维
        data_vecs = pd.DataFrame(wordvecs)
        data_vecs.to_csv('./vecs/wordvecs_' + str(id) + '.csv', index=False)
        print("document ", id, " well done.")


def main():
    # 读取数据
    dataFile = './sample_data.csv'
    data = pd.read_csv(dataFile)
    # 停用词表
    stopkey = [w.strip() for w in codecs.open('stopWord.txt', 'r', encoding='utf-8').readlines()]
    # 词向量模型
    inp = 'corpusSeqDone_1.vector'
    model = gensim.models.KeyedVectors.load_word2vec_format(inp, binary=False)
    buildAllWordsVecs(data, stopkey, model)


if __name__ == '__main__':
    main()

生成各主题的关键词

采用聚类方法对候选关键词的词向量进行聚类分析。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/7/14 23:08
# @Author  : Alvaro Pang
# @File    : clustertopics.py
# @Software: PyCharm
# 采用word2vec词聚类方法抽取关键词2——根据候选关键词的词向量进行聚类分析
import sys, os
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import math

# 对词向量采用K-mean聚类抽取topK关键词
topK = 6
os.environ["OMP_NUM_THREADS"] = '1'


def getkeywords_kmeans(data, topK):
    words = data['word']  # 词汇
    vecs = data.iloc[:, 1:]  # 向量表示
    kmeans = KMeans(n_clusters=1, random_state=10).fit(vecs)
    labels = kmeans.labels_  # 类别结果标签
    labels = pd.DataFrame(labels, columns=['label'])
    new_df = pd.concat([labels, vecs], axis=1)
    df_count_type = new_df.groupby('label').size()  # 各类别统计个数
    print(df_count_type)
    vec_center = kmeans.cluster_centers_  # 聚类中心

    # 计算距离(相似性)采用欧式距离
    distances = []
    vec_words = np.array(vecs)  # 候选关键词向量,dataFrame转array
    vec_center = vec_center[0]  # 第一个类别聚类中心,本例只有一个类别
    length = len(vec_center)  # 向量维度
    for index in range(len(vec_words)):  # 候选关键词个数
        cur_wordvec = vec_words[index]  # 当前词语的词向量
        dis = 0  # 向量距离
        for index2 in range(length):
            dis += (vec_center[index2] - cur_wordvec[index2]) * (vec_center[index2] - cur_wordvec[index2])
        dis = math.sqrt(dis)
        distances.append(dis)
    distances = pd.DataFrame(distances, columns=['dis'])

    result = pd.concat([words, labels, distances], axis=1)  # 拼接词语与其对应中心的距离
    result = result.sort_values(by="dis", ascending=True)  # 按照距离大小进行升序排列

    # 将用于聚类的数据的特征维度将到2维
    pca = PCA(n_components=2)
    new_pca = pd.DataFrame(pca.fit_transform(new_df))

    # 可视化
    d = new_pca[new_df['label'] == 0]
    plt.plot(d[0], d[1], 'r.')
    d = new_pca[new_df['label'] == 1]
    plt.plot(d[0], d[1], 'go')
    d = new_pca[new_df['label'] == 2]
    plt.plot(d[0], d[1], 'b*')
    plt.gcf().savefig('kmeans.png')
    plt.show()

    # 抽取排名前topk个词语作为文本关键词
    wordlist = np.array(result['word'])  # 选择词汇列并转换成数组格式
    word_split = [wordlist[x] for x in range(0, topK)]  # 抽取前topK个词汇
    word_split = " ".join(word_split)
    return word_split


def main():
    # 读取数据集
    dataFile = 'sample_data.csv'
    articleData = pd.read_csv(dataFile)
    ids, titles, keys = [], [], []

    rootdir = "vecs"  # 词向量文件根目录
    fileList = os.listdir(rootdir)  # 列出文件夹下所有的目录与文件
    # 遍历文件
    for i in range(len(fileList)):
        filename = fileList[i]
        path = os.path.join(rootdir, filename)
        if os.path.isfile(path):
            data = pd.read_csv(path)  # 读取词向量文件数据
            article_keys = getkeywords_kmeans(data, topK)  # 聚类算法得到当前文件的关键词
            print(article_keys)
            article_keys = article_keys
            # 根据文件名获得文章id以及标题
            (shortname, extension) = os.path.splitext(filename)  # 得到文件名和文件扩展名
            t = shortname.split('_')
            article_id = int(t[len(t) - 1])  # 获得文章id
            article_tit = articleData[articleData.id == article_id]['title']  # 获得文章标题
            article_tit = list(article_tit)[0]  # series转成字符串
            ids.append(article_id)
            titles.append(article_tit)
            keys.append(article_keys)
    # 将所有结果写入文件
    result = pd.DataFrame({"id": ids, "title": titles, "key": keys}, columns=["id", "title", "key"])
    result = result.sort_values(by='id', ascending=True)
    result.to_csv('keys_word2vec.csv', index=False)


if __name__ == '__main__':
    main()

检查运行结果

查看生成的各个主题的关键词,如下:
关键词

参考资料

  1. 《深入浅出Embedding——原理解析与应用实践》 吴茂贵 王红星 著
  2. 搜狗语料库word2vec获取词向量
  3. 用Word2Vec训练中文词向量(一)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/759889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

揭秘乳腺癌预测黑科技:R语言和支持向量机的奇妙之旅!

一、引言 乳腺癌被认为是全球范围内最常见的癌症之一&#xff0c;对女性健康造成了重大威胁[1]。根据世界卫生组织的统计数据&#xff0c;乳腺癌是女性恶性肿瘤中的主要类型&#xff0c;并且是导致女性死亡的第二大原因[2]。这个事实凸显了乳腺癌在全球范围内的流行程度以及对公…

数据库架构演变过程

&#x1f680; ShardingSphere &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&…

ES系列--分析器

一、前言 ES进行文档分析就会涉及到分析器&#xff0c;无论是内置的分析器&#xff0c;还是自定义的分析器&#xff0c;都是由一个分词器&#xff08;tokenizers&#xff09; 、0或多个词项过滤器&#xff08;token filters&#xff09;、0或多个字符过滤器&#xff08;charact…

随机数检测(四)

随机数检测&#xff08;四&#xff09;- 累加和检测、近似熵检测、线性复杂度检测、Maurer通用统计检测、离散傅里叶检测 3.12 累加和检测方法3.13 近似熵检测方法3.14 线性复杂度检测3.15 Maurer通用统计检测3.16 离散傅里叶检测方法 如果商用密码产品认证中遇到问题&#xff…

Python应用实例(二)数据可视化(四)

数据可视化&#xff08;四&#xff09;下载数据 1.CSV文件格式1.1 分析CSV文件头‘1.2 打印文件头及其位置1.3 提取并读取数据1.4 绘制温度图表1.5 在图表中添加日期 从网上下载数据&#xff0c;并对其进行可视化。网上的数据多得令人难以置信&#xff0c;大多未经仔细检查。如…

智能车打开usb相机和激光雷达录制数据包的过程记录

首先&#xff0c;智能车的遥控器启动之后&#xff0c;要解除驻车挡位&#xff08;尾灯不亮红色才可以&#xff09;&#xff0c;然后右上角的那个拨杆是喇叭&#xff0c;对应的左上角的那个拨杆是控制挡位的&#xff0c;包括前进档&#xff0c;后退档。假如是前进&#xff0c;往…

【我们一起60天准备考研算法面试(大全)-第十五天 15/60】【摩尔投票法】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

CSAPP Lab入门探索

此为记录 虚拟机准备工作 下载VMware 直接在浏览器中搜索VMware Workstation即可 等待 安装就是直接下一步下一步即可&#xff0c;那个安装路径也改下&#xff0c;默认是装在系统盘中 许可证: 直接在百度中搜索VMware Workstation 17 Pro密钥大全即可 这里给出一个参考的&…

人体姿态估计动作识别调研报告

人体姿态估计&动作识别 视频演示 Refs: https://www.zhihu.com/zvideo/1227562268420235264 姿态估计与行为识别&#xff08;行为检测、行为分类&#xff09;的区别 Refs&#xff1a;姿态估计与行为识别&#xff08;行为检测、行为分类&#xff09;的区别 姿态估计 定…

两分钟倒计时 - 啊哈C语言 第4章第5节

题目要求&#xff1a; 尝试编写一个两分钟的倒计时&#xff0c;形如&#xff1a;2:00 1:59 1:58 … 1:00 0:59 0:58 … 0:02 0:01 0:00 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #include<windows.h> int main(){int a2,b0;while(a>0 &…

SpringMVC的XML配置解析-spring18

SpringMVC的有很多组件&#xff1a;&#xff08;这些我们都可以用配件进行配置&#xff09; 1、充沛器 2、映射器 3、视图解析器 默认情况下他们要使用哪个组件&#xff0c;我们可以挖一下&#xff1a; 第一个重叠器映射器 第二个 重叠器适配器 第三个 视图适配器 打开看…

Vue生命周期详解学习笔记

生命周期 生命周期又名生命周期回调函数&#xff0c;生命周期函数&#xff0c;生命周期钩子。生命周期是Vue在关键时刻帮我们调用的一些特殊名称的函数。生命周期函数的名字不可更改&#xff0c;但函数的具体内容是程序员根据需求编写的。生命周期中的this指向vm或组件实例对象…

【PHP面试题48】Redis的事务?事务都有哪些注意的地方?

文章目录 一、关于事务1.1 事务的概念和优势1.2 Redis事务的基本用法 二、Redis事务的注意事项2.1 使用WATCH监视关键变量2.2 避免长时间事务2.3 避免事务中的循环2.4 处理事务执行结果2.5 考虑使用管道2.6 使用合适的事务隔离级别2.7 考虑事务的并发性2.8 监控事务执行情况 总…

项目管理进度管理神器:有效方法分享

在项目管理中&#xff0c;进度管理是至关重要的环节&#xff0c;它可以帮助项目团队及时发现和解决问题&#xff0c;确保项目按计划顺利进行。一个有效的进度管理方案需要考虑多方面的因素&#xff0c;包括任务分解、时间控制、资源分配、风险管理等。 如何有效的管理项目进度&…

剑指 Offer 68 - II. 二叉树的最近公共祖先

题目介绍 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以…

FL Studio2023最新中文版混音编曲宿主软件及电脑配置要求

现在大部分音乐的制作过程都是在宿主软件中完成的&#xff0c;宿主软件又称数字音频工作站&#xff0c;简写为DAW软件。目前市面上有非常多的宿主软件供大家选择&#xff0c;例如Cubase、Logic Pro以及我一直使用的FL Studio。每款不同的宿主软件都有不同的优缺点&#xff0c;所…

MFC第十七天 CFont类与LOGFONT结构体、记事本文件打开和保存及是否保存的逻辑流程分析、PreTranslateMessage虚函数与快捷键

文章目录 CFont类与LOGFONT结构体CFontDialog字体信息结构体与HFONT句柄的关系 记事本文件拖入、打开和保存及是否保存的逻辑流程分析PreTranslateMessage虚函数与快捷键附录 CFont类与LOGFONT结构体 CFontDialog 构造函数介绍 public: //用于指定字体对话框的初始字体属性&…

C# Modbus通信从入门到精通(4)——Modbus RTU(0x02功能码)

1、02(0x02)读线圈输入 使用该功能码能从远程地址中读取1到2000个输入线圈的状态,每个线圈的状态只能是0或者1,读取的线圈数量由主站读取时指定。 2、发送报文格式 更详细的格式如下: 从站地址+功能码+起始地址高位+起始地址低位+线圈数量高位+线圈数量低位+CRC,一共8个…

Linux进程理解【程序地址空间】

Linux进程理解【程序地址空间】 文章目录 Linux进程理解【程序地址空间】1. 话题引入2. 进程地址空间2.1 虚拟地址2.2 写时拷贝 3. 知识扩展 我们先来看看C/C程序地址空间的分布图 如此多区域的划分是为了更好的使用和管理空间&#xff0c;但是真实的内存空间也是按照图上的地址…

nginx的下载与安装

https://nginx.org/en/download.html 下载地址&#xff08;我下载的是1.20.2&#xff09; 1、首先保证可以连接外网 2、将包拖入opt/nginx 3、安装gcc环境 &#xff08;如果出现问题可以参考https://www.cnblogs.com/lzxianren/p/4254059.html&#xff09; yum -y install gc…