前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于自然语言处理系列-关键词提取

关于自然语言处理系列-关键词提取

作者头像
python与大数据分析
发布2022-03-11 14:39:23
4110
发布2022-03-11 14:39:23
举报
文章被收录于专栏:python与大数据分析

自然语言处理包括中文分词、词性标注、关键词抽取、依存句法分析、文本分类接口情感分析、词义相似度计算、实体标识、文本摘要等等,慢慢来吧,看看一步步能到什么程度。本文实现的是关键词提取。

在jiaba中,关键词提取包括了TF-IDF关键词提取、PageRank关键词提取方式,同时还可以自定义语料库、停用词库,在此基础上再进行TF-IDF关键词提取,本文略作尝试。

代码示例

代码语言:javascript
复制
#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import math
import re
import datetime
import sys
import jieba
import jieba.analyse
import codecs
from collections import Counter

#对文件进行分词处理
def segment(sentence, cut_all=False):
    sentence = sentence.replace('\n', '').replace('\u3000', '').replace('\u00A0', '')
    sentence = ' '.join(jieba.cut(sentence, cut_all=cut_all))
    return re.sub('[a-zA-Z0-9.。::,,))((!!??”“\"]', '', sentence).split()

#将文件从gb2312格式转码为utf-8格式
def EncodingtoUTF(filename):
    try:
        with codecs.open(filename, 'rb', 'mbcs') as f:
            text=f.read().encode("utf-8")
            with open(filename, 'wb') as e:
                e.write(text)
    except:
        return

# 对指定目录的文件进行分词
class DocumentsSegment(object):
    def __init__(self, dirname):
        self.dirname = dirname

        if not os.path.isdir(dirname):
            print(dirname, '- not a directory!')
            sys.exit()

    def __iter__(self):
        for dirfile in os.walk(self.dirname):
            for fname in dirfile[2]:
                # 对文件进行utf-8转码
                EncodingtoUTF(os.path.join(dirfile[0], fname))
                text = open(os.path.join(dirfile[0], fname),
                            'r', encoding='utf-8', errors='ignore').read()
                # 对文件进行迭代并进行分词
                yield segment(text)   # time consuming

class IDFGen():
    def __init__(self,inputdir,outputfile):
        self.inputdir=inputdir
        self.outputfile=outputfile
        self.documents=DocumentsSegment(inputdir)

    def gen_idf(self):
        ignored = {'', ' ', '', '。', ':', ',', ')', '(', '!', '?', '”', '“'}    #忽略词
        id_freq = {}    #词频字典
        i = 0
        for doc in self.documents:
            doc = set(x for x in doc if x not in ignored)   #剔除忽略词
            for x in doc:                                   #遍历文档
                id_freq[x] = id_freq.get(x, 0) + 1          #更新词频
            if i % 1000 == 0:                               #每1000篇文章提示进度
                print('Documents processed: ', i, ', time: ',
                      datetime.datetime.now())
            i += 1

        # 词频排序
        sortdata = dict(sorted(id_freq.items(), key=lambda x: x[1]))
        # 将词频转换后写入词频语料库
        with open(self.outputfile, 'w', encoding='utf-8') as f: #将词频取对数后,写入idf文件
            for key, value in sortdata.items():
                f.write(key + ' ' + str(math.log(i / value, 2)) + '\n')

# 词频文件加载
class IDFLoader(object):
    def __init__(self, idf_path):
        self.idf_path = idf_path
        self.idf_freq = {}     # idf
        self.mean_idf = 0.0    # 均值
        self.load_idf()

    # 加载词频文件
    def load_idf(self):       # 从文件中载入idf
        cnt = 0
        with open(self.idf_path, 'r', encoding='utf-8') as f:
            for line in f:
                try:
                    word, freq = line.strip().split(' ')
                    cnt += 1
                except Exception as e:
                    pass
                self.idf_freq[word] = float(freq)
            print(self.idf_freq)
        print('Vocabularies loaded: %d' % cnt)
        # 获取idf均值
        self.mean_idf = sum(self.idf_freq.values()) / cnt

