如何用Python进行自然语言处理的介绍(附代码)

279 阅读10分钟

用Python进行自然语言处理的介绍

用Python学习NLP的基础知识以及如何赋予文本以意义

我的语言的极限意味着我的世界的极限。- 路德维希-维特根斯坦

计算机讲自己的语言,即二进制语言。因此,它们与我们人类的互动方式是有限的;扩展它们的语言并理解我们自己的语言,对于让它们摆脱界限至关重要。

NLP是自然语言处理的缩写,它包括一套工具、程序和技术,计算机可以用来处理和理解人类通信。不要与语音识别相混淆,NLP处理的是理解词语的含义,而不是将音频信号解释成这些词语。

如果你认为NLP只是一个未来的想法,你可能会震惊地知道,当我们在谷歌中进行查询时,当我们在网上使用翻译时,当我们与谷歌助理或Siri交谈时,我们很可能每天都与NLP互动。NLP无处不在,由于NLTK等库的存在,在你的项目中实现NLP现在是非常容易的,这些库提供了对复杂性的巨大抽象。

在这篇文章中,我们将讨论如何使用NLTK库和python来处理NLP。


设置环境

为了使事情更简单,我们将使用jupyter笔记本Google Colab,你可以通过访问这里的补充源代码来了解我们所做的每一步。

一旦你有了jupyter笔记本,或者你选择的任何环境,确保你通过使用下面的命令安装nltk库:

!pip3 install nltk

注意,如果你不是在jupyter笔记本环境下,你将不需要在开始时的!


符号化

NLTK是一个巨大的库,提供了很多不同的工具来处理语言。虽然有些功能是库本身就有的,但有些模块需要额外下载。punkt 是一个处理标记化的模块,即把一段话分成几块或几个字的过程,它通常是文本分析过程中的第一步。在开始之前,请确保你下载该模块:

import nltk
nltk.download('punkt')

现在,让我们看看它的运行情况

from nltk.tokenize import word_tokenize
Text = "Good morning, How you doing? Are you coming tonight?"
Tokenized = word_tokenize(Text)
print(Tokenized)

输出:

['Good', 'morning', ',', 'How', 'you', 'doing', '?', 'Are', 'you', 'coming', 'tonight', '?']

这第一个功能,word_tokenize ,将文本分割成单词和符号,然而,你可以用punkt ,比如将一个段落分割成句子:

from nltk.tokenize import sent_tokenize
Text = "Good morning, How you doing? Are you coming tonight?"
Tokenized = sent_tokenize(Text)
print(Tokenized)

输出:

['Good morning, How you doing?', 'Are you coming tonight?']

如果第一个例子没有给人留下深刻印象,那么这一个绝对是。在这里,我们开始看到一个更智能的方法,它试图将文本分割成更简单的有意义的块状物。


停顿词

停止词是一个常用的词(如 "the"、"a"、"an"、"in"),搜索引擎在编制索引进行搜索和作为搜索查询的结果进行检索时都会将其忽略。在某些情况下,忽略这些词是很重要的,因此,拥有一本关于这些词的字典会变得非常方便,特别是当我们需要处理多种语言的时候。NLKT提供了一个处理阶梯词的模块,接下来让我们下载它:

import nltk
nltk.download('stopwords')

停止词是一个简单的单词列表,因此我们可以非常容易地对它进行操作,例如,通过编写一个小的路由来获得一个没有停止词的单词列表:

from nltk.corpus import stopwords
stopwords = stopwords.words("english")
Text = ["Good", "morning", "How", "you", "doing", "Are", "you", "coming", "tonight"]
for i in Text:
   if i not in stopwords:
       print(i)

输出:

Good
morning
How
Are
coming
tonight

由于我们得到的是一个简单的单词列表,所以我们可以简单地打印出来,以查看某一特定语言的所有单词:

from nltk.corpus import stopwords
stopwords = stopwords.words("english")
print(stopwords)

词干化

词干是一个词的基础或根部形式,例如,"loving "这个词的根部是 "love",而 "being "则是 "be"。词干是指我们将一个给定的词转化为其词干的过程。这是一项非常复杂的工作,单词可以以多种形式书写,而且不同的单词有不同的方式来获得其词干。值得庆幸的是,NLTK为我们实现这一目标提供了便利,让我们来看看是如何做到的:

