词向量技术原理及应用详解(五)——关键词提取

利用word2vec提取关键词:

说到提取关键词,一般会想到TF-IDF和TextRank,大家是否想过,Word2Vec还可以用来提取关键词?而且,用Word2Vec提取关键词,已经初步含有了语义上的理解,而不仅仅是简单的统计了,而且还是无监督的!

很显然,我们希望通过提取的关键词能够尽可能快地获取文章的大意也就是说,我们可以由关键词来猜到文本的大意,用数学来表示,那就是条件概率$$p(s|w_i)$$
            这里的$s$代表着一段文本,$w_i$是文本中的某个词,如果$w_i$是文本的关键词,那么应该使得上述概率最大。也就是说,我们只需要对句子中所有的词,算一遍上述概率,然后降序排列,就可以提取关键词了。说白了,关键词就是最能让我们猜到原文的词语。怎么估算这个概率?

利用Word2vec可以。为了估算$p(w_k|w_i)$,需要有大量的文本进行统计,好在这个过程是无监督的,统计是件很简单的事情。然而,我们有更好的工具,什么工具最擅长于对$p(w_k|w_i)$的建模呢?读者可能就已经猜到了,显然就是Word2Vec呀!Word2Vec的Skip-Gram模型,就是用来对这个概率进行建模的。

训练词向量的时候必须使用Skip-Gram + Huffman Softmax这个组合,也就是训练参数设置为sg=1,hs=1,才能在提取出关键词。

否则将训练的模型将少一个文件word2vec_cpws.model.trainables.syn1.npy。

具体实践代码如下:

import numpy as np
import gensim
from collections import Counter
import pandas as pd #引入它主要是为了更好的显示效果
import jieba
import re
#加载模型
model = gensim.models.word2vec.Word2Vec.load('model1/word2vec_cpws.model')

def predict_proba(oword, iword):
    iword_vec = model[iword]
    oword = model.wv.vocab[oword]
    oword_l = model.syn1[oword.point].T
    dot = np.dot(iword_vec, oword_l)
    lprob = -sum(np.logaddexp(0, -dot) + oword.code*dot)
    return lprob


def keywords(s):
    s = [w for w in s if w in model]
    ws = {w:sum([predict_proba(u, w) for u in s]) for w in s}
    return Counter(ws).most_common()

#
# jieba.load_userdict("jiebauserdict.txt")
stopword = [line.rstrip() for line in open("data/stop_words.txt", 'r', encoding='utf-8')]
def clean_text(text):
    newtext = []
    # text = re.sub(r'\d+', ' ', text) #去除数字
    text = jieba.cut(text)  # 分词
    for word in text:
        if word not in stopword:  # 去停用词 + 词性筛选
            newtext.append(word)
    lineswords=' '.join(newtext)
    return lineswords

reviews = pd.read_excel("data/cpws.xlsx")
f=open("write2.txt", "w", encoding='utf-8')
#选取有用的列
# reviews['comment'] = reviews['Summary'].astype(str) + reviews['Text'].astype(str)
reviews['comment'] = reviews['jslcm'].astype(str)
# print(reviews['comment'])
# reviews = reviews.drop(['Id'], 1)
# reviews = reviews.reset_index(drop=True)
for i in range(len(reviews)):
    print("keyword #", i + 1)
    content = reviews.jslcm[i]
    # print(reviews.jslcm[i])
    result = pd.Series(keywords(jieba.cut(content)))
    # result = pd.Series(keywords(clean_text(content)))
    results = result[:10]
    # print(results)
    for word in results:
        f.write(word[0] + ' ')
    f.write('\n')
    f.flush()
f.close()



提取的结果不是很好,数据没有经过预处理。当然单靠这种方法提取关键词是不可能有较好的结果的,需要将多种关键词提取算法进行结合,取各之所长。

参考:

https://www.spaces.ac.cn/archives/4316

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Steven灬

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

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

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

打赏作者

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

抵扣说明:

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

余额充值