2022年 11月 5日

只需5步用python让你掌握NLP基本概念(赶快收藏)

NLP简介 自然语言处理属于人工智能领域。所有计算机都擅长对数值数据进行处理,NLP这一部分计算机技术是处理文本数据,用来分析世界上不同的语言的。 现在NLP的应用大多都在机器翻译、舆情监测、自动摘要、观点提取、文本分类、问题回答、文本语义对比、语音识别、中文OCR等方面。

今天我们要get到的技能就是使用 Python中Spacy和NLTK 等库对语言处理进行基本概念的学习。

众所周知我们分析原始文本数据,数据量,代码量小的情况下,可以人眼分析一些。

但是如果我们试图在编程中建立一种机制,使用Python从文本数据中分析和提取最大的信息的话,我们还是使用 jupyter notebook 协助python编程代码进行所有处理和分析语言处理比较好。(Jupyter采用anaconda 发行版。)

毕竟用jupyter notebook的话就不用在回顾项目的时候再一次次的重新跑一遍代码了!

介绍了本篇教程的目的和要使用工具,学姐要开始上硬菜了!

五步走主题如下:

第 1 步:Spacy和NLTK安装指南

第 2 步:关于文本的基本概念和正则表达式

第 3 步:标记化和词干

第 4 步:词形还原和停用词

第 5步:词性 (POS) 和命名实体识别 (NER)

别跑,接下来我们就一步一步的说,保管你能看懂学会。

第 1 步:安装指南

安装 anaconda

首先安装 anaconda 发行版,安装后,anaconda会在环境中安装Spacy和NLTK库。

安装Spacy和NLTK

NLTK配置(安装NLTK库,命令行输入以下命令):

pip3 install nltk

有些时候的nltk代码需要语料库才能运行,运行下面的python代码下载语料库。

  1. import nltk
  2. nltk.download()

Spacy配置(安装spacy库,命令行输入以下命令):

pip3 install spacy

接着下载spacy的英语语言库:

python -m spacy download en #en stands for english

注意spacy使用时候需要声明使用的模型

  1. import spacy
  2. nlp = spacy.load('en_core_web_sm')

也可以下载spacy的中文语言库:

  1. python -m spacy download zh_core_web_sm
  2. import spacy
  3. nlp = spacy.load("zh_core_web_sm")

spacy库各语种下载传送门:https://spacy.io/usage/models#quickstart

第 2 步:文本的基本概念

安装下载好之后,接下来开始用 python读取这些文件,进行语言处理。先用一些文本数据来初步尝试一下,先从基本字符串开始:

  1. #打印普通字符串
  2. print('Amit')
  3. #output: Amit

举个例子:

字符串的名称是 GURUGRAM,这是一个城市的名字。如果需要选择特定范围的字母表时,要使用切片法和索引法。

当我们从左到右时,索引从0开始,当我们想要从右到左的字母表时,它从负 (-1) 开始,而不是从零开始。

然后用python进行以下操作:

  1. #首先将字符串插入到变量中
  2. string = GURUGRAM
  3. #获取第一个带有索引的字母
  4. print(string[0])
  5. #输出:G
  6. #打印多个字母
  7. print(string[2], string[5])
  8. #输出:RR
  9. #用于获取带有负索引的字母
  10. print(string[-4])
  11. #输出:G

现在通过切片获取字符:

  1. print(string[0:2])
  2. #output: GU
  3. print(string[1:4])
  4. #output: URU

是不是感觉有点意思了?那就开始挑战对句子的处理吧!

接下来是strip()函数表演时间,此函数可以删除开头和结尾的字符,但不能删除中间的字符,如果我们不指定删除字符,则默认情况下它将删除空格。

  1. #一个句子和句子中的移除字符
  2. sentence = "****Hello World! I am Amit Chauhan****"
  3. remove_character = "*"
  4. #使用strip函数去除
  5. star(*) sentence.strip(removing_character)
  6. #output:
  7. 'Hello World! I am Amit Chauhan'

上面的例子是从句子中去掉了星号。因此可以看出,这个函数可以去除字符,大家可以尝试以下不指定删除字符是什么样的结果。