from nltk.stem import PorterStemmer
ps = PorterStemmer()
words = ["Loving", "Chocolate", "Retrieved", "Being"]
for i in words:
   print(ps.stem(i))

输出:

love
chocol
retriev
be

这种对单词的简化在搜索引擎中很有帮助,可以防止同一单词的不同写法在搜索标准中被忽略。


计算词的数量

计算每个词出现的次数在文本分析中非常有帮助。NLTK为我们提供了一种巧妙的方法来计算文本中的单词频率,称为FreqDist

import nltk
words = ["men", "teacher", "men", "woman"]
FreqDist = nltk.FreqDist(words)
for i,j in FreqDist.items():
   print(i, "---", j)

输出:

men --- 2
teacher --- 1
woman --- 1

词组

很多时候,我们看到一些词被放在一起使用,以赋予一个特定的含义,例如 "我们走吧"、"最佳表现 "等。在文本分析中,将这些词作为成对的词来捕捉是很重要的,因为看到它们在一起,对文本的理解会有很大的不同。

大词

NLTK提供了一些方法来做到这一点,我们将从大梁开始,它是一种提取成对连接词的方法:

words = "Learning python was such an amazing experience for me"
word_tokenize = nltk.word_tokenize(words)
print(list(nltk.bigrams(word_tokenize)))

输出:

[('Learning', 'python'), ('python', 'was'), ('was', 'such'), ('such', 'an'), ('an', 'amazing'), ('amazing', 'experience'), ('experience', 'for'), ('for', 'me')]

同样地,我们也可以对3个或更多的词进行同样的处理。

三角形(Trigrams)

Bigrams是指总是出现在一起的两个词,但Trigrams与bigrams相同,但有三个词,代码上几乎没有区别:

words = "Learning python was such an amazing experience for me"
print(list(nltk.trigrams(word_tokenize)))

输出:

[('Learning', 'python', 'was'), ('python', 'was', 'such'), ('was', 'such', 'an'), ('such', 'an', 'amazing'), ('an', 'amazing', 'experience'), ('amazing', 'experience', 'for'), ('experience', 'for', 'me')]

Ngrams

Ngrams也是一些在一个短语或文档中一起出现的词或字母或符号,就像前面两种方法bigrams和trigrams一样,但在这里你可以指定词的编号。让我们看一个例子。

print(list(nltk.ngrams(word_tokenize, 4)))

输出:

[('Learning', 'python', 'was', 'such'), ('python', 'was', 'such', 'an'), ('was', 'such', 'an', 'amazing'), ('such', 'an', 'amazing', 'experience'), ('an', 'amazing', 'experience', 'for'), ('amazing', 'experience', 'for', 'me')]

尽管在所展示的文本中,结果似乎并不十分令人印象深刻,但在许多使用案例中,Ngrams可以被有效地使用,例如垃圾邮件的检测。


词法化

词缀化的概念与词干化非常相似,只是最后一个词缀化只删除了单词的前缀或后缀,有时会出现一些拼写错误,词缀化会将其转换为相关的基础单词。让我们看一个例子,但在这之前我们需要用NLTK下载WordNet包:

nltk.download('wordnet')
from nltk.stem import WordNetLemmatizer
Lem = WordNetLemmatizer()
print(Lem.lemmatize("believes"))
print(Lem.lemmatize("stripes"))

输出:

belief
stripe

当你运行这段代码时,它将把每个词转换成它的基础词,如 "believes "转换成 "belief","stripes "转换成 "stripe "等等。这个被称为WordNetLemmatizer的软件包的好处是,它有一个叫做pos的参数,代表 "语篇",你可以指定你想得到该词的动词或形容词。让我们看一个例子:

from nltk.stem import WordNetLemmatizer
Lem = WordNetLemmatizer()
print(Lem.lemmatize("believes", pos="v"))
print(Lem.lemmatize("stripes", pos="v"))

输出:

believe
strip

注意到结果的不同了吗?

POS标记器

