参考链接: Python | 用NLTK进行词干分析
一 提取词干
在英文中同一个词的形式是有多种的,名词的单数复数、动词的现在和过去式等等,所以在处理英文时要考虑词干的抽取问题。这里直接调用Nltk自带的两个词干抽取器
import re
import nltk
raw = """DENNIS: Listen, strange women lying in ponds distributing swords
is no basis for a system of government. Supreme executive power derives from
a mandate from the masses, not from some farcical aquatic ceremony."""
tokens = nltk.word_tokenize(raw) # 分词 如果该方法调用错误请运行 nltk.download('punkt')
porter = nltk.PorterStemmer()
print([porter.stem(t) for t in tokens])
lancaster = nltk.LancasterStemmer()
print([lancaster.stem(t) for t in tokens])
结果如下
porter:['denni', ':', 'listen', ',', 'strang', 'women', 'lie', 'in', 'pond', 'distribut', 'sword', 'is', 'no', 'basi', 'for', 'a', 'system', 'of', 'govern', '.', 'suprem', 'execut', 'power', 'deriv', 'from', 'a', 'mandat', 'from', 'the', 'mass', ',', 'not', 'from', 'some', 'farcic', 'aquat', 'ceremoni', '.'] lancaster:['den', ':', 'list', ',', 'strange', 'wom', 'lying', 'in', 'pond', 'distribut', 'sword', 'is', 'no', 'bas', 'for', 'a', 'system', 'of', 'govern', '.', 'suprem', 'execut', 'pow', 'der', 'from', 'a', 'mand', 'from', 'the', 'mass', ',', 'not', 'from', 'som', 'farc', 'aqu', 'ceremony', '.']
中文没有词干抽取的烦恼,中文应该关注于分词的结果(分词后面介绍,jieba,Hanlp等等各种各样的分词方法调用)
二 利用词干提取器,索引文章
当然你也可以直接用单词索引文章,但是用完词干提取器后索引的效果就更好了。
class IndexedText(object): # 首先定义了一个类
#初始化参数 stemmer是提取词干的方法,text待处理文本,self的作用大家可以直接忽视但是必不可少
def __init__(self, stemmer, text):
self._text = text # 将文本赋予变量self._text
self._stemmer = stemmer # 将提取词干的防范赋予self._stemmer
self._index = nltk.Index((self._stem(word), i) # 循环读取文本中的词,最后生成{词干1:(index1,index2,..)}的样式
for (i, word) in enumerate(text))
# 找出带处理词所处的index,然后提取index上下40个长度内的词
def concordance(self, word, width=40):
key = self._stem(word) # 提取待处理词的词干
wc = width//4 # 获取大概需要提取词的个数
for i in self._index[key]: # 循环开始获取上下文
lcontext = ' '.join(self._text[i-wc:i])
rcontext = ' '.join(self._text[i:i wc])
ldisplay = '%*s' % (width, lcontext[-width:]) # %*s右对齐,让打印出的长度是width
rdisplay = '%-*s' % (width, rcontext[:width]) # %-*s左对齐,让打印出的长度是width
print (ldisplay, rdisplay, '/n')
def _stem(self, word): # 词干提取并全部改为小写
return self._stemmer.stem(word).lower()
porter = nltk.PorterStemmer() # 定义词干提取的方法
grail = nltk.corpus.webtext.words('grail.txt') # 获取待处理的文本
text = IndexedText(porter, grail) # 实例化刚刚定义的类,同时将两个参数传入
text.concordance('lying') # 调用类中的找上下文的方法
结果如下,我的IDE是Spyder,为了让打印的结果更清晰,我在print()中加入了‘/n’让每一次打印后都换行。