《Python自然语言处理》练习1

时间:2021-10-30 06:29:14

通过前两次的学习,我自学了《Python自然语言处理》的第一章,现在把第一章课后题做一下,有兴趣的同学可以和我对下答案。目前打算就在Python自带的IDLE上练习。不会的话,再用eclipse找下灵感。(注:每个题目开头的小圆圈代表题目难度,越黑代表越难)

1. ○尝试使用Python 解释器作为一个计算器,输入表达式,如12/(4+1)。

在学习笔记(一)中我提到过一个方法:from __future__ import division

只要先输入这一行,之后的四则运算肯定就没问题了。其实这题关键就在浮点运算。


2. ○26 个字母可以组成26 的10 次方或者26**10 个10 字母长的字符串。也就是1411
67095653376L(结尾处的L 只是表示这是Python 长数字格式)。100 个字母长度的
字符串可能有多少个?

当然是26的100次方。不过这题的意图应该是让我用Python算出来吧。这个函数还真的忘了,用np.power(26,100),发现存储不了这么大的数。后来查了才发现要这样写:

>>> pow(26,100)
3142930641582938830174357788501626427282669988762475256374173175398995908420104023465432599069702289330964075081611719197835869803511992549376L


3. ○Python 乘法运算可应用于链表。当你输入['Monty', 'Python'] * 20 或者3 * se
nt1 会发生什么?

就分别复制20次和3次。

>>> ['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']
>>> 3*sent1
['Call', 'me', 'Ishmael', '.', 'Call', 'me', 'Ishmael', '.', 'Call', 'me', 'Ishmael', '.']


4. ○复习1.1 节关于语言计算的内容。在text2 中有多少个词?有多少个不同的词?

>>> len(text2)#词的个数
141576
>>> len(set(text2))#不同词的个数
6833


5. ○比较表格1-1 中幽默和言情小说的词汇多样性得分,哪一个文体中词汇更丰富?

浪漫小说的词汇多样性是8.3,而幽默只有4.3


6. ○制作《理智与情感》中四个主角:Elinor,Marianne,Edward 和Willoughby 的分布图。
在这部小说中关于男性和女性所扮演的不同角色,你能观察到什么?你能找出一对夫妻
吗?

>>> text2.dispersion_plot(['Elinor','Marianne','Edward','Willoughby'])

《Python自然语言处理》练习1
感觉Willoughby和Marianne是夫妻吧。

百度了一下,应该是猜对了,另外一对也是夫妻。


7. ○查找text5 中的搭配。

>>> text5.collocations()
wanna chat; PART JOIN; MODE #14-19teens; JOIN PART; PART PART;
cute.-ass MP3; MP3 player; JOIN JOIN; times .. .; ACTION watches; guys
wanna; song lasts; last night; ACTION sits; -...)...- S.M.R.; Lime
Player; Player 12%; dont know; lez gurls; long time


8. ○思考下面的Python 表达式:len(set(text4))。说明这个表达式的用途。描述在执行
此计算中涉及的两个步骤。

用来统计text4中不同单词的个数。set是集合的意思,用来去掉重复的单词。len是长度的意思,用来求长度。这个表达式的弊端是,把首字母大写和不大写的一个单词看作了两个单词。


9. ○复习1.2 节关于链表和字符串的内容。
a. 定义一个字符串,并且将它分配给一个变量,如:my_string = 'My String'(在
字符串中放一些更有趣的东西)。用两种方法输出这个变量的内容,一种是通过简
单地输入变量的名称,然后按回车;另一种是通过使用print 语句。

>>> me='beautiful'
>>> me
'beautiful'
>>> print me
beautiful

发现这两种输出是不一样的。第一次是以字符串的形式输出,第二次就只是单纯输出内容。


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

>>> me+me
'beautifulbeautiful'
>>> me*3
'beautifulbeautifulbeautiful'

解决没有空格的问题:

>>> ' '.join([me,me])
'beautiful beautiful'

>>> ' '.join([me]*3)
'beautiful beautiful beautiful'


10. ○使用的语法my_sent = ["My", "sent"],定义一个词链表变量my_sent(用你
自己的词或喜欢的话)。

>>> compliment=['I','am','a','wonderful','person','.']
>>> compliment
['I', 'am', 'a', 'wonderful', 'person', '.']

a. 使用' '.join(my_sent)将其转换成一个字符串。

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

>>> ' '.join(compliment)
'I am a wonderful person .'
>>> s=' '.join(compliment)
>>> s.split()
['I', 'am', 'a', 'wonderful', 'person', '.']


11. ○定义几个包含词链表的变量,例如:phrase1,phrase2 等。将它们连接在一起组
成不同的组合(使用加法运算符),最终形成完整的句子。len(phrase1 + phrase2)
与len(phrase1) + len(phrase2)之间的关系是什么?

>>> p=['Have','a','try','!']
>>> p
['Have', 'a', 'try', '!']
>>> compliment+p
['I', 'am', 'a', 'wonderful', 'person', '.', 'Have', 'a', 'try', '!']
>>> len(compliment)+len(p)
10
>>> len(compliment+p)
10

是相等的。


