查看原文
其他

对于中文,nltk能做哪些事情

2017-11-06 大邓 大邓带你玩python

NLTK学习-1

英文分词与词性标注

#分词

word_list = nltk.word_tokenize(text)

#标注
nltk.pos_tag(word_list)

我们最熟悉的nltk大概就是上面这样,而且因为适用场景主要是外文数据。所以没怎么碰nltk,这阵子又重新翻看了《用python做自然语言处理》一书(一年前看的时候因为不能处理中文,就没怎么学),发现稍微处理下中文数据,也是可以用强大的nltk实现的。下面我们开始尝试用nltk对中文数据进行分析,看看能做哪些东西。

一、搜索词语

这一章节,可以让你了解词语上下文查找、相似词语查找、统计词频、制作离散图。

实现上面的功能需要先将文本处理成nltk容易处理的Text类,方便进行文本搜索及计算。

1.1以三体小说为例,初始化Text类

from nltk.text import Text novel_data = open('texts/三体全集.txt').read()

#清除无关信息,只保留中文文本
cleaned_data = ''.join(re.findall(r'[\u4e00-\u9fa5]', novel_data))

wordlist = jieba.lcut(cleaned_data)

#初始化三体分词后的词语列表数据为Text类
text = Text(wordlist)

1.2word的上下文

词语word在text中的上下文

#三体  的上下文,打印宽度20字符,共10行的上下文
text.concordance(word='三体',width=20,lines=10)
Displaying 10 of 841 matches: 荐 好书 刘慈欣 三体 三体 终于 能 书 刘慈欣 三体 三体 终于 能 与 科 天立地 的 大字 三体 随后 出现 丁 再次 开始 在 三体 世界 中 命运 但 汪淼 明白 三体 的 真实 不 在 至 两个 数量级 三体 正是 这样 它 他 突然 悟出 三体 的 不 寻常 在 绳任 其 回到 三体 世界 飞星 关键 栗 他 想起 了 三体 中 的 那些 巨 它 最好 游戏 三体 难道 它 与 这

1.3word的上下文中最相似的10个词

#word =文明#在word上下文中找到最相思的10个词
text.similar(word='文明',num=10)
世界 人 他 太阳 宇宙 人类 时代 我们 舰队 方向

1.4多个词的上下文

Text.common_contexts([word1, word2])在_中 进入_时 到_的 是_的 的_世界 看到_的 和_的 和_两个

1.5 统计词语频数

text.count(word='三体')841

1.6离散图

""" 画出三体人物出现位置,横坐标为每个词出现在text中的索引位置 从图中基本上可以看出每个人物的出现在小说中的顺序。 汪淼和叶文洁出现在《三体》开头 罗辑几乎贯穿《三体》 维德、程心、云天明出现在《三体》末尾 """

words=['汪淼','叶文洁','章北海','申玉菲','罗辑','史强','庄颜','维德','程心','艾AA','云天明']
text.dispersion_plot(words)


1.7 按照已有风格,随机生成文本

根据text文本风格,按照给定的words随机生成一串文本。

但是不知道为啥,这里我没运行出来。 网上查了下,说可能跟nltk版本有关,待考证。

words = ['技术','三体']
print(text.generate(words))

没有运行出来,待解决

None

二、计算词语相似度

计算某个词与其他所有词的相似度这个功能,首先要将数据初始化为ContextIndex类。

from nltk.text import ContextIndex

#初始化三体分词后的词语列表数据为ContentIndex类
contentindex = ContextIndex(wordlist)

#计算各个词与word的相似度值,返回字典

similarity_scores = contentindex.word_similarity_dict(word='三体')

#保留关联度大于0.02的词语#为了减少打印的词语的数量,我这里选择的阈值为0.02
for key,value in similarity_scores.items():    if value>0.02:        print(key,value)
三体 1.0 那个 0.025295109612141653 其他 0.0224159402241594 这个 0.029950083194675542 地球 0.06006006006006005 中国 0.02147239263803681 两个 0.03639846743295019 宇宙 0.024855012427506214 所有 0.026286966046002194 整个 0.020618556701030927 每个 0.025974025974025976 人类 0.03790087463556851 太阳系 0.023379383634431455 太空 0.029654036243822072 外星 0.0374414976599064 三维 0.03193033381712627 亚洲 0.028846153846153848 掩体 0.023809523809523808

三、计算TF-IDF

TF-IDF值反映了一个词代表某类文本的代表性的程度。比如金融类文本中,“股票”具有很强的代表性,相反“美食”几乎不具有代表性。

tf-idf值越大,说明这个词对于这类文本越具有代表性。

3.1 tf-idf学习

TF-IDF,最开始用于信息检索,在信息检索中其计算过程如下

TF-IDF模型的主要思想是:如果词w在一篇文档d中出现的频率高,并且在其他文档中很少出现,则认为词w具有很好的区分能力,适合用来把文章d和其他文章区分开来。该模型主要包含了两个因素:TF,IDF

词频TF(Term Frequency):词w在文档d中出现次数count(w, d)和文档d中总词数size(d)的比值: 

逆向文档频率IDF(Inverse Document Frequency):文档总数n与词w所出现文件数docs(w, D)比值的对数: 

TF-IDF= TF * IDF =(词频*词权)

TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。

3.2 实战

先将数据初始化为TextCollection类

#TF-IDF

from nltk.text import TextCollection
import re
import jieba

def text(file):
   """
   该函数用来读取文件中的中文数据
   """
   novel_data = open(file).read()    cleaned_data = ''.join(re.findall(r'[\u4e00-\u9fa5]', novel_data))    
   wordlist = jieba.lcut(cleaned_data)    return cleaned_data

#不同种类的文本
text1 = text(file='texts/体育.txt')
text2 = text(file='texts/财经.txt')
text3 = text(file='texts/新闻.txt')
text4 = text(file='texts/科技.txt')

#将文本列表初始化为TextCollection类
mytexts = TextCollection([text1,text2,text3,text4])

3.2.1 计算tf

mytexts.idf('金融')0.6931471805599453

3.2.2 计算idf

#计算 金融 在 各个text的tf值
print(mytexts.tf('金融',text1))
print(mytexts.tf('金融',text2))
print(mytexts.tf('金融',text3))
print(mytexts.tf('金融',text4))
0.0 0.015074986401429792 0.0 0.0008085008085008085

3.2.3 计算tf-idf

#计算 金融在 各个text中的tf-idf值
print(mytexts.tf_idf('金融', text1))
print(mytexts.tf_idf('金融', text2))
print(mytexts.tf_idf('金融', text3))
print(mytexts.tf_idf('金融', text4))
0.0 0.010449184321130576 0.0 0.0005604100558927716

可见,词语“金融”很能代表 财经类文本,可以作为财经类文本的关键词。

四、Ngrams的实现

nltk.util模块可以帮助我们快速实现Ngrams

4.1 bigrams/trigrams

from nltk.util import bigrams,trigrams

#bigrams返回的是生成器,需要list才能直接显示出来
print(list(bigrams([1,2,3,4,5])))
print(list(trigrams([1,2,3,4,5])))
[(1, 2), (2, 3), (3, 4), (4, 5)] [(1, 2, 3), (2, 3, 4), (3, 4, 5)]

4.2 ngrams(sequence, n)

将序列生成n连词组序列

from nltk.util import ngrams

#生成3连词组序列
list(ngrams([1,2,3,4,5], 3))
[(1, 2, 3), (2, 3, 4), (3, 4, 5)]

4.3 skipgrams(sequence, n, k)

from nltk.util import skipgrams

