【Python】Python中的文本处理
作者 | KahEm Chu
编译 | VK
来源 | Towards Data Science
互联网连接了世界,而Facebook、Twitter和Reddit等社交媒体为人们提供了表达自己对某个话题的看法和感受的平台。然后,智能手机的普及直接增加了这些平台的使用率。例如,有96%或22.4亿Facebook活跃用户通过智能手机和平板电脑使用Facebook[1]。
随着社会媒体使用量的增加,文本数据的规模不断扩大,促进了自然语言处理(NLP)的研究,如信息检索和情感分析。大多数情况下,被分析的文档或文本文件是巨大的,并且含有大量的噪声,直接使用原始文本进行分析是不适用的。因此,文本处理对于为建模和分析提供清晰的输入至关重要。
文本处理包括两个主要阶段,即标识化(Tokenization)和规范化(Normalization)[2]。标识化是将一个较长的文本字符串拆分为较小的片段或标识的过程[3]。规范化是指将数字转换为它们的等价词,删除标点符号,将所有文本转换为相同的大小写,删除停用词,删除噪声,词根化或词形还原。
词根化-删除词缀(后缀、前缀、中缀),例如,running 变成run
词形还原-捕获单词的原本词形。例如,better变成good[4]
在本文中,我将演示Python中的文本处理。
下面是一段摘自丹尼尔·朱拉夫斯基和詹姆斯·H·沃克的《Speech and Language Processing》一书。马丁[6]。
“赋予计算机处理人类语言的能力的想法和计算机本身的想法一样古老。
这本书是关于这个令人兴奋的想法的实施和影响。我们介绍了一个充满活力的跨学科领域,有许多名称对应于它的许多方面,如语音和语言处理、人类语言技术、自然语言处理、计算语言学和语音识别与合成。
这一新领域的目标是让计算机执行涉及人类语言的有用任务,例如实现人机通信、改善人类通信或只是对文本或语音进行有用的处理。”
“The idea of giving computers the ability to process human language is as old as the idea of computers themselves. This book is about the implementation and implications of that exciting idea. We introduce a vibrant interdisciplinary field with many names corresponding to its many facets, names like speech and language processing, human language technology, natural language processing, computational linguistics, and speech recognition and synthesis. The goal of this new field is to get computers to perform useful tasks involving human language, tasks like enabling human-machine communication, improving human-human communication, or simply doing useful processing of text or speech.”
本段将用于下面的文本处理示例中。
Python中的文本处理
对于Python中的文本处理,演示中将使用两个自然语言处理(NLP)库,即NLTK(Natural Language Toolkit)和spaCy。之所以选择这两个库而不是Gensim和Transformer等其他文本处理库,是因为NLTK和spaCy是最受欢迎的库,对自然语言处理(NLP)的初学者来说非常友好。
对于NLTK和spaCy,首先需要将文本保存为变量。
text = """The idea of giving computers the ability to process human language is as old as the idea of computers themselves. This book is about the implementation and implications of that exciting idea. We introduce a vibrant interdisciplinary field with many names corresponding to its many facets, names like speech and language processing, human language technology, natural language processing, computational linguistics, and speech recognition and synthesis. The goal of this new field is to get computers to perform useful tasks involving human language, tasks like enabling human-machine communication, improving human-human communication, or simply doing useful processing of text or speech."""
基于NLTK的文本处理
导入所有需要的库
import re
import pandas as pd
import nltk
from nltk.tokenize import WordPunctTokenizer
nltk.download(’stopwords’)
from nltk.corpus import stopwords
nltk.download(’wordnet’)
from nltk.stem import WordNetLemmatizer
1.标识化
使用标识器将句子分隔成单个单词(标识)的列表。
word_punct_token = WordPunctTokenizer().tokenize(text)
除了上面使用的WordPunctTokenizer之外,NLTK库中还有几个标识器模块。例如,word_tokenize和RegexpTokenizer。
RegexpTokenizer通过设置RegexpTokenizer(‘\w+|<pre>不能识别此Latex公式:
[\d.]+|\S+’),可以将货币(如
9.99)分离为单个标识。所有提到的标识器都将以列表形式返回标识。NLTK还有一个模块名sent_tokenize,它能够将段落分隔成句子列表。
2.规范化
下面的脚本删除了非单词的标识,例如,符号和数字,以及仅包含少于两个字母或仅包含辅音的标识。这个脚本在本例中可能没有用处,但在处理大量文本数据时非常有用,它有助于清除大量噪声。我总是喜欢在处理文本数据时包含它。
clean_token=[]
for token in word_punct_token:
token = token.lower()
# 删除任何非字母的值
new_token = re.sub(r'[^a-zA-Z]+', '', token)
# 删除空值和单个字符值
if new_token != "" and len(new_token) >= 2:
vowels=len([v for v in new_token if v in "aeiou"])
if vowels != 0: # 删除只包含辅音的行
clean_token.append(new_token)
2a.删除停用词
停用词指没有多少用处的词,如介词。NLTK和spaCy在库中有不同数量的停用词,但是NLTK和spaCy都允许我们添加任何我们认为必要的词。例如,当我们处理电子邮件时,我们可以添加gmail、com、outlook作为stopwords。
# 获取停用词列表
stop_words = stopwords.words('english')
# 在列表中添加新的停用词
stop_words.extend(["could","though","would","also","many",'much'])
print(stop_words)
# 从标识列表中删除停用词
tokens = [x for x in clean_token if x not in stop_words]
2b.词性标注
这个过程指的是用词性位置标识单词,例如动词、形容词和名词。nltk.pos_tag模块以元组的形式返回结果,为了简化以后的任务,通常我会将它们转换为数据帧。
data_tagset = nltk.pos_tag(tokens)
df_tagset = pd.DataFrame(data_tagset, columns=['Word', 'Tag'])
2c.词形还原
词干化和词形还原都有助于减少词汇的维数,方法是将单词还原为词根形式(词形还原)或删除所有后缀、词缀、前缀等(词干化)。
词干分析有助于减少词汇的维数,但大多数情况下,词干分析会变得毫无意义,因为词干分析只会切掉词尾,而不会将单词还原为基本形式。例如,houses在删除后会变成hous,完全失去意义。因此,词形还原对于文本分析更为可取。
以下脚本用于获取名词、形容词和动词的词形还原形式。
# 创建lemmatizer对象
lemmatizer = WordNetLemmatizer()
# 对每个单词进行词形还原并显示输出
lemmatize_text = []
for word in tokens:
output = [word, lemmatizer.lemmatize(word, pos='n'), lemmatizer.lemmatize(word, pos='a'),lemmatizer.lemmatize(word, pos='v')]
lemmatize_text.append(output)
# 创建数据帧
df = pd.DataFrame(lemmatize_text, columns =['Word', 'Lemmatized Noun', 'Lemmatized Adjective', 'Lemmatized Verb'])
df['Tag'] = df_tagset['Tag']
将形容词、名词和动词分开进行词形还原是为了提高lemmatizer的准确性。
# 替换为单个字符以简化
df = df.replace(['NN','NNS','NNP','NNPS'],'n')
df = df.replace(['JJ','JJR','JJS'],'a')
df = df.replace(['VBG','VBP','VB','VBD','VBN','VBZ'],'v')
'''
定义一个函数,当tagset是名词时,词形还原;当标识集是形容词时,取词形还原的形容词
'''
df_lemmatized = df.copy()
df_lemmatized['Tempt Lemmatized Word']=df_lemmatized['Lemmatized Noun'] + ' | ' + df_lemmatized['Lemmatized Adjective']+ ' | ' + df_lemmatized['Lemmatized Verb']
df_lemmatized.head(5)
lemma_word = df_lemmatized['Tempt Lemmatized Word']
tag = df_lemmatized['Tag']
i = 0
new_word = []
while i<len(tag):
words = lemma_word[i].split('|')
if tag[i] == 'n':
word = words[0]
elif tag[i] == 'a':
word = words[1]
elif tag[i] == 'v':
word = words[2]
new_word.append(word)
i += 1
df_lemmatized['Lemmatized Word']=new_word
上面的脚本是根据词性标签将词形还原后的单词分配给原始单词。
3.获得清洗过的标识
# 计算标识的频率分布
lemma_word = [str(x) for x in df_lemmatized['Lemmatized Word']]
在对文本进行了标识化和规范化之后,现在我们获得了一个干净的标识列表,可以将其插入到WordCloud或其他文本分析模型中。
spaCy文本处理
1.标识化+词形还原
与NLTK相比,spaCy优势在于简化了文本处理过程。
# 导入spaCy并加载语言库
import spacy
# 你需要在下面的这一行下载软件包
!python -m spacy download en_core_web_sm
nlp = spacy.load('en_core_web_sm')
# 创建文档对象
doc = nlp(text)
token_list = []
# 收集POS, 依存关系和词根
for token in doc:
output = [token.text, token.pos_, token.dep_,token.lemma_]
token_list.append(output)
# 使用数据创建数据帧
df = pd.DataFrame(token_list, columns =['Word', 'POS Tag', 'Dependencies', 'Lemmatized Word'])
在spaCy中,当你执行标识化时,你可以获得POS标识和词形,这为你节省了一些精力。
2.规范化
由于词形还原是在一开始就执行的,所以标准化步骤只留下去除噪声和停用词。
2a.消除噪音
df_nopunct = df[df['POS Tag']!='PUNCT']
df_nopunct
spaCy POS中包含了一个标点符号标签,显示为PUNCT,因此我们可以通过去掉带有PUNCT标签的标记来删除所有的标点符号。
2b.删除停用词
import numpy as np
lemma_word = df_nopunct['Lemmatized Word'].values.tolist()
stopword = nlp.Defaults.stop_words
# 将单词添加到停用词集中,使用小写!
nlp.Defaults.stop_words.add('btw')
is_stopword_list = []
for word in lemma_word:
is_stopword = nlp.vocab[word].is_stop
is_stopword_list.append(is_stopword)
df_nopunct["is_stopword"] = is_stopword_list
df_nopunct
clean_df = df_nopunct[df_nopunct["is_stopword"]==False]
SpaCy有一个.is_stop可以用来检测一个标识是否是停用词,我们可以用它来删除停用词,如上面的脚本所示。
3.获得清洗过的标识
clean_list = clean_df["Lemmatized Word"].values.tolist()
现在我们获得了清理过的标识!
spaCy比NLTK更快、更先进,但是NLTK对初学者来说更好地理解文本处理中的每一个过程,因为它出现的早,并且有很多文档和解释。
你可以在这里找到spaCy和NLTK在GPU支持、效率、性能、最新技术、词向量和灵活性等其他特性方面的比较:https://towardsdatascience.com/text-normalization-with-spacy-and-nltk-1302ff430119。
感谢阅读!希望上面的演示能帮助你理解Python中的文本处理。
对于文本处理,理解数据结构与正则表达式(RegEx)一样重要。例如,类或模块的返回可能是元组和列表的形式,要操作输出,首先要了解它们。下面是我经常使用的一些脚本,用于为不同的目的更改变量的数据结构。
1.从数据帧(多列)到嵌套列表,从嵌套列表到列表
在创建主题模型或情感分析模型时,通常我们会根据句子或段落分别保存标识,例如,评论和tweet会分别保存,以获得每个评论或tweet的准确情感或话题。
因此,如果我们有10个评论,将有10个标识列表,将它们保存在一个变量中,创建一个嵌套列表。另一个例子是,一个数据框,有几个列保存文本数据,例如产品的评论。我们可能希望直接将这些列更改为列表,但将少数数据列更改为列表也会创建嵌套列表。
# df_essays是一个数据框,包含文本数据列
essay_list = df_essays.values.tolist() # 这将创建嵌套列表
# 这将创建平面列表
flatEssayList = [item for elem in essay_list for item in elem if str(item) != 'nan']
2.从数据帧(单列)或列表到文本
文本分析中最流行的应用之一是WordCloud,它主要用于分析文本中最频繁的讨论。这个模块只接受文本作为输入,所以在这个场景中,我们需要将list或DataFrame.Column更改为text。
# dataframe.column到文本
text = ‘ ‘.join(str(x) for x in df[‘review’])
# 列表到文本
text = ‘ ‘.join(str(x) for x in any_list)
3.从数据帧(单列)到列表
reviews_list = df["reviews"].values.tolist()
4.从文本到列表
这既简单又方便。
token_list = text.split()
5.从元组到数据帧
我上面提到过这个,在这里重复一下,以便更好地参考。
nltk.pos_tagmodule以元组的形式返回标签集(word,pos tag)。
data_tagset = nltk.pos_tag(tokens)
df_tagset = pd.DataFrame(data_tagset, columns=['Word', 'Tag'])
参考引用
往期精彩回顾 本站qq群851320808,加入微信群请扫码: