NLTK

读书笔记:NLTK基础教程——用NLTK和Python库构建机器学习应用。

书目

扩展阅读

NLP入门(前几章)
《Speech and Language Processing》,由Daniel Jurafsky与James H. Martin合著。
《Statistical Natural Language Processing》,由Christopher D. Manning与Hinrich Schütze合著
维基百科上与NLP相关的页面。https://en.wikipedia.org/wiki/NLP

残留

help()是不是只能用于str和list。
答:否。dir(dict)以及import后再help。

NLTK 库是当前自然语言处理(NLP)领域最为流行、使用最为广泛的库之一, 同时Python语言也已逐渐成为主流的编程语言之一。
关于这个问题,我们可以先来看看Gartner公司新一轮的趋势报告,你可以很清晰地看到,NLP技术赫然高居榜首。目前,NLP已被认为是业界最为稀缺的技能之一。
列表(list)是Python中最常用的数据结构之一。它们基本上相当于其他编程语言中的数组。
字典(dictionary)也是最常用到的数据结构之一。在其他编程语言中有时也被称为关联数组/存储。
字符串操作同时也是Python最主要的特性之一。

  • 在Python中,处理字符串会是一件非常轻松的工作。即使是那些非常简单的操作,例如字符串的切割,你也会看到相较于Java和C的大费周章,它在Python中是多么得简单明了。

    练级

    兴趣读者、爱好者、资深程序员、领域的研究人员、数据科学家。掌握一些NLP技能的人员。

    掌握技能

    理论:快速了解与一定的兴趣

    编程语言、NLTK、NLP和语言学
    python:基础教程、快速概览、快速浏览一下Python的基础要点(基础性的快速回顾之旅)、不同主题的Python的一些特性。基本的Python知识,如列表、字符串、正则表达式以及基本的I/O操作。
    help and dir 列表
    数据结构的基本知识,常用函数,Python通用结构。
    对NLP爱好者来说,正则表达式是另一个非常重要的技能。
    NLP:背景知识、相关概念、实用方面

    在NLP领域以及使用Python编程方面具有一定的背景知识
    与Python和NLP相关的快速入门
    详细地了解Python这门语言
    NLP相关的基本概念
    与处理自然语言相关的特性
    基本的NLP预处理步骤

    实践

    如何安装所需要的库。完成Python和NLTK及其他库的安装。安装了所有在NLTK工作中将会用到的程序。
    pip install BeautifulSoup4 –user
    演示了NLTK的使用思路
    编写一些非常基本的Python和NLTK代码片段。能编写并运行基本的Python程序。
    自行构建出一个能实际运行的、涉及云词的小型应用程序。
    开始构建一个非常基本的单词云实例。能顺利地产生出云词。
    如何构建一些NLP应用。构建出大部分与数据科学相关问题的单点解决方案。
    围绕着NLTK构建起所需要的一切,并让Python在我们的系统上顺利地工作。

    实例

    探索性数据分析(EDA)。
    通常对于一段文本域而言,EDA可能包含了多重含义。
    文档的主体术语类型是其中的一个简单用例。
    主题是什么?
    它们的出现频率如何?
    整个分析过程还会或多或少地涉及一些预处理层面的步骤。
    试着先用纯Python的方式来实现它,然后用NLTK再将其实现一次。
    清理掉html标签。
    一种可行的做法是只选取其中的标记,包括数字和字符。
    正则表达式可以轻松地将这些html字符串转换成一个标记列表。

分类

NLTK、文本处理、NLP、机器学习、数据科学领域
信息检索、分布式处理、本体开发、自然语言处理和机器学习
NLTK库与Python库。其他的Python库,你应该了解一下这些与文本挖掘或自然语言处理任务相关的库。
NLP任务和机器学习应用
通用的预处理技术、专属于NLP领域的预处理技术以及命名实体识别技术
文本分类、数据科学和数据处理、社交媒体挖掘和大规模文本挖掘
标识化处理、语块分解、词性标注、语法解析、机器翻译及语音识别
语言处理及大型非结构化数据
一些相关特定能力的Python库,如NLTK、scikit-learn、panda和NumPy
基础数据科学、机器学习起步
文本分析、网页抓取及检索、人力资源分析、虚拟系统的性能优化,以及气候变化的预测
路径名、文件夹名、文件名、文件扩展名、伪URL
数据库表名
用户输入以及Twitter句柄、代码

