NLP实战之关键词提取与主题模型

365365bet体育在 2025-10-04 23:09:02 admin 阅读 6131
NLP实战之关键词提取与主题模型

中文自然语言处理分析

和拉丁语系不同,亚洲语言是不用空格分开每个有意义的词的。而当我们进行自然语言处理的时候,大部分情况下,词汇是我们对句子和文章理解的基础,因此需要一个额外的分词工具去把完整的文本中分解成粒度更细的词。

1.1 关键词提取

1.1.1 基于 TF-IDF 算法的关键词抽取

import jieba.analyse

jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())

sentence 为待提取的文本,无需分词topK 为返回几个 TF/IDF 权重最大的关键词,默认值为 20withWeight 为是否一并返回关键词权重值,默认值为 FalseallowPOS 仅包括指定词性的词,默认值为空,即不筛选

以科技新闻为例:

import jieba.analyse as analyse

import pandas as pd

df = pd.read_csv("/jhub/students/data/course11/项目2/origin_data/technology_news.csv", encoding='utf-8')

df = df.dropna()

lines=df.content.values.tolist()

content = "".join(lines)

keywords = analyse.extract_tags(content, topK=30, withWeight=False, allowPOS=())

print(keywords)

1.1.2 基于 TextRank 算法的关键词抽取

jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=(‘ns’, ‘n’, ‘vn’, ‘v’)) 直接使用,接口相同,注意默认过滤词性。jieba.analyse.TextRank() 新建自定义 TextRank 实例

算法论文: TextRank: Bringing Order into Texts

基本思想:

将待抽取关键词的文本进行分词以固定窗口大小(默认为5,通过span属性调整),词之间的共现关系,构建图计算图中节点的PageRank,注意是无向带权图

用TextRank提取来提取关键词,用PageRank的思想来解释它:

如果一个单词出现在很多单词后面的话,那么说明这个单词比较重要一个TextRank值很高的单词后面跟着的一个单词,那么这个单词的TextRank值会相应地因此而提高

import jieba.analyse as analyse

import pandas as pd

df = pd.read_csv("/jhub/students/data/course11/项目2/origin_data/military_news.csv", encoding='utf-8')

df = df.dropna()

lines=df.content.values.tolist()

content = "".join(lines)

print(" ".join(analyse.textrank(content, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')))) # ("ns", "n", "vn", "v"))表示词性为地名、名词、动名词、动词

print("---------------------我是分割线----------------")

print(" ".join(analyse.textrank(content, topK=20, withWeight=False, allowPOS=('ns', 'n'))))

由实验结果,可以发现:

TextRank与TFIDF均严重依赖于分词结果——如果某词在分词时被切分成了两个词,那么在做关键词提取时无法将两个词黏合在一起(TextRank有部分黏合效果,但需要这两个词均为关键词)。因此是否添加标注关键词进自定义词典,将会造成准确率、召回率大相径庭。TextRank的效果并不优于TFIDF。TextRank虽然考虑到了词之间的关系,但是仍然倾向于将频繁词作为关键词。

此外,由于TextRank涉及到构建词图及迭代计算,所以提取速度较慢。

1.2 LDA主题模型

首先我们要把文本内容处理成固定的格式,一个包含句子的list,list中每个元素是分词后的词list。类似下面这个样子。

[[第,一,条,新闻,在,这里],[第,二,条,新闻,在,这里],[这,是,在,做, 什么],…]

from gensim import corpora, models, similarities

import gensim

1.2.1 载入停用词

import pandas as pd

stopwords=pd.read_csv("/jhub/students/data/course11/项目2/origin_data/stopwords.txt",index_col=False,quoting=3,sep="\t",names=['stopword'], encoding='utf-8')

stopwords=stopwords['stopword'].values

1.2.2 转换成合适的格式

import jieba

df = pd.read_csv("/jhub/students/data/course11/项目2/origin_data/technology_news.csv", encoding='utf-8')

df = df.dropna()

lines=df.content.values.tolist()

sentences=[]

for line in lines:

try:

segs=jieba.lcut(line)

segs = list(filter(lambda x:len(x)>1, segs))

segs = list(filter(lambda x:x not in stopwords, segs))

sentences.append(list(segs))

except Exception as e:

print(line)

continue

# 处理完格式为[[第,一,条,新闻,在,这里],[第,二,条,新闻,在,这里],[这,是,在,做, 什么],...]

print(sentences[:2])

# 看一眼

for word in sentences[5]:

print(word)

注意:python2和python3的区别,python2直接segs = list(filter(lambda x:len(x)>1, segs))即可,不需要加list。

1.2.3 词袋模型

dictionary = corpora.Dictionary(sentences) # 根据现有数据生成词典

print(dictionary)

corpus = [dictionary.doc2bow(sentence) for sentence in sentences] # 对每句话,统计每个词语的频数,组成词袋模型

corpus[5] # 第5句话的词袋表示,意思为字典中index为21的词语出现了1次,index为25的词语出现了1次…………index为138的词语出现1次

1.2.4 LDA建模

# lda训练 corpus=转化为词袋的词语列表 id2word=词典 num_topics=主题数量

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=20)

``

`

我们查一下20个主题中的第3号分类,其中最常出现的头5个单词是:

```python

print(lda.print_topic(3, topn=5))

我们把所有的主题打印出来看看

for topic in lda.print_topics(num_topics=20, num_words=4):

print(topic[1])

我们可以对新加入的文本,进行简单主题分类:

lda.get_document_topics(bow)

其中bow为新文本的词袋。如:

text5 = ['徐立', '商汤', '科技', 'CEO', '谈起', '本次', '参展', '谈到', '成立', '刚刚', '两年', '创业', '公司', '参展', '展示', '最新', '人工智能', '技术', '产品', '表达', '人工智能', '理解', '人工智能', '特定', '领域', '超越', '人类', '广泛应用', '标志', 'Master', '胜利', '围棋', '世界', '开拓', '局面', '不谋而合']

bow = dictionary.doc2bow(text5)

ndarray = lda.inference([bow])[0]

print(''.join(text5))

for e, value in enumerate(ndarray[0]):

print('主题%d推断值%.2f' % (e, value))

相关文章

深度解析,uu为何在游戏圈引发骂战,背后原因令人深思
国足无缘世界杯引西媒震惊:14亿人找不出23个世界杯球员 扩军仍无缘
阔腿裤怎么搭配上衣 阔腿裤与上衣搭配原则