NLTK文本预处理与文本分析

本文主要介绍Python中NLTK文本分析的内容,咱先来看看文本分析的整个流程:

原始文本 - 分词 - 词性标注 - 词形归一化 - 去除停用词 - 去除特殊字符 - 单词大小写转换 - 文本分析

一、分词

使用DBSCAN聚类算法的英文介绍文本为例:

from nltk import word_tokenize
sentence = "DBSCAN - Density-Based Spatial Clustering of Applications with Noise. Finds core samples of high density and expands clusters from them. Good for data which contains clusters of similar density "
token_words = word_tokenize(sentence)
print(token_words)

输出分词结果:

['DBSCAN', '-', 'Density-Based', 'Spatial', 'Clustering', 'of', 'Applications', 'with', 'Noise', '.', 'Finds', 'core', 'samples', 'of', 'high', 'density', 'and', 'expands', 'clusters', 'from', 'them', '.', 'Good', 'for', 'data', 'which', 'contains', 'clusters', 'of', 'similar', 'density']

二、词性标注

为什么要进行词性标注?咱先来看看不做词性标注,直接按照第一步分词结果进行词形归一化的情形:

常见词形归一化有两种方式(词干提取与词形归并):

1、词干提取

from nltk.stem.lancaster import LancasterStemmer
lancaster_stemmer = LancasterStemmer()
words_stemmer = [lancaster_stemmer.stem(token_word) for token_word in token_words]
print(words_stemmer)

输出结果:

['dbscan', '-', 'density-based', 'spat', 'clust', 'of', 'apply', 'with', 'nois', '.', 'find', 'cor', 'sampl', 'of', 'high', 'dens', 'and', 'expand', 'clust', 'from', 'them', '.', 'good', 'for', 'dat', 'which', 'contain', 'clust', 'of', 'simil', 'dens']

说明:词干提取默认提取单词词根,容易得出一些不具实际意义的单词,比如上面的”Spatial“变为”spat“,”Noise“变为”nois“,在常规文本分析中没意义,在信息检索中用该方法会比较合适。

2、词形归并(单词变体还原)

from nltk.stem import WordNetLemmatizer
wordnet_lematizer = WordNetLemmatizer()
words_lematizer = [wordnet_lematizer.lemmatize(token_word) for token_word in token_words]
print(words_lematizer)

输出结果:

['DBSCAN', '-', 'Density-Based', 'Spatial', 'Clustering', 'of', 'Applications', 'with', 'Noise', '.', 'Finds', 'core', 'sample', 'of', 'high', 'density', 'and', 'expands', 'cluster', 'from', 'them', '.', 'Good', 'for', 'data', 'which', 'contains', 'cluster', 'of', 'similar', 'density']

说明:这种方法主要在于将过去时、将来时、第三人称等单词还原为原始词,不会产生词根这些无意义的单词,但是仍存在有些词无法还原的情况,比如“Finds”、“expands”、”contains“仍是第三人称的形式,原因在于wordnet_lematizer.lemmatize函数默认将其当做一个名词,以为这就是单词原型,如果我们在使用该函数时指明动词词性,就可以将其变为”contain“了。所以要先进行词性标注获取单词词性(详情如下)。

3、词性标注

先分词,再词性标注:

from nltk import word_tokenize,pos_tag
sentence = "DBSCAN - Density-Based Spatial Clustering of Applications with Noise. Finds core samples of high density and expands clusters from them. Good for data which contains clusters of similar density"
token_word = word_tokenize(sentence)  #分词
token_words = pos_tag(token_word)     #词性标注
print(token_words)

输出结果:

[('DBSCAN', 'NNP'), ('-', ':'), ('Density-Based', 'JJ'), ('Spatial', 'NNP'), ('Clustering', 'NNP'), ('of', 'IN'), ('Applications', 'NNP'), ('with', 'IN'), ('Noise', 'NNP'), ('.', '.'), ('Finds', 'NNP'), ('core', 'NN'), ('samples', 'NNS'), ('of', 'IN'), ('high', 'JJ'), ('density', 'NN'), ('and', 'CC'), ('expands', 'VBZ'), ('clusters', 'NNS'), ('from', 'IN'), ('them', 'PRP'), ('.', '.'), ('Good', 'JJ'), ('for', 'IN'), ('data', 'NNS'), ('which', 'WDT'), ('contains', 'VBZ'), ('clusters', 'NNS'), ('of', 'IN'), ('similar', 'JJ'), ('density', 'NN')]

说明:列表中每个元组第二个元素显示为该词的词性,具体每个词性注释可运行代码”nltk.help.upenn_tagset()“或参看说明文档:词性标签说明

三、词形归一化(指明词性)

from nltk.stem import WordNetLemmatizer
words_lematizer = []
wordnet_lematizer = WordNetLemmatizer()
for word, tag in token_words:
    if tag.startswith('NN'):
        word_lematizer =  wordnet_lematizer.lemmatize(word, pos='n')  # n代表名词
    elif tag.startswith('VB'): 
        word_lematizer =  wordnet_lematizer.lemmatize(word, pos='v')   # v代表动词
    elif tag.startswith('JJ'): 
        word_lematizer =  wordnet_lematizer.lemmatize(word, pos='a')   # a代表形容词
    elif tag.startswith('R'): 
        word_lematizer =  wordnet_lematizer.lemmatize(word, pos='r')   # r代表代词
    else: 
        word_lematizer =  wordnet_lematizer.lemmatize(word)
    words_lematizer.append(word_lematizer)