sent = "a b c d e f".split()
print(list(skipgrams(sent, 2, 1)))
print(list(skipgrams(sent, 3, 1)))
[('a', 'b'), ('a', 'c'), ('b', 'c'), ('b', 'd'), ('c', 'd'), ('c', 'e'), ('d', 'e'), ('d', 'f'), ('e', 'f')] [('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'c', 'd'), ('b', 'c', 'd'), ('b', 'c', 'e'), ('b', 'd', 'e'), ('c', 'd', 'e'), ('c', 'd', 'f'), ('c', 'e', 'f'), ('d', 'e', 'f')]

五、probability模块

probability模块中有两个比较好用的类,一个是FreqDist,另一个是ConditionFreqDist类。

FreqDist可以实现词频计算,并制图

ConditionFreqDist可以实现带条件的词频计算,并制图。

5.1 FreqDist类

5.1.1初始化词语列表为FreqDist对象

from nltk.probability import FreqDist novel_data = open('texts/三体全集.txt').read()

cleaned_data = ''.join(re.findall(r'[\u4e00-\u9fa5]', novel_data))

wordlist = jieba.lcut(cleaned_data)

#创建包含给定样本的频率分布(传入词语列表)
fdist = FreqDist(wordlist)

5.1.2 打印词语列表

#打印词列表
print(fdist.keys())
dict_keys(['刘慈欣', '三体', '终于', '能', '与', '科幻', '朋友', '们', '见面', '了', '用', '连载', '的', '方式', '事先', '谁', '都', '没有', '想到', '也', '是', '无奈', '之', '举', '之前', '就', '题材', '问题', '编辑', '仔细', '商讨', '过', '感觉', '什么', '但', '没想到', '今年', '文革', '三十周年', '这', '事儿', '单行本', '一时', '出', '不了', '只能', '这样', '其实', '本书', '不是', '内容', '在', '其中', '只', '占', '不到', '十分之一', '却是', '一个', '漂荡', '故事', '中', '挥之不去', '精神', '幽灵',...... '虽', '球状', '闪电', '续集', '可以', '看做', '那个', '所', '发生', '世界', '其后', '延续', '物理学家', '出现', '已', '不', '重要', '其他', '人', '则', '永远', '消失', '林云', '真的', '死', '虽然', '我', '有时', '想', '如果', '她', '活', '下来', '最后', '是不是', '这个', '主人公', '样子', '这是', '暂', '名为', '地球', '往事', '系列', '第一部', '更长', '开始', '关于', '背叛', '生存', '死亡', '有时候', '比起', '还是', '忠诚', '可能', '更是', '疯狂', '偏执'])

5.1.3 打印词语与频数对

#打印词语与出现次数数据
print(fdist.items())
dict_items([('刘慈欣', 11), ('三体', 841), ('终于', 110), ('能', 897), ('与', 1349), ('科幻', 54), ('朋友', 24), ('们', 309), ('见面', 16), ('了', 10167), ('用', 644), ('连载', 3), ('的', 36268), ('方式', 103), ('事先', 2), ('谁', 234), ('都', 2951)........('没有', 2128), ('想到', 153), ('也', 2671), ('是', 7110), ('无奈', 7), ('之', 106), ('举', 12), ('之前', 138), ('就', 2233), ('题材', 3), ('问题', 318), ('编辑', 3), ('仔细', 41), ('商讨', 1), ('过', 695), ('感觉', 468), ('什么', 1177), ('但', 2670), ('没想到', 22), ('今年', 6), ('文革', 22), ('三十周年', 1), ('这', 2911), ('事儿', 85), ('单行本', 1), ('一时', 36), ('出', 359), ('不了', 58), ('只能', 325)】)

5.1.4 词语总数

#打印词语总数
print(fdist.N())
457899

5.1.5 打印出现次数最多的词语

print(fdist.max())

5.1.6 输出某个词的出现次数

print(fdist['三体'])841

5.1.7 计算词频

#计算词频
print(fdist.freq('三体'))
0.0018366495668258721

5.1.8 绘制前20个词频数累计图

#总词数45万,前20个词占据了总量的近25%
fdist.plot(20,cumulative=True)

TablesAre
fdist = FreqDist(wordlist)将wordlist化为FreqDist对象
fdist.inc(wordlist2)增加新数据
fdist['monstrous']'monstrous'的频数
fdist.freq('monstrous')'monstrous'的频率
fdist.N()wordlist中词语总数
fdist.keys()wordlist中的词语列表
fdist.max()wordlist中出现次数最多的词语
fdist.plot()绘制频数分布图

5.2 ConditionFreqDist类

带条件的频率分布类

条件和事件 频率分布计算观察到的事件,如文本中出现的词汇。条件频率分布需要事件关联一个条件,所以不是处理一个词序列,而是配对的序列。

text = ['The', 'Fulton', 'County', 'Grand', 'Jury', 'said', ...]
pairs = [('news', 'The'), ('news', 'Fulton'), ('news', 'County'), ...]

每对的形式:(条件,事件)。


from nltk.probability import ConditionalFreqDist

import re
import jieba

def text_split(file):    """    对文本进行分词,返回分词后的列表    """    novel_data = open(file).read()
   cleaned_data = ''.join(re.findall(r'[\u4e00-\u9fa5]', novel_data))    
   wordlist = jieba.lcut(cleaned_data)    return wordlist texts = ['体育.txt','财经.txt','新闻.txt','科技.txt']

cfd = ConditionalFreqDist(     (text,len(word))     for text in texts    
    for word in text_split(text))

#计算前10大词在各类文本中的频数
cfd.tabulate(conditions=['体育.txt','财经.txt','新闻.txt','科技.txt'],samples=range(10))

六、文本分类之朴素贝叶斯

这里使用nltk提供的数据 male.txt female.txt做为训练出一个模型,输入一个名字,预测一个人名的性别。

训练模型需要使用特征,这里我们假定使用名字最后一个字母作为特征。这里类比一下,比如中文中出现"亭"/"芳",很大的可能性是女名。而“国”、“帅”、"凯"极大的可能性是男名。

import randomfrom nltk import NaiveBayesClassifier

#读取名字数据
def gender_data(file):    names = []    for line in open(file).readlines():        name = line.strip()        names.append(name)    return names

#这里({name:True},'male')({name:True},'female'),nltk内部的NaiveBayesClassifier我还没研究,所以这里只能将就
males = [({name[-1]:True},'male')
        for name in gender_data(file='names/male.txt')]

females = [({name[-1]:True},'female')
          for name in gender_data(file='names/female.txt')]

names = (males+females)#打乱顺序random.shuffle(names)

#特征集
featuresets = [(name,gender) for (name,gender) in names]

#将特征集分为训练集和测试集
train_set, test_set = featuresets[500:],featuresets[:500]

#使用训练集训练分类器
classifier = NaiveBayesClassifier.train(train_set)
print(classifier.classify({'David'[-1]:True}))
print(classifier.classify({'Mike'[-1]:True}))
print(classifier.classify({'Lucy'[-1]:True}))
print(classifier.classify({'Adelina[-1]':True}))


#分类器准确性
print(nltk.classify.accuracy(classifier, test_set))
male male female female 0.748

分类器的准确率达到0.748,还是挺不错的哦。


历史文章:

数据采集

selenium驱动器配置详解

icrawler:强大简单的图片爬虫库

抓取单博主的所有微博及其评论

爬虫神器PyQuery的使用方法

pyquery一些自定义的用法

【视频】猫途鹰网站评论数据抓取

【视频讲解】在scrapy框架中如何使用selenium?

【实战视频】使用scrapy写爬虫-爬知乎live

简易SQLite3数据库学习

【视频教程】对视频进行基本操作

【视频】抓包小练习-B站评论数据抓取

fake-useragent库:值得花2分钟学习的库

【视频】爬取饿了么平台上的门店信息

如何抓取视频资源-以头条视频为例

当爬虫遭遇验证码,怎么办

【视频】手把手教你抓美女~

【视频】有了selenium,小白也可以自豪的说:“去TMD的抓包、cookie”

【视频】快来get新技能--抓包+cookie,爬微博不再是梦

【视频教程】用python批量抓取简书用户信息

识别假货有绝招,就用python爬淘宝评论

用Python抓取百度地图里的店名,地址和联系方式

文本处理分析

gensim:用Word2Vec进行文本分析

Python NLP中的五大英雄

用SenticNet库做细粒度情感分析

如何对csv文件中的文本数据进行分析处理

复杂网络分析数据准备篇

文本分析之网络关系

用词云图解读“于欢案”

基于共现发现人物关系的python实现

用pyecharts制作词云图

RAKE:快速自动抽取关键词算法

图片数据处理

OpenCV:快速入门图片人脸识别

好玩的OpenCV:图片操作的基本知识(1)

好玩的OpenCV:图像操作的基本知识(2)

OpenCV:计算图片有多色

如何对数据进行各种排序?

其他

【视频】初学者必看:python环境配置

开扒皮自己微信的秘密

初识装饰器函数

计算运行时间-装饰器实现

花十分钟,给爱机安装个MongoDB

chardet库:轻松识别文件的编码格式

使用Python登录QQ邮箱发送QQ邮件

WTF Python: 开启你的懵逼模式

8行代码实现微信聊天机器人

WTF Python: 开启你的懵逼模式

WTF Python:开启懵逼模式第二弹

使用Python+OpenCV进行面部合成

十分钟学会用Flask发邮件


迅雷不给力,我DIY了个下载器



项目下载 

链接: https://pan.baidu.com/s/1slof6Df 密码: 2rq8

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存