Python NLTK的学习(一)

0.前言

前面一段时间随着断断续续的的学习过一段时间的NLTK包的使用,但是都是用到啥学啥。现在打算删除写的这部分内容,根据参考书重新进行系统的整理、学习。

参考书:Python 自然语言处理, StevenBird, EwanKlein 和 EdwardLoper。版权所有 2009 Steven Bird, Ewan Klein 和 Edward Loper, 978-0-596-51649-9。”


1.语言处理与python

1.1 语言计算:文本和单词

相信,即使小白如我,此刻也安装好了python,至少也是可以输入helloworld的人。那就足够了。

然后就是安装NLTK ,也是非常的简单:

pip install nltk

就可以完成安装,如果按照失败,说明网络有问题,不够快,换个时间再来一次就可以了。

1.1.1 用nltk.book 库练习

from nltk.book import*

通过上述命令,我们可以加载到NLTK提供的9本书

1.1.1.1搜索文本

即通过各种方式对文本的一种查找和定位。

我们可以通过concordance方法,获得某一个词语在指定文本的上下文信息。

text1.concordance('monstrous')

也可以通过similar方法得到出现在相同上下文的词语

text1.similar('monstrous')

更可以使用common_contexts寻找两个或两个以上词语共同的上下文。

text2.common_contexts(['monstrous','very'])
--返回结果形式
a_pretty am_glad a_lucky is_pretty be_glad

可以使用dispersion_plot来获得词在文本中的位置,每一条竖线代表一个单词,

%matplotlib inline
text4.dispersion_plot(["citizens", "democracy", "freedom", "duties", "America"])

这是美国总统就职演说的文章首尾相连形成的语料,通过下面的结果图形我们可以发现词语的历时使用频率的变化。
在这里插入图片描述
书中提供的生成随机文本的generate功能已经被注释了,新的版本的NLTK已经无法使用。我的版本是nltk: 3.3

text3.generate()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-463eb7c367ab> in <module>
----> 1 text3.generate()

TypeError: generate() missing 1 required positional argument: 'words'
1.1.1.2 词汇计数

这一部分就是用各种各样的方法来对词汇进行计数,毕竟语言处理,定量是很重要的一部分。

和python本身对文本处理的方法一致
len(text3)#文本的计数
len(set(text3))#文本词汇数量
len(text3)/len(set(text3))#词汇丰富度
text3.count('day')#特定词汇的计数
text3.count('day')/len(text3)#词频

1.2 python:将文本当作词链表(list)

1.2.1 链表/列表/list

把文本中的每一个词语或标点都当作是列表中的一个元素,一篇文本也就是一个列表。

sent1 = ['Call', 'me', 'Ishmael', '.']

nltk中对于文本列表的操作和python内置的一样(或也许就是一回事,不懂这个)。

  • 我们可以对文本列表进行连接和追加
  • 我们可以找到某个词语的索引和找到某个索引对应的词语或符号
  • 我们可以对文本进行任意的切片获取语言片段
  • 我们可以对文本指定位置进行修改

1.2.2 变量

说实话,对于变量的概念,小白的我仅仅是浮于表面,我理解的变量就是名字。指代了一些东西。变量的背后是什么,变量的基础又是什么,还不清楚。但是,仅仅是用于目前我的需要来看,不是什么大的问题。深入的了解,可以放到以后。

1.2.3 字符串

用法其实类似于列表

1.3 语言计算:简单的统计

统计可以让我们发现一个文本于另一个文本不同的地方,甚至是原因。

1.3.1 频率统计

NLTK内置函数,FreaDist可以直接使用,返回文本中最常见(频率最高)的词。当然这个功能我们也可以自己直接实现,通过定义字典。

fdist1=FreqDist(text1)
fdist1['whale']#查询某个词的频率
vocabulary1=list(fdist1.keys())
print(vocabulary1[:50])#输出词汇表前50,结果很怪,可能是版本更新的问题,不好用
fdist1.plot(,cumulative=True)#可以显示词语的累积频率图
fdist1.hapaxes()#可以查询只出现一次的词语

在这里插入图片描述

1.3.2 细粒度的选择词

我们可以根据所需要的词语从文本中进行细致的选择。比如下面的就是选择文本中长度大于15的单词

V=set(text1)
long_words=[w for w in V if len(w)>15]
sorted(long_words)

又或者查询长度大于7,频率大于7的词语:

fdist5=FreqDist(text5)
sorted([w for w in set(text5) if len(w)>7 and fdist5[w]>7])

这个用法与python本身内置的好像没啥区别

1.3.3 词语搭配和双连词

也就是寻得文本中经常互相出现的词语,NLTK提供了两种,一种是函数bigrams(),

list(bigrams(['i','am','a','teacher']))
--函数本身生成的是generator对象,将其转换为列表即可直观看到结果
[('i', 'am'), ('am', 'a'), ('a', 'teacher')]

这种方式生成的词语是基于单个词进行生成的。
另外提供了一种可以直接获取高频双连词的函数:collocations()