if __name__ == "__main__":
    inputdir = 'C:\Python\Pycharm\langprocess\\train'
    idffile = 'C:\Python\Pycharm\langprocess\\udfidf.txt'
    stopwordfile= 'C:\Python\Pycharm\langprocess\\stopwords.txt'
    filename = 'C:\Python\Pycharm\langprocess\\train\C4-Literature\C4-Literature02.txt'

    str = '''《三国演义》描写了从东汉末年到西晋初年之间近百年的历史风云,以描写战争为主,诉说了东汉末年的群雄割据混战和魏、蜀、吴三国之间的政治和军事斗争,最终司马炎一统三国,建立晋朝的故事。反映了三国时代各类社会斗争与矛盾的转化,并概括了这一时代的历史巨变,塑造了一群叱咤风云的三国英雄人物。全书可大致分为黄巾起义、董卓之乱、群雄逐鹿、三国鼎立、三国归晋五大部分。在广阔的历史舞台上,上演了一幕幕气势磅礴的战争场面。作者罗贯中将兵法三十六计融于字里行间,既有情节,也有兵法韬略。《三国演义》是中国文学史上第一部章回小说,是历史演义小说的开山之作,也是第一部文人长篇小说,中国古典四大名著之一。'''
    seg_list = jieba.cut(str)       #分词
    # 《|三国演义|》|描写|了|从|东汉|末年|到|西晋|初年|之间|近|百年|的|历史风云|,|以|描写|战争|为主|,|诉说|了|东汉|末年|的|群雄割据|混战|和|魏|、|蜀|、|吴三国|之间|的|政治|和|军事|斗争
    data = Counter(seg_list)        #用Counter函数构造字典
    # Counter({',': 12, '的': 10, '了': 6, '、': 6, '。': 6, '三国': 4, '是': 3, '《': 2, '三国演义': 2, '》': 2
    # Counter输出的时候有顺序,但其实内部是无顺序的,建议排序一下
    top10= data.most_common(10)     #通过Counter函数的most_common获取前10名
    #[(',', 12), ('的', 10), ('了', 6), ('、', 6), ('。', 6), ('三国', 4), ('是', 3), ('《', 2), ('三国演义', 2), ('》', 2)]
    sortdata=sorted(data.items(), key=lambda x: x[1], reverse=True)
    # [(',', 12), ('的', 10), ('了', 6), ('、', 6), ('。', 6), ('三国', 4), ('是', 3), ('《', 2), ('三国演义', 2), ('》', 2)
    # AttributeError: 'Counter' object has no attribute 'sort'
    # 所以只能转换为list再通过list进行排序
    items = list(data.items())
    items.sort(key=lambda x: x[1], reverse=True)
    # [(',', 12), ('的', 10), ('了', 6), ('、', 6), ('。', 6), ('三国', 4), ('是', 3), ('《', 2), ('三国演义', 2), ('》', 2), ('描写', 2), ('东汉', 2),

    # ----------------------------------------关键词提取-------------------------------------------
    # 基于TF-IDF算法的关键词抽取
    # 第一个参数:待提取关键词的文本
    # 第二个参数:返回关键词的数量,重要性从高到低排序
    # 第三个参数:是否同时返回每个关键词的权重
    # 第四个参数:词性过滤,为空表示不过滤,若提供则仅返回包括指定词性的词,默认值为空,即不筛选
    keywords = jieba.analyse.extract_tags(str, topK=5, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v'))
    # [('三国', 0.5706667621368), ('兵法', 0.3433023063252), ('描写', 0.2863118806472), ('历史风云', 0.256041307266), ('群雄逐鹿', 0.242178363654)]

    # 基于 TF-IDF 算法的关键词抽取,使用停用词词典,使用逆向文件频率文本语料库
    tfidf = jieba.analyse.TFIDF()
    tfidf.set_stop_words('stopwords.txt')   # 使用停用词词典
    tfidf.set_idf_path('idf.txt')           # 使用默认的逆向文件频率(IDF)文本语料库
    keywords=tfidf.extract_tags(str,topK=5, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v')) # 再进行
    # [('三国', 0.5706667621368), ('兵法', 0.3433023063252), ('描写', 0.2863118806472), ('历史风云', 0.256041307266), ('群雄逐鹿', 0.242178363654)]

    # 基于 TextRank 算法的关键词抽取
    # 第一个参数:待提取关键词的文本
    # 第二个参数:返回关键词的数量,重要性从高到低排序
    # 第三个参数:是否同时返回每个关键词的权重
    # 第四个参数:词性过滤,为空表示不过滤,若提供则仅返回符合词性要求的关键词,默认过滤词性是('ns', 'n', 'vn', 'v')
    keywords = jieba.analyse.textrank(str, topK=5, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v'))
    # [('三国', 1.0), ('斗争', 0.7784764171715404), ('兵法', 0.6974027914816684), ('历史', 0.6748143587652791), ('时代', 0.6480813515953463)]

    # 利用jieba进行关键字提取时,有两种接口。
    # 一个基于TF-IDF算法,一个基于TextRank算法。
    # TF-IDF算法,完全基于词频统计来计算词的权重,然后排序,在返回TopK个词作为关键字。
    # TextRank相对于TF-IDF,基本思路一致,也是基于统计的思想,只不过其计算词的权重时,还考虑了词的上下文(通过窗口滑动来实现),
    #         而且计算词的权重时,也考虑了相关联系词的影响。可以说,TextRank实际上是依据位置与词频来计算词的权重的。
    # TF-IDF计算简单,运行性能更好。

    # ----------------------------------------自定义预料库后关键词提取-------------------------------------------
    #content = open(filename, 'rb').read()
    content = open(filename, 'r', encoding='utf-8', errors='ignore').read()

    jieba.analyse.set_stop_words(stopwordfile)
    keywords = jieba.analyse.extract_tags(content, topK=10)  #, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v'))  # 再进行
    print('未使用自定义预料,输出关键词:',keywords)
    # 未使用自定义预料,输出关键词: ['岭南文化', '文化', '爱国主义', '学者', '近代', '研讨会', '侨乡', '传统', '研究', '炎黄']

    # 基于原始语料,生成自定义的词频库
    myidffile=IDFGen(inputdir,idffile)
    myidffile.gen_idf()
    jieba.analyse.set_stop_words(stopwordfile)
    jieba.analyse.set_idf_path(idffile);
    keywords = jieba.analyse.extract_tags(content, topK=10)
    print('使用自定义预料后,输出关键词:', keywords)
    # 使用自定义预料后,输出关键词: ['岭南文化', '爱国主义', '广东', '侨乡', '岭南', '中原', '与会', '商品经济', '学者', '近代']
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python与大数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 代码示例
相关产品与服务
NLP 服务
NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档