第4课:动手实战中文文本中的关键字提取

前言

关键词提取就是从文本里面把跟这篇文章意义最相关的一些词语抽取出来。这个可以追溯到文献检索初期,关键词是为了文献标引工作,从报告、论文中选取出来用以表示全文主题内容信息的单词或术语,在现在的报告和论文中,我们依然可以看到关键词这一项。因此,关键词在文献检索、自动文摘、文本聚类/分类等方面有着重要的应用,它不仅是进行这些工作不可或缺的基础和前提,也是互联网上信息建库的一项重要工作。

关键词抽取从方法来说主要有两种:

  • 第一种是关键词分配:就是给定一个已有的关键词库,对于新来的文档从该词库里面匹配几个词语作为这篇文档的关键词。

  • 第二种是关键词提取:针对新文档,通过算法分析,提取文档中一些词语作为该文档的关键词。

目前大多数应用领域的关键词抽取算法都是基于后者实现的,从逻辑上说,后者比前者在实际应用中更准确。

下面介绍一些关于关键词抽取的常用和经典的算法实现。

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

在信息检索理论中,TF-IDF 是 Term Frequency - Inverse Document Frequency 的简写。TF-IDF 是一种数值统计,用于反映一个词对于语料中某篇文档的重要性。在信息检索和文本挖掘领域,它经常用于因子加权。TF-IDF 的主要思想就是:如果某个词在一篇文档中出现的频率高,也即 TF 高;并且在语料库中其他文档中很少出现,即 DF 低,也即 IDF 高,则认为这个词具有很好的类别区分能力。

TF 为词频(Term Frequency),表示词 t 在文档 d 中出现的频率,计算公式:

enter image description here

其中,ni,j<math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>n</mi><mrow class="MJX-TeXAtom-ORD"><mi>i</mi><mo>,</mo><mi>j</mi></mrow></msub></math> 是该词 ti<math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>t</mi><mi>i</mi></msub></math> 在文件 dj<math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>d</mi><mi>j</mi></msub></math> 中的出现次数,而分母则是在文件 dj<math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>d</mi><mi>j</mi></msub></math> 中所有字词的出现次数之和。

IDF 为逆文档频率(Inverse Document Frequency),表示语料库中包含词 t 的文档的数目的倒数,计算公式:

enter image description here

其中,|D| 表示语料库中的文件总数,|{j:ti∈dj}|<math xmlns="http://www.w3.org/1998/Math/MathML"><mrow class="MJX-TeXAtom-ORD"><mo stretchy="false">|</mo></mrow><mo fence="false" stretchy="false">{</mo><mi>j</mi><mo>:</mo><msub><mi>t</mi><mi>i</mi></msub><mo>∈</mo><msub><mi>d</mi><mi>j</mi></msub><mo fence="false" stretchy="false">}</mo><mrow class="MJX-TeXAtom-ORD"><mo stretchy="false">|</mo></mrow></math> 包含词 ti<math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>t</mi><mi>i</mi></msub></math> 的文件数目,如果该词语不在语料库中,就会导致被除数为零,因此一般情况下使用 1+|{j:ti∈dj}|<math xmlns="http://www.w3.org/1998/Math/MathML"><mn>1</mn><mo>+</mo><mrow class="MJX-TeXAtom-ORD"><mo stretchy="false">|</mo></mrow><mo fence="false" stretchy="false">{</mo><mi>j</mi><mo>:</mo><msub><mi>t</mi><mi>i</mi></msub><mo>∈</mo><msub><mi>d</mi><mi>j</mi></msub><mo fence="false" stretchy="false">}</mo><mrow class="MJX-TeXAtom-ORD"><mo stretchy="false">|</mo></mrow></math>。

TF-IDF 在实际中主要是将二者相乘,也即 TF * IDF, 计算公式:

enter image description here

因此,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:仅包括指定词性的词,默认值为空,即不筛选。

接下来看例子,我采用的语料来自于百度百科对人工智能的定义,获取 Top20 关键字,用空格隔开打印:

    import jieba.analyse
    sentence  = "人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。人工智能可以对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。人工智能是一门极富挑战性的科学,从事这项工作的人必须懂得计算机知识,心理学和哲学。人工智能是包括十分广泛的科学,它由不同的领域组成,如机器学习,计算机视觉等等,总的说来,人工智能研究的一个主要目标是使机器能够胜任一些通常需要人类智能才能完成的复杂工作。但不同的时代、不同的人对这种“复杂工作”的理解是不同的。2017年12月,人工智能入选“2017年度中国媒体十大流行语”。"
    keywords = "  ".join(jieba.analyse.extract_tags(sentence , topK=20, withWeight=False, allowPOS=()))
    print(keywords)

执行结果:

人工智能 智能 2017 机器 不同 人类 科学 模拟 一门 技术 计算机 研究 工作 Artificial Intelligence AI 图像识别 12 复杂 流行语

