中文文本中的关键字提取算法总结

技术交流QQ群:1027579432,欢迎你的加入!

0.关键词提取

  • 定义:从文本中把与这篇文章意义最相关的一些词语抽取出来。
  • 应用:在文献检索、自动文摘、文本聚类/分类等方面有着重要的应用,它不仅是进行这些工作不可或缺的基础和前提,也是互联网上信息建库的一项重要工作。

1.关键词抽取的方法-----主要有两种

  • 关键词分配:给定一个已有的关键词库,对于新来的文档从该词库里面匹配几个词语作为这篇文档的关键词。
  • 关键词提取:针对新文档,通过算法分析,提取文档中一些词语作为该文档的关键词。目前。大多数应用领域的关键词抽取算法都是基于第二种方法实现的,因为第二种方法在实际应用中更准确。

2.基于TF-IDF算法进行关键词提取

  • 在信息检索理论中,TF-IDF是(Term Frequency-Inverse Document Frequency)的简写。TF-IDF是一种数值统计,用来反映一个词语对于语料中某篇文档的重要性。在信息检索和文本挖掘领域,它经常用于因子加权。TF-IDF的主要思想:如果某个词在一篇文档中出现的频率越高,即TF越高;并且在语料库中其他文档中很少出现,即DF低,也就是IDF越高,则认为这个词具有很好的类别区分能力。
  • TF(Term Frequency)词频:表示词语在文档d中出现的概率,计算公式如下:
    \mathrm{tf}_{\mathrm{i}, \mathrm{j}}=\frac{n_{i, j}}{\sum_{k} n_{k, j}}
    其中,\boldsymbol{n}_{i, j}是该词语\boldsymbol{t}_{i}在文档\boldsymbol{d}_{j}中出现的次数,而分母则是在文档\boldsymbol{d}_{j}中所有字词的出现次数之和。
  • IDF(Inverse Document Frequency)逆文档频率:表示语料库中包含词语\boldsymbol{t}_{i}的文档的数目的倒数,计算公式如下:
    \mathrm{idf}_{\mathbf{i}}=\log \frac{|D|}{\left|\left\{j : t_{i} \in d_{j}\right\}\right|}
    其中,|D|表示语料库中文档的总数,\left|\left\{j : t_{i} \in d_{j}\right\}\right|表示包含词语\boldsymbol{t}_{i}的文档数量。如果该词语不出现在语料库中,就会导致被除数为0,因此一般情况下使用1+\left|\left\{j : t_{i} \in d_{j}\right\}\right|
  • TF-IDF在实际中主要是将上面的两者相乘,即TF*IDF,计算公式如下:
    \mathrm{TF}-\mathrm{IDF}_{i, j}=\mathrm{tf}_{i, j} \times \mathrm{idf}_{i}
    因此,TF-IDF倾向于过滤常见的词语,保留重要的词语。例如,某一特定文档内的高频词语,以及该词语在整个文档集合中的低文件频率,可以产生出高权重的TF-IDF。
  • jieba分词库已经实现了基于TF-IDF算法的关键词抽取,通过import jieba.analyse引入,函数参数解释如下:
    jieba.analyse.extract_tags(sentence, topK=20, withWeight=False,allowPOS=())
    
    • sentence:待提取的文本语料
    • topK:返回TF-IDF权重最大的关键词个数,默认是20
    • withWeight:是否需要返回关键词权重值,默认是False
    • allowPOS:仅包括指定词性的词,默认值是空,即不筛选
     import jieba.analyse
    
     sentence = "人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。人工智能可以对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。人工智能是一门极富挑战性的科学,从事这项工作的人必须懂得计算机知识,心理学和哲学。人工智能是包括十分广泛的科学,它由不同的领域组成,如机器学习,计算机视觉等等,总的说来,人工智能研究的一个主要目标是使机器能够胜任一些通常需要人类智能才能完成的复杂工作。但不同的时代、不同的人对这种“复杂工作”的理解是不同的。 [1]  2017年12月,人工智能入选“2017年度中国媒体十大流行语”。"
     keywords = " ".join(jieba.analyse.extract_tags(sentence=sentence, topK=20, withWeight=False, allowPOS=()))
     print(keywords)
    
     keywords = jieba.analyse.extract_tags(sentence, topK=10, withWeight=True, allowPOS=(['n', 'v']))   # 只提取前10个名词和动词
     print(keywords)
    

