2 文本数据的预处理
到目前为止,我们已经学会了如何从文本数据中提取基本特征。深入文本和特征提取之前,我们的第一步应该是清洗数据,以获得更好的特性。
我们将实现这一目标做一些基本的训练数据预处理步骤。
2.1 小写转化
预处理的第一步,我们要做的是把我们的推文变成小写。这避免了拥有相同的多个副本。例如,当我们计算字词汇数量时,“Analytics”和“analytics”将被视为不同的单词。
train['tweet']=train['tweet'].apply(lambda sen:" ".join(x.lower() for x in sen.split())) train['tweet'].head()
0 @user when a father is dysfunctional and is so... 1 @user @user thanks for #lyft credit i can't us... 2 bihday your majesty 3 #model i love u take with u all the time in ur... 4 factsguide: society now #motivation Name: tweet, dtype: object
2.2 去除标点符号
下一步是去除标点符号,因为它在文本数据中不添加任何额外的信息。因此删除的所有符号将帮助我们减少训练数据的大小。
train['tweet'] = train['tweet'].str.replace('[^\w\s]','') train['tweet'].head()
0 user when a father is dysfunctional and is so ... 1 user user thanks for lyft credit i cant use ca... 2 bihday your majesty 3 model i love u take with u all the time in urð... 4 factsguide society now motivation Name: tweet, dtype: object
正如你所看到的在上面的输出中,所有的标点符号,包括"#"和"@"已经从训练数据中去除
2.3 停用词去除
正如我们前面所讨论的,停止词(或常见单词)应该从文本数据中删除。为了这个目的,我们可以创建一个列表stopwords作为自己停用词库或我们可以使用预定义的库。
from nltk.corpus import stopwords stop=stopwords.words('english') train['tweet']=train['tweet'].apply(lambda sen:" ".join(x for x in sen.split() if x not in stop)) train['tweet'].head()
0 user father dysfunctional selfish drags kids d... 1 user user thanks lyft credit cant use cause do... 2 bihday majesty 3 model love u take u time urð ðððð ððð 4 factsguide society motivation Name: tweet, dtype: object
2.4 常见词去除
我们可以把常见的单词从文本数据首先,让我们来检查中最常出现的10个字文本数据然后再调用删除或保留。
freq=pd.Series(' '.join(train['tweet']).split()).value_counts()[:10] freq
user 17473 love 2647 ð 2511 day 2199 â 1797 happy 1663 amp 1582 im 1139 u 1136 time 1110 dtype: int64
现在我们把这些词去除掉,因为它们对我们文本数据分类没有任何作用
freq=list(freq.index) freq
['user', 'love', 'ð', 'day', 'â', 'happy', 'amp', 'im', 'u', 'time']
train['tweet']=train['tweet'].apply(lambda sen:' '.join(x for x in sen.split() if x not in freq)) train['tweet'].head()
0 father dysfunctional selfish drags kids dysfun... 1 thanks lyft credit cant use cause dont offer w... 2 bihday majesty 3 model take urð ðððð ððð 4 factsguide society motivation Name: tweet, dtype: object
2.5 稀缺词去除
同样,正如我们删除最常见的话说,这一次让我们从文本中删除很少出现的词。因为它们很稀有,它们之间的联系和其他词主要是噪音。可以替换罕见的单词更一般的形式,然后这将有更高的计数。
freq = pd.Series(' '.join(train['tweet']).split()).value_counts()[-10:] freq
happenedâ 1 britmumspics 1 laterr 1 2230 1 dkweddking 1 ampsize 1 moviescenes 1 kaderimsin 1 nfinity 1 babynash 1 dtype: int64
freq = list(freq.index) train['tweet'] = train['tweet'].apply(lambda x: " ".join(x for x in x.split() if x not in freq)) train['tweet'].head()
0 father dysfunctional selfish drags kids dysfun... 1 thanks lyft credit cant use cause dont offer w... 2 bihday majesty 3 model take urð ðððð ððð 4 factsguide society motivation Name: tweet, dtype: object
所有这些预处理步骤是必不可少的,帮助我们减少我们的词汇噪音,这样最终产生更有效的特征。
2.6 拼写校对
我们都见过推文存在大量的拼写错误。我们再短时间内匆忙发送tweet,很难发现这些错误。在这方面,拼写校正是一个有用的预处理步骤,因为这也会帮助我们减少单词的多个副本。例如,“Analytics”和“analytcs”将被视为不同的单词,即使它们在同一意义上使用。
为实现这一目标,我们将使用textblob库。
TextBlob是一个用Python编写的开源的文本处理库。它可以用来执行很多自然语言处理的任务,比如,词性标注,名词性成分提取,情感分析,文本翻译,等等。你可以在官方文档阅读TextBlog的所有特性。
from textblob import TextBlob train['tweet'][:5].apply(lambda x: str(TextBlob(x).correct()))
0 father dysfunctional selfish drags kiss dysfun... 1 thanks left credit can use cause dont offer wh... 2 midday majesty 3 model take or ðððð ððð 4 factsguide society motivation Name: tweet, dtype: object
注意,它会花费很多时间去做这些修正。因此,为了学习的目的,我只显示这种技术运用在前5行的效果。
另外在使用这个技术之前,需要小心一些,因为如果推文中存在大量缩写,比如“your”缩写为“ur”,那么将修正为“or”
2.7 分词
分词是指将文本划分为一系列的单词或词语。在我们的示例中,我们使用了textblob库
TextBlob(train['tweet'][1]).words
WordList(['thanks', 'lyft', 'credit', 'cant', 'use', 'cause', 'dont', 'offer', 'wheelchair', 'vans', 'pdx', 'disapointed', 'getthanked'])
2.8 词干提取
词形还原(lemmatization),是把一个任何形式的语言词汇还原为一般形式(能表达完整语义),而词干提取
(stemming)是抽取词的词干或词根形式(不一定能够表达完整语义)。词形还原和词干提取是词形规范化的两类重要方式,都能够达到有效归并词形的目的,二者既有联系也有区别。具体介绍请参考词干提取(stemming)和词形还原(lemmatization)
词干提取(stemming)是指通过基于规则的方法去除单词的后缀,比如“ing”,“ly”,“s”等等。
from nltk.stem import PorterStemmer st=PorterStemmer() train['tweet'][:5].apply(lambda x:" ".join([st.stem(word) for word in x.split()]))
0 father dysfunct selfish drag kid dysfunct run 1 thank lyft credit cant use caus dont offer whe... 2 bihday majesti 3 model take urð ðððð ððð 4 factsguid societi motiv Name: tweet, dtype: object
在上面的输出中,“dysfunctional ”已经变为“dysfunct ”
2.9 词性还原
词形还原处理后获得的结果是具有一定意义的、完整的词,一般为词典中的有效词
from textblob import Word train['tweet']=train['tweet'].apply(lambda x:" ".join([Word(word).lemmatize() for word in x.split()])) train['tweet'].head()
0 father dysfunctional selfish drag kid dysfunct... 1 thanks lyft credit cant use cause dont offer w... 2 bihday majesty 3 model take urð ðððð ððð 4 factsguide society motivation Name: tweet, dtype: object