1
2
3
4
5
6
7
8
9
10
11
12
13
文本的歧义及其清理
通用的预处理技术。在任何文本挖掘和NLP任务中所需的所有预处理步骤。
断词处理、词干处理、停用词去除。
例如标识化处理(tokenization)、词干提取(stemming)、停用词(stop word)去除;
本清理技术,如何用NLTK来简化它们的实现。
专属于NPL领域的预处理技术等,
如词性标注(part-of-speech tagging);以及大多数文本相关的NLP任务都会涉及的命名实体识别(Named-entity recognition,简称NER)等技术。
更为复杂的NLP任务上,例如语法解析(parsing)以及其他NLP应用。
NLP应用:
如何进行文本分类,可以用NLTK搭配scikit-learn库来进行。
如何从网页和社交媒体中采集数据
如何用NLTK进行大规模的文本处理
自然语言处理简介

词条

解释型编程语言,会在对其表达式进行计算的同时检查其中的变量类型。在声明变量时无需对其进行初始化和类型声明。例如:Python。
对语言有深入研究的人通常被叫作语言学家。
而“计算机语言学家”这个专用名词则指的是将计算机科学应用于语言处理领域的人。
因此从本质上来说,一个计算机语言学家应该既有足够的语言理解能力,同时还可以用其计算机技能来模拟出语言的不同方面。
虽然计算机语言学家主要研究的是语言处理理论,但NLP无疑是对计算机语言学的具体应用。

字典

字典是一种键值索引型的数据结构,其索引键可以是任意一种不可变的类型,例如字符串和数字都经常被用来充当索引键。
字典是被多种编程语言广泛用于实现诸多算法的一种非常便利的数据结构。
而且,Python的字典结构还是所有的这些编程语言中最为优雅的哈希表实现之一。

哈希表

哈希表是一种操作起来非常容易的字典结构,其优势在于,你只需通过寥寥几段代码就可以用它建立起一个非常复杂的数据结构。

函数

而所有类似于其他编程语言中的参数和参数类型的声明都会被放在该括号内。Python也有自己的函数编写方式。
从大型程序的编写实践来说,使用函数/类和某种成熟的编程范式是一个更佳的做法。

1
def <函数名>():

在Python中,
函数的定义通常会从关键字def开始,
后面紧跟着相应的函数名和括号()。
实际代码部分将会从冒号(:)后面开始,
代码的初始行通常会是一个文档字符串(注释),
接着是代码的主体部分,
最后我们会以一个return语句来结束整个函数。

NLP

在英语环境中,语言处理研究这一领域通常被简称为NLP。
NLP多数情况下指的是计算机上各种大同小异的语言处理应用,以及用NLP技术所构建的实际应用程序。
在实践中,NLP与教孩子学语言的过程非常类似。
其大多数任务(如对单词、语句的理解,形成语法和结构都正确的语句等)对于人类而言都是非常自然的能力。
但对于NLP来说,其中有一些任务就必须要转向文本分析
等这些领域的一部分,且这些任务有一大部分还仍是当前计算机领域中非常棘手的挑战。
自大数据的概念问世之后,我们所面对的主要挑战是——业界需要越来越多不仅能处理结构化数据,同时也能处理半结构化或非结构化数据的人才。
对于我们所生产出来的那些博客、微博、Facebook订阅、聊天信息、E-mail以及网络评论等,各公司都在致力于收集所有不同种类的数据,以便建立更好的客户针对性,形成有意义的见解。
而要想处理所有的这些非结构化数据源,我们就需要掌握一些NLP技能的人员。

NLP工具清单