text4.collocations()
United States; fellow citizens; four years; years ago; Federal
Government; General Government; American people; Vice President; God
bless; Chief Justice; Old World; Almighty God; Fellow citizens; Chief
Magistrate; every citizen; one another; fellow Americans; Indian
tribes; public debt; foreign nations

也可以对文本的词语的词长的分布进行统计,也就是综合使用上面的方法,将统计词语变成统计词语的长度。
还可以对词语的其他细节,比如首尾标志等进性统计

len([w for w in text1 if w.endswith('a')])

1.5 NLTK眼中的NLP全景图

  • 词义消歧
  • 指代消解
  • 自动问答
  • 机器翻译
  • 人机对话
  • 情感分析
#nltk.chat.chatbots()#死循环,网上查到说是可能把回车作为输入值导入死循环了
nltk.chat.zen_chat()#可以直接调用想要聊天的几种类型就可以使用

第一章课后练习

  1. ○尝试使用 Python 解释器作为一个计算器,输入表达式,如 12/(4+1)。
t=12/(4-1)
  1. ○26 个字母可以组成 26 的 10 次方或者 26**10 个 10 字母长的字符串。 也就是 1411
    67095653376L(结尾处的 L 只是表示这是 Python 长数字格式)。 100 个字母长度的
    字符串可能有多少个?
length_=100**10
  1. ○Python 乘法运算可应用于链表。当你输入[‘Monty’, ‘Python’] * 20 或者 3 * se
    nt1 会发生什么?
>>> ['Monty','Python']*20
['Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python', 'Monty', 'Python']
  1. ○复习 1.1 节关于语言计算的内容。在 text2 中有多少个词?有多少个不同的词?
len(text2)
set(text2)
  1. ○比较表格 1-1 中幽默和言情小说的词汇多样性得分,哪一个文体中词汇更丰富?
这个直接比较结果就行
  1. ○制作《理智与情感》 中四个主角: Elinor, Marianne, Edward 和 Willoughby 的分布图。
    在这部小说中关于男性和女性所扮演的不同角色, 你能观察到什么?你能找出一对夫妻
    吗?
这里其实就是找词汇的分布图
%matplotlib inline
text4.dispersion_plot(["citizens", "democracy", "freedom", "duties", "America"])
#将前面例子的词语改下就可以
  1. ○查找 text5 中的搭配。
text5.collocations()#双连词
  1. ○思考下面的 Python 表达式: len(set(text4))。 说明这个表达式的用途。 描述在执行
    此计算中涉及的两个步骤。
len(set(text4))
将文本4中的词汇进行去重
获得词汇数量
  1. ○复习 1.2 节关于链表和字符串的内容。
    a. 定义一个字符串, 并且将它分配给一个变量, 如: my_string = ‘My String’(在
    字符串中放一些更有趣的东西)。用两种方法输出这个变量的内容,一种是通过简
    单地输入变量的名称,然后按回车;另一种是通过使用 print 语句。
test='this is a test'
print(test)

b. 尝试使用 my_string+ my_string 或者用它乘以一个数将字符串添加到它自身,
例如: my_string* 3。 请注意, 连接在一起的字符串之间没有空格。 怎样能解决
这个问题?

>>> test='this is a test'
>>> tests=test*3
>>> tests
'this is a testthis is a testthis is a test'
>>> testss= (test+' ')*3
>>> testss
'this is a test this is a test this is a test '
  1. ○使用的语法 my_sent = [“My”, “sent”],定义一个词链表变量 my_sent(用你
    自己的词或喜欢的话)。
    a. 使用’ '.join(my_sent)将其转换成一个字符串。
>>> my_sent=['my','sent']
>>> my_newsent=''.join(my_sent)
>>> my_newsent
'mysent'

b. 使用 split()在你指定的地方将字符串分割回链表。

>>> my_back=my_newsent.split(('y'))
>>> my_back
['m', 'sent']
  1. ○定义几个包含词链表的变量,例如: phrase1, phrase2 等。将它们连接在一起组
    成不同的组合(使用加法运算符), 最终形成完整的句子。 len(phrase1 + phrase2)
    与 len(phrase1) + len(phrase2)之间的关系是什么?
>>> test1=['this','is','test1']
>>> test2=['this','is','test2']
>>> test3=test1+test2
>>> len(test3)
6
>>> len(test1)+len(test2)
6
  1. ○考虑下面两个具有相同值的表达式。哪一个在 NLP 中更常用?为什么?
    a. “Monty Python”[6:12]
    b. [“Monty”, “Python”][1]
不清楚大家怎么用,但是我会用第二个,在取元素的时候比较简单不容易出错
  1. ○我们已经看到如何用词链表表示一个句子, 其中每个词是一个字符序列。 sent1[2][2]
    代表什么意思?为什么?请用其他的索引值做实验。
>>> sent=['this','is','test2'][2][2]#取得第三个元素的第三个元素
>>> sent
's'
  1. ○在变量 sent3 中保存的是 text3 的第一句话。 在 sent3 中 the 的索引值是 1, 因为 s
    ent3[1]的值是“the”。 sent3 中“the” 的其它出现的索引值是多少?