3.基于TextRank算法进行关键词提取

  • TextRank是由PangeRank改进而来的,核心思想是将文本中的词语当作图中的节点,通过边相互连接,不同的节点会有不同的权重,权重高的节点可以作为关键字。TextRank的计算公式如下:
    W S\left(V_{i}\right)=(1-d)+d * \sum_{V_{j} \in I n\left(V_{i}\right)} \frac{w_{j i}}{\sum_{V_{k} \in O u t\left(V_{j}\right)}} W S\left(V_{j}\right)
    从上式可以看出,节点i的权重取决于节点i的邻接节点中i到j这条边的权重、j节点的所有出度的边的权重、节点j的权重这三个因素。将这些邻接节点计算的权重相加,再乘上一定的阻尼系数,就是节点i的权重,阻尼系数d一般取0.85
  • TextRank用于关键词提取的算法如下:
    • (1)把给定的文本T按照完整句子进行分割,即:
      T=\left[S_{1}, S_{2}, \cdots, S_{m}\right]
    • (2)对每个句子,进行分词和词性标注处理,并过滤掉停用词,只保留指定词性的词语(如名词、动词、形容词),其中t_{i, j}是保留后的候选关键词。
      S_{i}=\left[t_{i, 1}, t_{i, 2}, \cdots, t_{i, n}\right]
    • (3)构建候选关键词图G=(V,E),其中V是节点集,由(2)步中生成的候选关键词组成。然后采用共现关系(Co-Occurrence)构造任意两个节点之间的边,两个节点之间存在边即仅当它们对应的词汇在长度为K的窗口中共现,K表示窗口大小,即最多共现K个单词。
    • (4)根据TextRank的公式,迭代传播各节点的权重,直到收敛。
    • (5)对节点权重进行倒序排列,从而得到最重要的T个单词,作为候选关键词。
    • (6)由第(5)步得到最重要的T个词汇,在原始文本中进行标记,如果构成相邻词组,则组合成多词关键词。
  • jieba库中已经实现了基于TextRank算法的关键词抽取,通过命令import jieba.analyse
jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'))
result = " ".join(jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=("ns", "n", "vn", "v")))
print(result)

result = " ".join(jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=("n", "v")))  # 只看动词和名词
print(result)

4.基于LDA主题模型进行关键词抽取

  • 语料是一个关于汽车的短文本,下面通过gensim库完成基于LDA的关键词提取。整个过程的步骤为:
    • (1)文件加载
    • (2)jieba分词
    • (3)去停用词
    • (4)构建词袋模型
    • (5)LDA模型训练
    • (6)结果可视化
import jieba.analyse as analyse
import jieba
import pandas as pd
from gensim import corpora, models, similarities
import gensim
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline



# 设置文件路径
dir = "E://DeepLearning//jupyter_code//dataset//corpus//02_project//"
file_desc = "".join([dir, "car.csv"])
stop_words = "".join([dir, "stopwords.txt"])


# 定义停用词
stopwords = pd.read_csv(stop_words, index_col=False, quoting=3, sep="\t", names=["stopword"], encoding="utf-8")
stopwords = stopwords['stopword'].values

# 加载语料
df = pd.read_csv(file_desc, encoding='utf-8')

# 删除nan行
df.dropna(inplace=True)
lines = df.content.values.tolist()

# 开始分词
sentences = []
for line in lines:
    try:
        segs = jieba.lcut(line)
        segs = [v for v in segs if not str(v).isdigit()]  # 去数字
        segs = list(filter(lambda x: x.strip(), segs))  # 去空格
        segs = list(filter(lambda x: x not in stopwords, segs))  # 去停用词
        sentences.append(segs)
    except Exception:
        print(line)
        continue

# 构建词袋模型
dictionary = corpora.Dictionary(sentences)
corpus = [dictionary.doc2bow(sentence) for sentence in sentences]
# lda模型,num_topics是主题个数
lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=10)

# 查一下第1号分类,其中最常出现的5个词
print(lda.print_topic(1, topn=5))
print("---------------------------------分割线-------------------------------------")
# 打印所有10个主题,每个主题显示8个词
for topic in lda.print_topics(num_topics=10, num_words=8):
    print(topic[1])


# 显示中文matplotlib
plt.rcParams["font.sans-serif"] = [u'SimHei']
plt.rcParams["axes.unicode_minus"] = False
# 在可视化部分,首先画出10个主题的8个词的概率分布图
num_show_term = 8  # 每个主题下显示几个词
num_topics = 10
for i, k in enumerate(range(num_topics)):
    ax = plt.subplot(2, 5, i+1)
    item_dis_all = lda.get_topic_terms(topicid=k)
    item_dis = np.array(item_dis_all[:num_show_term])
    ax.plot(range(num_show_term), item_dis[:, 1], 'b*')
    item_word_id = item_dis[:, 0].astype(np.int)
    word = [dictionary.id2token[i] for i in item_word_id]
    ax.set_ylabel(u"概率")
    for j in range(num_show_term):
        ax.text(j, item_dis[j, 1], word[j], bbox=dict(facecolor='green', alpha=0.1))
plt.suptitle(u"10个主题及其8个主要词的概率", fontsize=18)
plt.show()

5.基于pyhanlp进行关键词提取

  • HanLP也可以进行关键词提取,内部采用TextRankKeyword实现,如下面所示:
from pyhanlp import *

result = HanLP.extractKeyword(sentence, 20)
print(result)

6.代码及数据集下载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容