这些工具有些是由相关组织在建立自己的NLP应用时开发的,而有些则纯粹属于开源项目:
GATE。
Mallet。
Open NLP。
UIMA。
Stanford toolkit。
Genism。
Natural Language Tool Kit (NLTK)
上述大多数工具都是用Java编写的,在功能上也都很相似。强大实用。

现实应用

拼写校正(MS Word/其他编辑器)
搜索引擎(Google、Bing、Yahoo!、WolframAlpha)。
语音引擎(Siri、Google Voice)。
垃圾邮件分类(所有电子邮件服务)。垃圾过滤器来过滤垃圾邮件
新闻订阅(Google、Yahoo!等)。
机器翻译(Google翻译与其他类似服务)。
IBM Watson
最基本的事情用到Siri

image.png

停用词

无用词。由于冠词、代词在大多数文档中都是普遍存在的,因而对信息的识别没有帮助。
a an the
of for =
在大多数NLP及信息检索任务中,人们通常都会先删除掉这些停用词。

NLTK

NLTK的设计充分体现了简单的魅力。也就是说,对于大多数复杂的NLP任务,它都可以用寥寥几行代码来实现。
NLTK:易用性(NLTK库是一个非常易学的工具包)和其对相关概念的解释度。
这得益于Python本身非常平缓的学习曲线(毕竟NLTK是用它编写的),人们学习起来会非常快。
NLTK库中收纳了NLP领域中的绝大部分任务,它们都被实现得非常优雅,且易于使用。
正是出于上述的这些原因,NLTK如今已成为了NLP社区最流行的库之一。

图灵测试

图灵测试关注的是人机对话能力,换句话说,什么时候机器能通过对话骗到你的一百块钱,也比它下棋下赢世界冠军更智能点。而想要增强人机对话能力,自然语言处理就是首当其冲的一个领域了。正如我们所说,机器的专长是数学领域,所以自然语言处理问题的目的就是要把我们人类的文本、音频转换成可被分析的数学模型,这对于机器来说是比围棋困难得多的事情。这也是人类和机器的根本区别,对于这两种智能来说,困难的定义是截然不同的。

人物

Nitin Hardeniya

Nitin Hardeniya数据科学家,拥有4年以上从业经验,期间分别任职于Fidelity、Groupon和[24]7等公司,其业务横跨各个不同的领域。此外,他还拥有IIIT-H的计算语言学硕士学位,并且是5项客户体验专利的作者。
他热衷于研究语言处理及大型非结构化数据,至少拥有5年日常使用Python的工作经验。他相信,用Python可以构建出大部分与数据科学相关问题的单点解决方案。
他将自己写这本书的经历看成是自己职业生涯的众多荣誉之一,希望用一种非常简单的形式为人们介绍与NLP和机器学习相关的、所有的这些复杂工具。在这本书中,他为读者提供了一种变通方法,即使用一些相关特定能力的Python库,如NLTK、scikit-learn、panda和NumPy等。
《NLTK基础教程——用NLTK和Python库构建机器学习应用》作者

其他

审阅者简介Afroz Hussain数据科学家,目前在PredictifyMe公司从事与美国基础数据科学、机器学习起步相关的研究。他在数据科学领域拥有丰富的项目经验、多年使用Python、scikit-learn,以及基于NLTK进行文本挖掘的工作经历。他拥有10年以上的编程经验以及与数据分析和商业智能项目相关的软件开发经验。此外,他还通过在线课程以及参加Kaggle比赛等活动,获得了不少数据科学领域的新技能。
Sujit Pal目前就职于[[Elsevier实验室]],这是一个包含了[[Reed-Elsevier PLC工作组]]在内的研发团队。他的兴趣主要集中在信息检索、分布式处理、本体开发、自然语言处理和机器学习这几个领域。而且,他也很喜欢用Python、Scala和Java来编写自己的代码。他充分整合了自己在这些方面的技能,帮助公司改进了不同产品的一些特性并构建了一些新特性。他深信自己需要终身学习,并且也在博客:sujitpal.blogspot.com中分享其经验。
Kumar Raj第二代数据科学家,目前就职于惠普软件的研发部门,为其提供相关的解决方案。在那里,他主要负责开发以惠普软件产品为核心的分析层。他毕业于印度理工学院Kharagpur技术分校,并具有两年以上各种大数据分析领域的工作经验,涉及文本分析、网页抓取及检索、人力资源分析、虚拟系统的性能优化,以及气候变化的预测等

需要累积

N年使用Python的工作经验经历
在数据科学领域拥有丰富的项目经验
编程经验
数据分析和商业智能项目相关的软件开发经验
充分整合了自己的技能
帮助公司改进了不同产品的一些特性并构建了一些新特性

社会现象

说来也凑巧,在我签下这本书的翻译合同时,这个世界好像还不知道AlphaGo的存在。而在我完成这本书的翻译之时,Master已经对人类顶级高手连胜60局了。至少从媒体的热度来看,的确在近几年,人工智能似乎是越来越火了。其原因是Google在汽车驾驶和围棋这两个领域的项目得到了很好的进展和宣传,而这两个领域在过去被很多人想当然地认为是人类的专属领域。因此在专属领域接连被突破情况下,一些人得了“机器恐惧症”。例如高晓松先生的这段微博:

@高晓松  作为自幼学棋,崇拜国手的业余棋手,看了Master50 : 0横扫中日韩顶尖高手的对局,难过极了。为所有的大国手伤心,路已经走完了。多少代大师上下求索,求道求术,全被破解。未来一个八岁少年只要一部手机就可以战胜九段,荣誉信仰灰飞烟灭。等有一天,机器做出了所有的音乐和诗歌,我们的路也会走完。 1月4日 16:21 来自 iPhone 7 Plus
其实之所以会有这样恐惧,大部分是因为人们在讨论人工智能的时候容易将机器“人格化”,很多科幻作品就是这么干的,这看起来很合理,但问题是机器无论如何都不是人。对于机器来说,围棋说穿了不过是一种基于统计学概率的决策模型,属于数学领域的问题,它本来就是机器的强项。用围棋对于人类的难度来推导机器智能的进步,其实是很没有逻辑的事情。而且事实上,今天所流行的这些人工智能方法都是在20世纪70年代前后提出的理论,今天的辉煌主要是由于硬件的进步为实现提供了基础,但在智能上并没有多大的实质突破。要知道,人们对于鉴定人工智能的主要标准早有定论,那就是图灵测试

套话

众所周知,语言是人们日常生活的核心部分,任何与语言问题相关的工作都会显得非常有意思。希望这本书能带你领略到NLP的风采,并引起学习NLP的兴趣。首先,我们需要来了解一下该领域中的一些令人惊叹的概念,并在工作中实际尝试一些具有挑战性的NLP应用。
身处信息时代,我们甚至不能想象生活中没有Google会是什么样子。
在这里,我们可以再列举一些令人惊叹的NLP应用实例。
构建上述这些应用都需要非常具体的技能,需要优秀的语言理解能力和能有效处理这些语言的工具。因此,这些不仅是各NLP最具优势领域的未来趋势,同时也是我们用NLP这种最独特技能所能创建的应用种类

词频统计

1
2
3
4
5
6
7
8
9
10
str1='Hello Python. I like Python.'
word_freq={}
for tok in str1.split():
if tok in word_freq:
word_freq[tok]+=1
else:
word_freq[tok]=1
print(word_freq)
>>>
{'Hello': 1, 'Python.': 2, 'I': 1, 'like': 1}

要点:

for tok in str1.split(): 注意in 后面接了个返回列表的函数。
if tok in word_freq: 键是如何作用于字典的。
word_freq[tok]+=1 字典是如何用键操作值的。

函数式统计词频

1
2
3
4
5
6
7
8
9
10
11
12
13
def wordfreq(str1):
word_freq={}
for tok in str1.split():
if tok in word_freq:
word_freq[tok]+=1
else:
word_freq[tok]=1
print(word_freq)
def main():
str1='Hello Python. I like Python.'
wordfreq(str1)
if __name__=='__main__':
main()