>>> sent3
['In', 'the', 'beginning', 'God', 'created', 'the', 'heaven', 'and', 'the', 'earth', '.']
  1. ○复习 1.4 节讨论的条件语句。 在聊天语料库(text5) 中查找所有以字母 b 开头的词。
    按字母顺序显示出来。
word=sorted([w for w in text5 if w.startswith('b')])
  1. ○在 Python 解释器提示符下输入表达式 range(10)。 再尝试 range(10, 20), range
    (10, 20, 2)和 range(20, 10, -2)。在后续章节中我们将看到这个内置函数的多用
    用途。
0910192011,步长为2
  1. ◑使用 text9.index()查找词 sunset 的索引值。 你需要将这个词作为一个参数插入到圆
    括号之间。通过尝试和出错的过程中,找到完整的句子中包含这个词的切片。
>>> text9.index('sunset')
629
  1. ◑使用链表加法、 set 和 sorted 操作,计算句子 sent1…sent8 的词汇表。
>>> sents=sent1+sent2+sent3+sent4+sent5+sent6+sent7+sent8
>>> word=[w for w in sents]
>>> sorted(set(word))
['!', ',', '-', '.', '1', '25', '29', '61', ':', 'ARTHUR', 'Call', 'Citizens', 'Dashwood', 'Fellow', 'God', 'House', 'I', 'In', 'Ishmael', 'JOIN', 'KING', 'MALE', 'Nov.', 'PMing', 'Pierre', 'Representatives', 'SCENE', 'SEXY', 'Senate', 'Sussex', 'The', 'Vinken', 'Whoa', '[', ']', 'a', 'and', 'as', 'attrac', 'been', 'beginning', 'board', 'clop', 'created', 'director', 'discreet', 'earth', 'encounters', 'family', 'for', 'had', 'have', 'heaven', 'in', 'join', 'lady', 'lol', 'long', 'me', 'nonexecutive', 'of', 'old', 'older', 'people', 'problem', 'seeks', 'settled', 'single', 'the', 'there', 'to', 'will', 'wind', 'with', 'years']
  1. ◑下面两行之间的差异是什么?哪一个的值比较大?其他文本也是同样情况吗?
>>> sorted(set([w.lower() for w in text1]))
>>> sorted([w.lower() for w in set(text1)]
第二行内容更多
集合去重与全部小写的先后会影响数量
  1. ◑w.isupper()和 not w.islower()这两个测试之间的差异是什么?
>>> test='abc A-12BC'
>>> a=[w for w in test if w.isupper()]
>>> b=[w for w in test if  not w.islower()]
>>> a
['A', 'B', 'C']
>>> b
[' ', 'A', '-', '1', '2', 'B', 'C']
取值范围不同
  1. ◑写一个切片表达式提取 text2 中最后两个词。
text2[-3:]
  1. ◑找出聊天语料库( text5)中所有四个字母的词。使用频率分布函数( FreqDist),
    以频率从高到低显示这些词。
>>> word=[w for w in text5 if len(w)>4 ]
>>> word_fre=FreqDist(word)
>>> word_fre
FreqDist({'ACTION': 346, 'there': 120, 'wanna': 107, '.....': 73, 'hello': 71, 'about': 70, 'everyone': 63, 'where': 63, 'right': 54, 'think': 54, ...})
  1. ◑复习 1.4 节中条件循环的讨论。 使用 for 和 if 语句组合循环遍历《巨蟒和圣杯》( text6)的电影剧本中的词,输出所有的大写词,每行输出一个。
>>> word=[w for w in text6 if w.isupper()]
>>> word
  1. ◑写表达式找出 text6 中所有符合下列条件的词。结果应该是词链表的形式: [‘word1’, ‘word2’, …]。
    a. 以 ize 结尾
    b. 包含字母 z
    c. 包含字母序列 pt
    d. 除了首字母外是全部小写字母的词(即 titlecase)
a=[w for w in text6 if w.endswith('ize')]
b=[w for w in text6 if 'z' in w]
c=[w for w in text6 if 'pt' in w]
d=[w for w in text6 if w.istitle()]
  1. ◑定义 sent 为词链表[‘she’, ‘sells’, ‘sea’, ‘shells’, ‘by’, ‘the’, ‘sea’, ‘shore’]。
    编写代码执行以下任务:
    a. 输出所有 sh 开头的单词
    b. 输出所有长度超过 4 个字符的词
a=[w for w in sent if w.startswith('sh')]
b=[w for w in sent if len(w)>4]
  1. ◑下面的 Python 代码是做什么的? sum([len(w) for w in text1]),你可以用它来
    算出一个文本的平均字长吗?
sum([len(w) for w in text1])

  1. ◑定义一个名为 vocab_size(text)的函数, 以文本作为唯一的参数, 返回文本的词汇
    量。
def vocab_size(text):
	return [w for w in text]
  1. ◑定义一个函数 percent(word, text),计算一个给定的词在文本中出现的频率,结
    果以百分比表示。

  2. ◑我们一直在使用集合存储词汇表。 试试下面的 Python 表达式: set(sent3) < set(t53
    ext1)。实验在 set()中使用不同的参数。它是做什么用的?你能想到一个实际的应用

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值