print(words_lematizer)

输出结果:

['DBSCAN', '-', 'Density-Based', 'Spatial', 'Clustering', 'of', 'Applications', 'with', 'Noise', '.', 'Finds', 'core', 'sample', 'of', 'high', 'density', 'and', 'expand', 'cluster', 'from', 'them', '.', 'Good', 'for', 'data', 'which', 'contain', 'cluster', 'of', 'similar', 'density']

说明:可以看到单词变体已经还原成单词原型,如“Finds”、“expands”、”contains“均已变为各自的原型。

四、去除停用词

经过分词与词形归一化之后,得到各个词性单词的原型,但仍存在一些无实际意义的介词、量词等在文本分析中不重要的词(这类词在文本分析中称作停用词),需要将其去除。

from nltk.corpus import stopwords 
cleaned_words = [word for word in words_lematizer if word not in stopwords.words('english')]
print('原始词:', words_lematizer)
print('去除停用词后:', cleaned_words)

输出结果:

原始词: ['DBSCAN', '-', 'Density-Based', 'Spatial', 'Clustering', 'of', 'Applications', 'with', 'Noise', '.', 'Finds', 'core', 'sample', 'of', 'high', 'density', 'and', 'expand', 'cluster', 'from', 'them', '.', 'Good', 'for', 'data', 'which', 'contain', 'cluster', 'of', 'similar', 'density']
去除停用词后: ['DBSCAN', '-', 'Density-Based', 'Spatial', 'Clustering', 'Applications', 'Noise', '.', 'Finds', 'core', 'sample', 'high', 'density', 'expand', 'cluster', '.', 'Good', 'data', 'contain', 'cluster', 'similar', 'density']

说明:of、for、and这类停用词已被去除。

五、去除特殊字符

标点符号在文本分析中也是不需要的,也将其剔除,这里我们采用循环列表判断的方式来剔除,可自定义要去除的标点符号、要剔除的特殊单词也可以放在这将其剔除,比如咱将"DBSCAN"也连同标点符号剔除。

characters = [',', '.','DBSCAN', ':', ';', '?', '(', ')', '[', ']', '&', '!', '*', '@', '#', '$', '%','-','...','^','{','}']
words_list = [word for word in cleaned_words if word not in characters]
print(words_list)

输出结果:

['Density-Based', 'Spatial', 'Clustering', 'Applications', 'Noise', 'Finds', 'core', 'sample', 'high', 'density', 'expand', 'cluster', 'Good', 'data', 'contain', 'cluster', 'similar', 'density']

说明:处理后的单词列表已不存在“-”、“.”等特殊字符。

六、大小写转换

为防止同一个单词同时存在大小写而算作两个单词的情况,还需要统一单词大小写(此处统一为小写)。

words_lists = [x.lower() for x in words_list ]
print(words_lists)

输出结果:

['density-based', 'spatial', 'clustering', 'applications', 'noise', 'finds', 'core', 'sample', 'high', 'density', 'expand', 'cluster', 'good', 'data', 'contain', 'cluster', 'similar', 'density']

七、文本分析

经以上六步的文本预处理后,已经得到干净的单词列表做文本分析或文本挖掘(可转换为DataFrame之后再做分析)。

统计词频(这里我们以统计词频为例):

from nltk import FreqDist    
freq = FreqDist(words_lists)   
for key,val in freq.items():
    print (str(key) + ':' + str(val))

输出结果:

density-based:1
spatial:1
clustering:1
applications:1
noise:1
finds:1
core:1
sample:1
high:1
density:2
expand:1
cluster:2
good:1
data:1
contain:1
similar:1

可视化(折线图):

freq.plot(20,cumulative=False)
词频

可视化(词云):

绘制词云需要将单词列表转换为字符串

words = ' '.join(words_lists)
words

输出结果:

'density-based spatial clustering applications noise finds core sample high density expand cluster good data contain cluster similar density'

绘制词云

from wordcloud import WordCloud
from imageio import imread
import matplotlib.pyplot as plt
pic = imread('./picture/china.jpg')
wc = WordCloud(mask = pic,background_color = 'white',width=800, height=600)
wwc = wc.generate(words)
plt.figure(figsize=(10,10))
plt.imshow(wwc)
plt.axis("off")
plt.show()
词频

文本分析结论:根据折线图或词云,咱可以直观看到“density”与“cluster”两个单词出现最多,词云中字体越大。

谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350

推荐阅读更多精彩内容

  • 2018.06.13 星期三 天气:雨加冰雹 今天干活时,他们在聊天,一位说他去干活,老板多给...
    三七李心宇妈妈阅读 357评论 2 3
  • 初三迎喜神之后,年的气息便开始散去,直至恢复平常。唯有远处时不时的炮声,不厌其烦的诉说着节日的欢快,也在激发着小孩...
    厚朴HOPE_阅读 332评论 0 3
  • 电视开在高尔夫频道,有一眼没一眼地看着比赛。二杯白葡萄酒下了肚,微醺正好,但第三杯继续。两个炉子上炖着好吃的银耳红...
    枫叶国的雪君阅读 343评论 0 0