等价于

1
2
3
4
5
6
7
8
9
10
def wordfreq(str1):
word_freq={}
for tok in str1.split():
if tok in word_freq:
word_freq[tok]+=1
else:
word_freq[tok]=1
print(word_freq)
str1='Hello Python. I like Python.'
wordfreq(str1)

python官网网站源码

1
2
3
4
5
6
7
import requests
def HtmlText(url0):
html0 = requests.get(url).text
return html0
url='http://python.org/'
html = HtmlText(url)
print(html)

清理数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import requests
def HtmlText(url0):
html0 = requests.get(url).text
return html0
url = 'http://python.org/'
html = HtmlText(url)
# print(html)
# ~~~~~~~~~~数据清理~~~~~~~~~~~
#==================普通分割str.split===============
# tokens = [tok for tok in html.split()] #可直接运行
#==================正则分割re.split================
#-----------------\W匹配任意非单词性字符---------
# import re
# tokens = [tok for tok in re.split('\W+',html)] #可直接运行
#==================NLTK的clean_html================
#!!!!! 报错
#import nltk
# clean = nltk.clean_html(html)
# NotImplementedError: To remove HTML markup, use BeautifulSoup’s get_text() function,
# 原因是BeautifulSoup在相同方面做出了更好的成果之后,nltk自己删除了相应的同类函数,
# 可以用BeautifulSoup中的相应函数进行替代,所以上图的代码可以改为
#!!!!!
#==================bs4的get_text================
from bs4 import BeautifulSoup
tokens = [tok for tok in BeautifulSoup(html,'lxml').get_text().split()]
# ~~~~~~~~~~清理完毕~~~~~~~~~~~
print('Total num of tokens:',str(len(tokens)))
print(tokens[:5])
#['Welcome', 'to', 'Python.org', '{', '"@context":']

清洗+词频统计+排序

注意字典取子集与字典排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
def HtmlText(url0):
html0 = requests.get(url).text
return html0
url = 'http://python.org/'
html = HtmlText(url)
from bs4 import BeautifulSoup
tokens = [tok for tok in BeautifulSoup(html,'lxml').get_text().split()]
freq_dis = {}
for tok in tokens:
if tok in freq_dis:
freq_dis[tok] += 1
else:
freq_dis[tok] = 1
#!!!
#freq_dis.sort() #AttributeError:'dict' object has no attribute 'sort'
#!!!
import operator
sorted_freq_dis= sorted(freq_dis.items(), key=operator.itemgetter(1),reverse=True)
#========dict.items(),key=key=operator.itemgetter(1)【按第二列排序】,reverse=True【从大到小】
print('Total num of tokens:',str(len(sorted_freq_dis)))
print(sorted_freq_dis[:5])
#>>>
#[('Python', 54), ('>>>', 24), ('and', 22), ('to', 18), ('the', 15)]

nltk+词频+可视化

nltk.FreqDist 返回class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
def HtmlText(url0):
html0 = requests.get(url).text
return html0
url = 'http://python.org/'
html = HtmlText(url)
from bs4 import BeautifulSoup
tokens = [tok for tok in BeautifulSoup(html,'lxml').get_text().split()]
import nltk
freq_dis_nltk = nltk.FreqDist(tokens)
print(freq_dis_nltk)
#<FreqDist with 584 samples and 1069 outcomes>
print(type(freq_dis_nltk))
# <class 'nltk.probability.FreqDist'>
for k,v in freq_dis_nltk.items():
print(k,v)
#遗留问题:为什么没降序排列
freq_dis_nltk.plot(10)

image.png

停用词(未实现)

1
2
3
4
5
6
>>>stopwords=[word.strip().lower() for word in open("PATH/english.stop.
txt")]
>>>clean_tokens=[tok for tok in tokens if len(tok.lower())>1 and (tok.
lower() not in stopwords)]
>>>Freq_dist_nltk=nltk.FreqDist(clean_tokens)
>>>Freq_dist_nltk.plot(50, cumulative=False