12. ○考虑下面两个具有相同值的表达式。哪一个在NLP 中更常用?为什么?
a. "Monty Python"[6:12]
b. ["Monty", "Python"][1]

b更常用。因为代码数量少,也不容易出错。


13. ○我们已经看到如何用词链表表示一个句子,其中每个词是一个字符序列。sent1[2][2]
代表什么意思?为什么?请用其他的索引值做实验

>>> sent1[2][2]

'h'

代表下标为2的单词的下标为2的字母。(第三个单词的第三个字母)


14. ○在变量sent3 中保存的是text3 的第一句话。在sent3 中the 的索引值是1,因为s
ent3[1]的值是“the”。sent3 中“the”的其它出现的索引值是多少?

>>> for i in range(0,len(sent3)):
if sent3[i]=='the':
print i



1
5
8


15. ○复习1.4 节讨论的条件语句。在聊天语料库(text5)中查找所有以字母b 开头的词。
按字母顺序显示出来。

>>> sorted([w for w in set(text5) if w.startswith('b')])

结果太多,就不展示了。


16. ○在Python 解释器提示符下输入表达式range(10)。再尝试range(10, 20), range
(10, 20, 2)和range(20, 10, -2)。在后续章节中我们将看到这个内置函数的多用
用途。

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(10,20)
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> range(10,20,2)
[10, 12, 14, 16, 18]

>>> range(20,10,-2)
[20, 18, 16, 14, 12]


17. .使用text9.index()查找词sunset 的索引值。你需要将这个词作为一个参数插入到圆
括号之间。通过尝试和出错的过程中,找到完整的句子中包含这个词的切片。

>>> text9.index('sunset')#第一个sunset出现的索引
629

>>> text9.concordance('sunset')

结果就不展示了。


18. .使用链表加法、set 和sorted 操作,计算句子sent1...sent8 的词汇表。

>>> words=sorted(set(sent1+sent2+sent3+sent4+sent5+sent6+sent7+sent8+sent9))


19. .下面两行之间的差异是什么?哪一个的值比较大?其他文本也是同样情况吗?
>>> sorted(set([w.lower() for w in text1]))
>>> sorted([w.lower() for w in set(text1)]

第二种写法会有重复的词。所有文本都是这样的。


20. .w.isupper()和not w.islower()这两个测试之间的差异是什么?

第一种是测试w中所有字符是否都是大写字母,第二种是测试w中所有字符是否都不是小写字符。


21. .写一个切片表达式提取text2 中最后两个词。

>>> text2[-2:]
[u'THE', u'END']


22. .找出聊天语料库(text5)中所有四个字母的词。使用频率分布函数(FreqDist),
以频率从高到低显示这些词。

>>> fdist54=FreqDist(w for w in text5 if len(w)==4)
>>> fdist54
FreqDist({u'JOIN': 1021, u'PART': 1016, u'that': 274, u'what': 183, u'here': 181, u'....': 170, u'have': 164, u'like': 156, u'with': 152, u'chat': 142, ...})


23. .复习1.4 节中条件循环的讨论。使用for 和if 语句组合循环遍历《巨蟒和圣杯》(tex
t6)的电影剧本中的词,输出所有的大写词,每行输出一个。

>>> for w in set(text6):
if w.isupper():
print w

结果不展示了不展示了==。


24. .写表达式找出text6 中所有符合下列条件的词。结果应该是词链表的形式:['word
1', 'word2', ...]。
a. 以ize 结尾 >>> w1=[w for w in set(text6) if w.endswith('ize')]
b. 包含字母z >>> w2=[w for w in set(text6) if 'z' in w]
c. 包含字母序列pt >>> w3=[w for w in set(text6) if 'pt' in w]
d. 除了首字母外是全部小写字母的词(即titlecase)>>> w4=[w for w in set(text6) if w.istitle()]


25. .定义sent 为词链表['she', 'sells', 'sea', 'shells', 'by', 'the', 'sea', 'shore']。
编写代码执行以下任务:
a. 输出所有sh 开头的单词
b. 输出所有长度超过4 个字符的词

>>> sent=['she','sells','sea','shells','by','the','sea','shore']
>>> [w for w in sent if w.startswith('sh')]
['she', 'shells', 'shore']
>>> [w for w in sent if len(w)>4]
['sells', 'shells', 'shore']


26. .下面的Python 代码是做什么的?sum([len(w) for w in text1]),你可以用它来
算出一个文本的平均字长吗?

text1中,所有词的长度的和。

平均长度:

>>> s=sum([len(w)for w in text1])
>>> from __future__ import division
>>> s/len(text1)
3.830411128023649

这里要注意浮点运算。


27. .定义一个名为vocab_size(text)的函数,以文本作为唯一的参数,返回文本的词汇
量。

>>> def vocab_size(text):
return len(set([w.lower() for w in text if w.isalpha()]))


>>> vocab_size(text1)
16948


28. .定义一个函数percent(word, text),计算一个给定的词在文本中出现的频率,结
果以百分比表示。

>>> def percent(word,text):
fd=FreqDist(text)
return 1.0*fd[word]/len(text)


>>> percent('love',text2)
0.0005438774933604566


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

吗?

比较两个text的词汇量。

比较不同种类文本词汇量的大小。