Python编程进阶03-自然语言处理实战

Python编程进阶01--输入输出文件操作

Python编程进阶02--Excel文件操作 

1、jieba扩展库(库描述,基本操作)

2、文本词频统计实战(《三国演义》词频统计、人物统计)


首先我们来了解一下中文分词的特点和难点: 

【中文分词介绍】

【中文分词特点】

  • 词是最小的能够独立活动的有意义的语言成分
  • 汉语是以字为单位,不像西方语言,词与词之间没有空格之类的标志指示词的边界
  • 分词问题为中文文本处理的基础性工作,分词的好坏对后续中文信息处理起关键作用

【中文分词难点】

  • 分词规范,词的定义还不明确(《统计自然语言处理》宗成庆)
  • 歧义切分问题,交集型切分问题,多以组合型切分歧义
  • 结婚的和尚未结婚的=>结婚 / 的 / 和 / 尚未 / 结婚 / 的

                                            结婚 / 的 / 和尚 / 未 / 结婚 / 的 

  • 未登录词问题有两种解释:一是已有的此表中没有收录的词,二是已有的训练语料中未曾出现过的词,一些网络新词,自造词,自造词一般都属于这些词。                                          

【中文分词方法】

  • 基于字典、词库匹配的分词方法(基于规则)

将待分的字符串与一个充分大的机器词典中的词条相匹配。常用的有:正想最大匹配,逆向最大匹配,最少切分法。实际应用中,将机械分词作为处分手段,利用语言信息提高切分准确率。

  • 基于词频统计的方法(基于统计)

相邻的字词同时出现的次数越多,越有可能构成一个词语,对语料中的字组频度进行统计,基于词的频度统计的分词方法是一种全切分方法。jieba就是基于统计的分词方法。

  • 基于知识理解的分词方法

该方法主要基于句法、语法分析,并结合语义分析,通过对上下文内容所提供信息的分析对词进行丁姐,由于汉语语言知识的笼统、复杂性,目前还处在实验阶段

jieba扩展库

【jieba是Python中一个重要的第三方中文分词函数库】

  • jieba分词,完全开源,有集成的python库,简单易用
  • 安装:

全自动安装:easy_install jieba或者pip install jieba / pip3 install jieba

半自动安装:先下载https://pypi.python.org/pypi/jieba/,解压运行python setup.py install

手动安装:将jieba目录放置于当前目录或者site-packages目录

通过import jieba来使用

【jieba实现原理】

  • 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能称此情况所构成的有向无环图(DAG)。

例如句子“抗日战争”生成的DAG中{0:[0,1,3]}这样一个简单的DAG,就是表示0位置开始,在0,1,3位置都是词,就是说0~0,0~1,0~3即“抗”,“抗日”,“抗日战争”这三个词在dict.txt中都是词。

  • 采用了动态规划查找最大概率路径,找出基于词频的最大切分组合。

根据动态规划查找最大概率路径的基本思想就是对句子从右往左反向计算最大概率,以此类推,最后得到最大概率路径,得到最大概率的切分组合。

  • 对于未登录词,采用了基于汉字成词能力的隐马尔科夫(HMM)模型,使用了Viterbi算法(一种最优路径算法)

注:隐马尔科夫模型是一个关于时序的概率模型,描述由隐马尔可夫链随机生成观测序列的过程,属于生成模型。在语音识别、自然语言处理、生物信息等领域有着广泛的应用。

【jieba支持三种分词模式】

  • 精确模式:试图将句子最精确的分开,适合文本分析
  • 全模式:把句子中所有的可以成词的词语都扫描出来,速度非常快,但是不能解决歧义
  • 搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词
  • 支持繁体分词
  • 支持自定义词典
  • MIT授权协议(开源软件授权协议)

【jieba常用函数】

  • jieba.cut:方法接受三个输入参数,需要分词的字符串;cut_all参数用来控制是否采用全模式;HMM参数用来控制是否使用HMM模型。
  • jieba.cut_for_search:方法接受两个参数,需要分词的字符串;是否使用HMM模型。该方法适合使用搜索引擎构建倒排索引的分词,粒度比较细
  • jieba.cut以及jieba.cut_for_search返回的结构都是一个可迭代的generator,可以使用for循环来获得分词后得到的每一个词语(unicode)或者用jieba.lcut以及jieba.lcut_for_search直接返回list,然后接可以使用list列表的各种函数进行操作。
#_*_coding:utf-8 _*_

import jieba

# cut方法有两个参数:
# 1)第一个参数是我们想分词的字符串
# 2)第二个参数cut_all是用来控制是否采用全模式

# 全模式
word_list = jieba.cut("今天天气真好。亲爱的,我们去远足吧!",cut_all = True)
print("全模式:","|".join(word_list))
# 精确模式,默认即为精确模式
word_list = jieba.cut("今天天气真好。亲爱的,我们去远足吧!",cut_all = False)
print("精确模式:","|".join(word_list))
# 搜索引擎模式
word_list = jieba.cut_for_search("今天天气真好。亲爱的,我们去远足吧!")
print("搜索引擎模式:","|".join(word_list))

运行结果:

Building prefix dict from the default dictionary ...
Dumping model to file cache C:\Users\孔东帅\AppData\Local\Temp\jieba.cache
Loading model cost 1.123 seconds.
Prefix dict has been built successfully.
全模式: 今天|今天天气|天天|天气|真好|。|亲爱|的|,|我们|去|远足|吧|!
精确模式: 今天天气|真|好|。|亲爱|的|,|我们|去|远足|吧|!
搜索引擎模式: 今天|天天|天气|今天天气|真|好|。|亲爱|的|,|我们|去|远足|吧|!

【TF-IDF释义】

  • TF-IDF(term frequency-inverse document frequency)是一种用于信息检索与数据挖掘的数据加权技术。
  • TF意思是词频,指关键词在文中出现的次数除以全文总字数。
  • IDF意思是逆文本频率指数,反映关键词的普遍程度--当一个词月普遍(即有大量文档包含这个词)时,其IDF值越低;反之,IDF值越高(如的,地,得出现频率很高,但不能代表关键词有效信息)

词频(TF)=((某个词在文章中出现次数)/(文章的总词数))×逆文档频率(IDF)=log((语料库文档总数)/包含该词的文档数+1)词频(TF)=(某个词在文章中的出现次数/文章的总词数)×逆文档频率(IDF)=log(语料库的文档总数/包含该词的文档数+1)

【可以看出】

  • 当一个词在文档频率高并且新鲜度高(即普遍度低),其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:词性过滤,为空表示不过滤,若提供则金返回符合词性要求的关键词

看下面示例:

示例文档“十九大报文节选.txt”自提:https://download.csdn.net/download/MARS_098/12117033

import jieba.analyse

f = open("\十九大报告节选.txt","rb") # 加上文件绝对地址
sentence = f.read()

keywords = jieba.analyse.extract_tags(sentence,topK = 15,withWeight = True,allowPOS = ('n','nr','ns'))
# allowPOS:词性过滤:n表示名词、nr表示人名、ns表示地名

for item in keywords:
    print(item[0],item[1])

运行结果:

初心 1.056602437712
小康社会 0.6097804820220001
特色 0.5239102226336
全党同志 0.512082614532
社会主义 0.50983069314
中国 0.3632784823992
全面 0.33744171159299996
时代 0.3303798174336
人民 0.3125617860198
大会 0.2465050141716
共命运 0.228315420044
机遇期 0.222561778594
伟大旗帜 0.214452476432
方得 0.1954708653386
牢记 0.18611115603679998

【文本词频统计实战】

  • 统计《三国演义》词频前20的词语
  • “三国演义.txt”文件自提:
  • 链接:https://pan.baidu.com/s/1_Gd1Tm2_-60VXTHJZQPTLA 
    提取码:ygqu
import jieba

f = open("E:\Python大战机器学习\第三部分 Python编程进阶\code 3、自然语言处理实战\三国演义.txt","rb")
txt = f.read()
words = jieba.lcut(txt)    # 分词
counts = {}      # 定义一个空字典保存分词结果

for word in words:
    if len(word) == 1:    # 排除单个字的分词结果,如“我”
        continue
    else:
        counts[word] = counts.get(word,0) + 1
        
items = list(counts.items())
items.sort(key = lambda items:items[1],reverse = True)
# reverse = True表示根据词频逆向输出
for i in range(20):
    word,count = items[i]
    print("{0:<10}{1:>5}".format(word,count))

运行结果:

曹操          934
孔明          831
将军          760
却说          647
玄德          570
关公          509
丞相          488
二人          465
不可          435
荆州          419
孔明曰         385
玄德曰         383
不能          383
如此          376
张飞          348
商议          344
如何          336
主公          327
军士          309
吕布          299

观察我们可以发现,统计结果会有一些错误,如曹操和丞相其实是一个人,但是却分开成了两个,孔明曰也被错分类为一个人,接下来我们再来进一步统计处理:

import jieba 

f = open("E:\Python大战机器学习\第三部分 Python编程进阶\code 3、自然语言处理实战\三国演义.txt","rb")
txt = f.read()
words = jieba.lcut(txt)
counts = {}

for word in words:   
    if len(word)==1:    # 排除单个字的分词结果
        continue
    elif word == "诸葛亮" or word =="孔明曰":
        rword = "孔明"
    elif word == "关公" or word == "云长":
        rword = "关羽"
    elif word == "玄德" or word == "玄德曰":
        rword = "刘备"
    elif word == "孟德" or word == "丞相":
        rword = "曹操"
    else:
        rword = word
        counts[word] = counts.get(word,0) + 1
        
personlist = ["孔明","曹操","张飞","刘备","关羽","孙权","吕布","鲁肃","赵云","马超","姜维","魏延",\
             "庞统","董卓","袁绍","孟获","陆逊","孙尚香","孙坚","孙策","司马懿","曹丕","张辽"]
items = list(counts.items())
items.sort(key = lambda items:items[1],reverse = True)
for i in range(50):
    word,count = items[i]
    if personlist.count(word)>0:
        print("{0:<10}{1:>5}".format(word,count))

运行结果:

曹操          934
孔明          831
张飞          348
吕布          299
刘备          271
孙权          264
赵云          255
司马懿         221
袁绍          190
马超          185
魏延          177

已进入实战进度,我也是小白,最近因为考研的事不得已放一放机器学习的内容了,接下来,本人将会主攻网络安全方面的内容,整理之后也会发布出来,一起进步吧。

发布了51 篇原创文章 · 获赞 5 · 访问量 2003

猜你喜欢

转载自blog.csdn.net/MARS_098/article/details/103999028