公众号:尤而小屋
作者:Peter
编辑:Peter
大家好,我是Peter~
本文是《NLTK基础教程-用NLTK和Python库构建机器学习应用》的学习笔记,主要讲解的是文本歧义及其清理。
1 文本歧义及清理
文本歧义是指从原生数据中获取一段机器可读的已格式化文本之前所要做的全部预处理工作,包含:
- 数据再加工data munging
- 文本清理
- 特定预处理
- 标识化处理
- 词干提取
- 词形还原
- 停用词移除
- 罕见词移除
- 拼写纠错
2 语句分离器
2.1 内置方法
语句分离指的是将一大段原生文本分割成一系列的语句,以便从中获取更多有意义的信息,也就是让语句成为一个可用的交流单元。
In [1]:
import numpy as np
import nltk
nltk.download('punkt')
nltk.download('wordnet')
[nltk_data] Downloading package punkt to
[nltk_data] C:\Users\Administrator\AppData\Roaming\nltk_data...
[nltk_data] Package punkt is already up-to-date!
[nltk_data] Downloading package wordnet to
[nltk_data] C:\Users\Administrator\AppData\Roaming\nltk_data...
[nltk_data] Package wordnet is already up-to-date!
Out[1]:
True
In [2]:
input_string = 'this is an example sent. The sentence splitter will split on sent markers. Ohh really !!'
In [3]:
from nltk.tokenize import sent_tokenize
all_sent = sent_tokenize(input_string)
all_sent
Out[3]:
['this is an example sent.', 'The sentence splitter will split on sent markers.', 'Ohh really !!']
其中, sent_tokensize是NLTK中的语句边界检测算法,也可以自定义分离器:
2.2 自定义方法
In [4]:
import nltk.tokenize.punkt
In [5]:
tokenizer = nltk.tokenize.punkt.PunktSentenceTokenizer()
3 标识化处理
机器所能理解的最小处理单元是单词(分词)。标识化实际上就是将原生字符串分割成一系列有意义的分词。
标识化处理的复杂性因具体的NLP任务而异,比如英文中可以使用正则表达式来提取想要的内容
In [6]:
s = 'Hi everyone ! My name is Peter and I am 18'
下面采用不同的标识器tokenizer进行分词处理:
1、split方法
In [7]:
# 方法1
s.split()
Out[7]:
['Hi', 'everyone', '!', 'My', 'name', 'is', 'Peter', 'and', 'I', 'am', '18']
2、word_tokenize()方法是一个通用的、可面向所有类型语料库的标识化处理方法
In [8]:
# 方法2
from nltk.tokenize import word_tokenize
word_tokenize(s)
Out[8]:
['Hi', 'everyone', '!', 'My', 'name', 'is', 'Peter', 'and', 'I', 'am', '18']
In [9]:
# 方法3
from nltk.tokenize import regexp_tokenize, wordpunct_tokenize, blankline_tokenize
3、regexp_tokenize基于正则表达式的分词函数,pattern表示具体的模式,用户可以根据需求自定义:
In [10]:
regexp_tokenize(s, pattern='\w+') # \w表示匹配文字 +表示1个或多个
Out[10]:
['Hi', 'everyone', 'My', 'name', 'is', 'Peter', 'and', 'I', 'am', '18']
In [11]:
regexp_tokenize(s, pattern='\d+') # \d表示匹配数字
Out[11]:
['18']
wordpunct_tokenize 是一个用于分词的函数,通常在自然语言处理和文本分析中使用。它可以将文本分解成单词和标点符号:
In [12]:
wordpunct_tokenize(s)
Out[12]:
['Hi', 'everyone', '!', 'My', 'name', 'is', 'Peter', 'and', 'I', 'am', '18']
4 词干提取(stemming)
词干提取是一种基于规则的文本处理方法,通过删除单词的后缀来提取词干,也称为stemming。
它的目的是将单词转化为其基本形式,即词干,而不考虑单词的语法和语义。例如,将“running”、“runs”和“ran”都转化为词干“run”。
词干提取有多种方法,其中最常用的是Porter词干提取算法和Lancaster词干提取算法。这些算法基于不同的规则和启发式方法,根据单词的特定模式和规则来进行词干提取。
In [13]:
from nltk.stem import PorterStemmer
from nltk.stem.lancaster import LancasterStemmer
from nltk.stem.snowball import SnowballStemmer
- PorterStemmer:PorterStemmer是一个用于从英文单词中获得符合语法的词干的工具。它可以将单词还原为其词根形式,例如将 "running"、"runs" 和 "ran" 都还原为 "run"。此外,PorterStemmer 还用于创建一个字典,存储文本中每一个单词的出现频率
- LancasterStemmer:LancasterStemmer 是基于 Lancaster 词干提取算法的工具,它可以替换和消除英文单词中的后缀。该算法比 Porter 词干提取算法更复杂,涉及到更多不同情感词的使用。
- SnowballStemmer:这个提取器家族可分别用于荷兰语、英语、法语等多种语言。
In [14]:
# 创建两个词干提取对象
pst = PorterStemmer()
lst = LancasterStemmer()
In [15]:
pst.stem("eating")
Out[15]:
'eat'
In [16]:
pst.stem("eaten") # 没有提取到词干eat
Out[16]:
'eaten'
In [17]:
pst.stem("eats")
Out[17]:
'eat'
使用lst实例的效果:
In [18]:
lst.stem("eating")
Out[18]:
'eat'
In [19]:
lst.stem("eaten")
Out[19]:
'eat'
In [20]:
lst.stem("eats")
Out[20]:
'eat'
5 词形还原lemmatization
对于更为复杂的NLP任务,我们必须改用词形还原(lemmatization)。
In [21]:
from nltk.stem import WordNetLemmatizer
In [22]:
wlem = WordNetLemmatizer()
wlem.lemmatize("ate")
Out[22]:
'ate'
在这里WordNetLemmatizer使用wordnet,它会针对单词去搜索wordnet这个语义词典
词干提取和词形还原的区别:
词干提取(stemming)的主要目标是简化或归并词的形态,将词转变为它的词干(或词根)形式。这种方法主要用于英文等形态变化较少的语言,主要通过去除词的后缀实现。例如,“running” 的词干是 “run”,“drove” 的词干是 “drive”。在信息检索和文本处理领域,词干提取能够将不同形式的词汇统一到一个基本的形态上,提高检索的准确性和效率。
词形还原(lemmatization)的目标是将词汇还原为其最基本或最常用的形态,通常用于处理有复杂形态变化的自然语言,如德语、俄语或阿拉伯语等。以德语为例,“sein” 是 “to be” 的现在时第三人称单数形式,而词形还原会将 “sein” 还原为 “to be”。
词形还原比词干提取更关注于理解词汇的内在语义逻辑
6 停用词移除Stop word removal
停用词移除是NLP任务中最为常用的预处理工作之一。就是简单地移除语料库中所有文档中都会出现的单词。比如单词and、the、of等。
NLTK库中内置了22种语言的停用词列表。
In [23]:
from nltk.corpus import stopwords
In [24]:
stop_list = stopwords.words("english")
In [25]:
text = "this is just a test"
In [26]:
clean_word_list = [word for word in text.split() if word not in stop_list] # 不在停用词中的单词列出来
clean_word_list
Out[26]:
['test']
7 罕见词移除
通常我们会设置一个标准长度,将太短或者太长的词语进行移除:
# tokens is a list of all tokens in corpus
freq_dist = nltk.FreqDist()
rare_words = freq_dist.keys()[-50:]
after_rare_words = [word for word in token not in rare_words]
8 拼写纠错spellchecker
- 纯字典查找的方式创建基本的拼写检查器
- 开发的增强型的字符串算法,比如edit-distance等
In [27]:
from nltk.metrics import edit_distance # Peter Norvig发明
In [28]:
edit_distance("rain", "shine")
Out[28]:
3