自然语言处理( NLP )就是开发能够理解人类语言的应用程序和服务。
自然语言处理的应用,包括语音识别,语音翻译,理解句意,理解特定词语的同义词,以及写出语法正确,句意通畅的句子和段落。
NLTK 是一个当下流行的,用于自然语言处理的 Python 库。
-
安装nltk库
要求python的版本必须为2.7及以上,直接使用pip安装
pip install nltk
-
检测并下载nltk的data包
进入python控制台
import nltk # 没有报错,说明安装nltk成功
nltk.download() # 弹出nltk的data包下载器
注意:
nltk_data下载,所有包大概3.2G,下载时间较长,可以根据需要下载所需要的部分即可
-
nltk_data的使用
在代码中使用nltk
import nltk
nltk.data.path.append("../nltk_data")
-
nltk实例应用
获取测试纯文本,nltk是针对英文的文本处理,获取php官方介绍,当作测试文本
既然我们用的是python,当然使用最简单的方法获取咯
爬虫获取php.net文本信息
# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import requests
from bs4 import BeautifulSoup
response = requests.get('http://php.net').text
text = BeautifulSoup(response, 'html.parser').text
with open('./php.txt', 'w') as f:
f.write(text.strip().replace('\n', ' '))
对文本进行分词,并统计词频
# coding: utf-8
import re
import nltk
file = open('./php.txt', 'r').read()
words = [x for x in re.split('[ ,.:]', file) if x != '']
# nltk 统计词频
fd = nltk.FreqDist(words)
for key, val in fd.items():
print key, val
fd.plot(20, cumulative=False)
# python 原生代码统计词频
# word_set = set(words)
# for word in word_set:
# print word, words.count(word)
print words
FreqDist方法:nltk中的词频统计方法,结果与python原生统计词频效果相同
plot方法:绘制词频图,使用此功能需要安装Matplotlib
Matplotlib与python版本的对应关系
这里的1.5.3好理解,就是matplotlib这个包的版本号,而cpXX这是指适用的python版本号。比如cp27是指适用于python2.7版本,cp35适用python35。win32、win amd64则分别指32位和64位操作系统。
可以直接使用pip命令安装对应的Matplotlib版本
去除stopwords后统计词频
# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import re
import copy
import nltk
nltk.data.path.append('../nltk_data')
from nltk.corpus import stopwords
file = open('./php.txt', 'r').read()
words = [x for x in re.split('[ ,.:]', file) if x != '']
# 去除stopwords
stop_words = copy.copy(words)
for word in set(words):
if word in stopwords.words('english'):
stop_words.remove(word)
fd = nltk.FreqDist(stop_words)
for key, val in fd.items():
print key, val
fd.plot(20, cumulative=False)
print len(words), len(stop_words)
使用nltk进行分词
# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import nltk
nltk.data.path.append('../nltk_data')
from nltk.tokenize import sent_tokenize, word_tokenize
file = open('./php.txt', 'r').read()
# nltk分句
sents = sent_tokenize(file)
for sent in sents:
print sent
# nltk分词
words = word_tokenize(file)
for word in words:
print word
相比于使用re模块进行分词统计,nltk的分词更加准确,它会把php.net等特殊词划分为一个词,而不会分开统计
配合stopwords使用,去除干扰词使结果更加精确
-
实例:使用nltk获取php.net中的分词,同义词,反义词
# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import re
import copy
import requests
from bs4 import BeautifulSoup
import nltk
nltk.data.path.append('../nltk_data')
from nltk.corpus import stopwords, wordnet
from nltk.stem import WordNetLemmatizer
from nltk.tokenize import sent_tokenize, word_tokenize
response = requests.get('http://php.net').text
text = BeautifulSoup(response, 'html.parser').text
# nltk 分句
# sents = sent_tokenize(text)
# for sent in sents:
# print sent
# nltk 分词
words = word_tokenize(text)
new_words = list(set(copy.copy(words)))
for word in set(words):
if word in stopwords.words('english') or not re.search('[a-zA-Z]{3,}', word):
new_words.remove(word)
# 词形还原
wnl_words = []
wnl_ = WordNetLemmatizer()
for nw in new_words:
nw = nw.lower()
nw = wnl_.lemmatize(nw)
if nw.endswith('ing') or nw.endswith('ed'):
nw = wnl_.lemmatize(nw, pos='v')
wnl_words.append(nw)
print wnl_words
# 获取同义词字典
syn_dict = {}
for word in wnl_words:
synonyms = []
for syn in wordnet.synsets(word):
for lemma in syn.lemmas():
synonyms.append(lemma.name())
if not synonyms:
continue
syn_dict[word] = synonyms
print syn_dict
# 获取反义词字典
anto_dict = {}
for word in wnl_words:
antonyms = []
for syn in wordnet.synsets(word):
for l in syn.lemmas():
if l.antonyms():
antonyms.append(l.antonyms()[0].name())
if not antonyms:
continue
anto_dict[word] = antonyms
print anto_dict
由于nltk中的stopwords不是并不全面,需要手动过滤一些词