和strip函数完全相反的操作是join操作,例子:

  1. str1 = "Happy"
  2. str2 = "Home""
  3. Good ".join([str1, str2])
  4. #output: 'Happy Good Home'

正则表达式

正则表达式有时称为关系表达式或 RegEx,用于字符或字符串匹配,在许多情况下用于查找和替换字符或字符串。

那如何在正则表达式中处理字符串和模式?首先学习在实际操作中导入正则表达式:

  1. # 要使用正则表达式,我们需要 import re
  2. import re

如何对简单字符串使用“re”?例子:

首先得有一个句子,然后在其中找到字符串,再对字符串进行一些操作👇

  1. sentence = "My computer gives a very good performance in a very short time."
  2. string = "very"

在句子中搜索字符串:

  1. str_match = re.search(string, sentence)
  2. str_match
  3. #output:<re.Match object; span=(20, 24), match='very'>

我们也可以对这个字符串做一些操作。比如要检查所有操作,可以写入 str_match。然后按选项卡,就会显示所有操作。

  1. str_match.span()
  2. #output:(20, 24)

上面是展示字符串“very”的跨度,20表示从句子中的第20个索引开始到第24个索引结束。

如果我们想找到一个出现多次的单词可以使用 findall 操作:

  1. find_all = re.findall("very", sentence)
  2. find_all
  3. #output: ['very', 'very']

上面的操作只是查找在一个字符串中出现多次出现的字符串。

如果我们想知道一个句子中单词的跨度以便我们可以了解单词的位置,就用迭代方法 finditer 操作。

  1. for word in re.finditer("very", sentence):
  2.               print(word.span())
  3. #output:(20, 24)(47, 51)

一些正则表达式是(a-z),(A-Z),(0–9),(\- \)。), (@, #, $, %).这些表达式用于查找文本中的模式,如有必要,还可用于清除干净的数据。有了模式,我们就可以使用量词来知道我们期望多少个表达式。

第 3 步:标记化(Tokenization)

当一个句子分解成小的单个单词时,这些单词被称为标记,这个过程被称为标记化。

前缀、中缀、后缀和例外中的句子分解,我们将使用 spacy 库学习标记化:

  1. #引入import库
  2. import spacy
  3. #加载spacy英文库
  4. load_en = spacy.load('en_core_web_sm')
  5. #take an example of string
  6. example_string = "I'm going to meet\ M.S. Dhoni."
  7. #加载字符串到库
  8. words = load_en(example_string)
  9. #getting tokens pieces with
  10. for loop for tokens in words:
  11. print(tokens.text)
  12. #output:"
  13. I
  14. 'm
  15. going
  16. to
  17. meet
  18. M.S.
  19. Dhoni
  20. . "

我们可以从索引和切片中获取标记:

  1. str1 = load_en(u"This laptop belongs to Amit Chauhan")
  2. #获取索引为str1[1] 的令牌
  3. str1[1]
  4. #output: laptop
  5. #通过切片获取令牌
  6. str1[2:6]
  7. #output: belongs to Amit Chauhan

词干

词干提取是将单词还原为词根的过程。

词干分析器的类型:

1. Porter Stemmer

2. Snowball Stemmer

Spacy不包含词干分析器,因此我们将使用 NLTK库进行词干提取。

Porter词干分析器于1980年开发,它的功能就是将单词缩减为其词干或词根:

  1. #引入nltk库
  2. import nltk
  3. #import porter stemmer from nltk
  4. from nltk.stem.porter import PorterStemmer
  5. pot_stem = PorterStemmer()
  6. #随机词测试搬运工
  7. words = ['happy', 'happier', 'happiest', 'happiness', 'breathing', 'fairly']for word in words:
  8.         print(word + '----->' + pot_stem.stem(word))
  9. #output:
  10. happy----->happi
  11. happier----->happier
  12. happiest----->happiest
  13. happiness----->happi
  14. breathing----->breath
  15. fairly----->fairli

上面这些词被简化为仅有词干,但是porter词干分析器的结果并不是很让人满意。

因此,就用Snowball词干分析器进行改进:

  1. from nltk.stem.snowball import SnowballStemmer
  2. snow_stem = SnowballStemmer(language='english')
  3. for word in words:
  4.    print(word + '----->' + snow_stem.stem(word))
  5. #output:
  6. happy----->happi
  7. happier----->happier
  8. happiest----->happiest
  9. happiness----->happi
  10. breathing----->breath
  11. fairly----->fair

第4步:词形还原

词形还原比词干提取要好,而且信息丰富,除了词干之外,还可以确定词周围的词性。因为spacy有词形还原,没有办法提取词干,所以就使用spacy进行词形还原:

#import library

import spacy

#Loading spacy english library

load_en = spacy.load(‘en_core_web_sm’)

#take an example of string

example_string = load_en(u”I’m happy in this happiest place with all happiness. It feels how happier we are”)

for lem_word in example_string:

   print(lem_word.text, ‘\t’, lem_word.pos_, ‘\t’, lem_word.lemma, ‘\t’, lem_word.lemma_)

在上面的词形还原代码中,单词的描述给出了所有信息。每个单词的词性和输出中的数字是英语语言库中的特定引理。观察结果中的happiest to happy、happier to happy的结果,得出词形还原比词干分析器更好的结论。

停止词

停止词用于过滤一些经常重复且但不提供有关文本信息的词。在Spacy中,有一些停用词的内置列表:

  1. #import library
  2. import spacy
  3. #Loading spacy english library
  4. load_en = spacy.load('en_core_web_sm')
  5. print(load_en.Defaults.stop_words)

第5步:词性 (POS)

词性是获取文本和单词信息的过程,或者说是获取单词的语法信息,深层信息对于自然语言处理非常重要。

有两种类型的标签:对于名词,动词使用粗标签;对于复数名词,过去时类型,使用细粒度标签 (fine-grained tags):

  1. #import library
  2. import spacy
  3. #Loading spacy english library
  4. load_en = spacy.load('en_core_web_sm')
  5. str1 = load_en(u"This laptop belongs to Amit Chauhan")

检查有索引位置的标记:

  1. print(str1[1])
  2. #output: laptop

调用这个token的操作:

  1. #pos_ tag操作
  2. print(str1[1].pos_)
  3. #output: NOUN
  4. #了解细粒度信息
  5. print(str1[1].tag_)
  6. #output: NN

粗标记是 NOUN,细粒度 标记是NN,可以看出这个名词是单数。

借助spacy了解什么是 POS 计数:

  1. pos_count = str1.count_by(spacy.attrs.POS)
  2. pos_count
  3. #output: {90: 1, 92: 1, 100: 1, 85: 1, 96: 2}

这些数字是什么?咱们接着看!

先来看看90这个数字是什么意思:

  1. str1.vocab[90].text
  2. #output: DET

DET表示数字90属于限定词,数值1属于它,DET在一个句子中重复了一次。

命名实体识别 (NER)

命名实体识别对于识别文本并将其赋予标签实体非常有用,无论它是原始形式还是非结构化形式。

当你不知道文本的实体类型时,NER帮助你标记它们并赋予文本含义。

使用spacy做NER示例:

  1. #import library
  2. import spacy
  3. #Loading spacy english library
  4. load_en = spacy.load('en_core_web_sm')
  5. #lets label the entity in the text file
  6. file = load_en(u" I am living in India, Studying in IIT")
  7. doc = file if doc.ents:
  8. for ner in doc.ents:
  9.     print(ner.text + ' - '+ ner.label_ + ' - ' + str(spacy.explain(ner.label_)))
  10. else:
  11. print(No Entity Found)
  12. #output: India - GPE - Countries, cities, states

上面的代码中用NER分析文本,发现印度是一个国家名称或州名,所以我们可以知道标记是用实体标注完成的。

学会了吗?没有的话再看一遍!一定要动手敲,看代码是不能成为合格的码农的!有什么学习上的问题就来问学姐吧!

参考文档:

https://pub.towardsai.net/nlp-zero-to-hero-with-python-2df6fcebff6e