前段时间,当你在学校时,你可能学会了将单词分为动词、名词、形容词等。而今天,这项任务对我们人类来说是非常微不足道的,但是如果计算机想要理解人类的语言,他们就需要理解这些概念,他们需要区分行动和目标、动词和名词的不同。NLTK为我们提供了POS(Part of Speech)来对单词进行分类。

它超级容易操作,让我们来看看代码:

nltk.download('averaged_perceptron_tagger')
words = "Learning python was such an amazing experience for me"
word_tokenize = nltk.word_tokenize(words)
print(nltk.pos_tag(word_tokenize))

输出:

[('Learning', 'VBG'), ('python', 'NN'), ('was', 'VBD'), ('such', 'JJ'), ('an', 'DT'), ('amazing', 'JJ'), ('experience', 'NN'), ('for', 'IN'), ('me', 'PRP')]

结果是一个单词的列表和与之相关的POS标签。这些标签是首字母缩写,你可以在下面的表格中找到完整的参考:

POS标签的列表


命名实体识别

现在我们开始使用更强大的功能,NER(命名实体识别)是用来捕捉所有文本中提到的命名实体。命名的实体可以是任何东西,从一个地方,一个人,一个组织,金钱,等等。

这可能是非常强大的,与其他方法相结合,可以直接从文本资源中回答问题,如 "谁是美国总统?",而不需要有结构化的答案。如果你经常在谷歌上搜索,你会看到相当多的这种方法在发挥作用:

nltk.download('maxent_ne_chunker')
nltk.download('words')


Text = "The russian president Vladimir Putin is in the Kremlin"
Tokenize = nltk.word_tokenize(Text)
POS_tags = nltk.pos_tag(Tokenize)
NameEn = nltk.ne_chunk(POS_tags)
print(NameEn)

输出:

(S
  The/DT
  russian/JJ
  president/NN
  (PERSON Vladimir/NNP Putin/NNP)
  is/VBZ
  in/IN
  the/DT
  (FACILITY Kremlin/NNP))

看看现在我们如何开始结合我们所学的功能来收集关于文本的更多信息,并开始通过识别其中的结构和实体来赋予一个句子,一个文本更多的意义。

情感分析

到目前为止,我们用文字把它分解成更小的单元,然后用于处理。情感分析与此不同,它是一个确定文本的情感或情绪成分的过程。它非常有名,例如,对应用程序、电影等的正面和负面评论进行编目。

虽然可以利用我们已经学过的函数直接用NLTK做情感分析,但这仍然是一个不必要的繁琐过程,幸好python提供了TextBlob,这是一个建立在NLTK之上的文本处理库,它为我们处理了情感分析的所有复杂问题。

正如我们接下来将通过分析美国第46任总统乔-拜登的一条推文来证明的那样,它非常容易使用:

!pip3 install textblob

from textblob import TextBlob
Joe_Biden_Tweet = "Small businesses need relief, but many were muscled out of the way by big companies last year."
Joe_Biden = TextBlob(Joe_Biden_Tweet)
print(Joe_Biden.sentiment)

输出:

Sentiment(polarity=0.0625, subjectivity=0.26666666666666666)

情感分析的结果有两个变量,极性和主观性。极性是一个介于-1和1之间的值,-1表示非常消极,+1表示非常积极。主观性在0和1之间,指的是人的意见、情感甚至判断。数字越大,文本的主观性越强。


拼写纠正

我们提到TextBlob有多种用途,拼写纠正是其中之一。听起来很简单,TextBlob可以帮助我们消除文本中的拼写错误。让我们来看看它的实际效果:

from textblob import TextBlob
Text = "Smalle businesses neede relief"
spelling_mistakes = TextBlob(Text)
print(spelling_mistakes.correct())

输出:

Small business need relief

正如预期的那样,TextBlob识别了我们的错误,并在生成的文本中纠正了这些错误。


总结

NLP是一个复杂而迷人的世界,今天我们介绍了一些概念和代码,但我们几乎没有触及可以做什么的表面。NLTK是一个巨大的库,有大量的用例和潜力,值得详细阅读。在接下来的文章中,我们将继续学习NLP,什么是新的趋势,新的算法,以及人工智能将如何让我们生产出能够与人类无缝互动的机器。

谢谢你的阅读!