下面只获取 Top10 的关键字,并修改一下词性,只选择名词和动词,看看结果有何不同?

    keywords =(jieba.analyse.extract_tags(sentence , topK=10, withWeight=True, allowPOS=(['n','v'])))
    print(keywords)

执行结果:

[('人工智能', 0.9750542675762887), ('智能', 0.5167124540885567), ('机器', 0.20540911929525774), ('人类', 0.17414426566082475), ('科学', 0.17250169374402063), ('模拟', 0.15723537382948452), ('技术', 0.14596259315164947), ('计算机', 0.14030483362639176), ('图像识别', 0.12324502580309278), ('流行语', 0.11242211730309279)]

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

TextRank 是由 PageRank 改进而来,核心思想将文本中的词看作图中的节点,通过边相互连接,不同的节点会有不同的权重,权重高的节点可以作为关键词。这里给出 TextRank 的公式:

enter image description here

节点 i 的权重取决于节点 i 的邻居节点中 i-j 这条边的权重 / j 的所有出度的边的权重 * 节点 j 的权重,将这些邻居节点计算的权重相加,再乘上一定的阻尼系数,就是节点 i 的权重,阻尼系数 d 一般取 0.85。

TextRank 用于关键词提取的算法如下:

(1)把给定的文本 T 按照完整句子进行分割,即:

enter image description here

(2)对于每个句子,进行分词和词性标注处理,并过滤掉停用词,只保留指定词性的单词,如名词、动词、形容词,其中 ti,j<math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>t</mi><mrow class="MJX-TeXAtom-ORD"><mi>i</mi><mo>,</mo><mi>j</mi></mrow></msub></math> 是保留后的候选关键词。

enter image description here

(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'))

直接使用,接口参数同 TF-IDF 相同,注意默认过滤词性。

接下来,我们继续看例子,语料继续使用上例中的句子。

    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)

执行结果:

智能 人工智能 机器 人类 技术 模拟 包括 科学 理论 计算机 领域 年度 需要 心理学 信息 语言 识别 带来 过程 延伸

基于 LDA 主题模型进行关键词提取

其实,使用 LDA 获取文本关键词在我的第一次 Chat《NLP 中文短文本分类项目实践(上)》已经讲过了,为了保持内容的完整性,在这里我继续写一下。

备注:由于 Chat 《NLP 中文短文本分类项目实践(上)》的内容是收费的,已把该内容放到达人课的最后一篇,读者不用购买即可阅读。

语料是一个关于汽车的短文本,下面通过 Gensim 库完成基于 LDA 的关键字提取。整个过程的步骤为:文件加载 -> jieba 分词 -> 去停用词 -> 构建词袋模型 -> LDA 模型训练 -> 结果可视化。

    #引入库文件
    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 = "D://ProgramData//PythonWorkSpace//study//"
    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='gbk')
    #删除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是主题的个数,这里定义了5个
    lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=10)
    #我们查一下第1号分类,其中最常出现的5个词是:
    print(lda.print_topic(1, topn=5))
    #我们打印所有5个主题,每个主题显示8个词
    for topic in lda.print_topics(num_topics=10, num_words=8):
        print(topic[1])

执行结果如下图所示:

enter image description here
    #显示中文matplotlib
    plt.rcParams['font.sans-serif'] = [u'SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    # 在可视化部分,我们首先画出了九个主题的7个词的概率分布图
    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'9个主题及其7个主要词的概率', fontsize=18)
    plt.show()

执行结果如下图所示:

enter image description here

基于 pyhanlp 进行关键词提取

除了 jieba,也可以选择使用 HanLP 来完成关键字提取,内部采用 TextRankKeyword 实现,语料继续使用上例中的句子。

    from pyhanlp import *
    result = HanLP.extractKeyword(sentence, 20)
    print(result)

执行结果:

[人工智能, 智能, 领域, 人类, 研究, 不同, 工作, 包括, 模拟, 新的, 机器, 计算机, 门, 科学, 应用, 系统, 理论, 技术, 入选, 复杂]

总结

本节内容的重点就是掌握关键字提取的基本方法,常规的关键词提取方法如上所述,当然还有其他算法及其改进,有深入研究需求的,可以下载关键字提取方面的论文阅读。

参考文献:

  1. Mihalcea R, Tarau P. TextRank: Bringing order into texts[C]//Proceedings of EMNLP. 2004, 4(4): 275.
  2. Witten I H, Paynter G W, Frank E, et al. KEA: Practical automatic keyphrase extraction[C]//Proceedings of the fourth ACM conference on Digital libraries. ACM, 1999: 254-255.
  3. Chien L F. PAT-tree-based keyword extraction for Chinese information retrieval[C]//ACM SIGIR Forum. ACM, 1997, 31(SI): 50-58.

如有侵权请联系QQ:758230255删除

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

推荐阅读更多精彩内容