我有一个过程,类似于:
问题是(大概是因为标记化首先发生的事实?)多个单词的停止词(短语)不会被删除。在
完整示例:
import re
import nltk
from nltk.stem import WordNetLemmatizer
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS as ESW, CountVectorizer
# Make sure we have the corpora used by nltk's lemmatizer
try:
nltk.data.find('corpora/wordnet')
except:
nltk.download('wordnet')
# "Naive" token similar to that used by sklearn
TOKEN = re.compile(r'\b\w{2,}\b')
# Tokenize, then lemmatize these tokens
# Modified from:
# http://scikit-learn.org/stable/modules/feature_extraction.html#customizing-the-vectorizer-classes
class LemmaTokenizer(object):
def __init__(self):
self.wnl = WordNetLemmatizer()
def __call__(self, doc):
return (self.wnl.lemmatize(t) for t in TOKEN.findall(doc))
# Add 1 more phrase to sklearn's stop word list
sw = ESW.union(frozenset(['sinclair broadcast group']))
vect = CountVectorizer(stop_words=sw, ngram_range=(1, 4),
tokenizer=LemmaTokenizer())
# These are nonsense babbling
docs = ["""And you ask Why You Are Sinclair Broadcast Group is Asking It""",
"""Why are you asking what Sinclair Broadcast Group and you"""]
tf = vect.fit_transform(docs)
重申:已适当删除了单个单词的停止词,但短语仍然是:
^{pr2}$我该怎么更正?在
来自the documentation of ^{} :
再往下看参数
token_pattern
:因此,只有当
analyzer(token)
的结果等于'sinclair broadcast group'
时,它才会删除停止字。但是默认的analyzer
是'word'
,这意味着停止单词检测只适用于单个单词,因为如上所述,标记是由默认的token_pattern
定义的。在令牌不是n个gram(相反,n个gram是由令牌组成的,在构造n个gram之前,停止字移除似乎发生在令牌级别)。在
作为一个快速检查,您可以将您的自定义stopword更改为
'sinclair'
,以便在将其视为独立单词时正确删除该单词。在换句话说,您需要将自己的callable作为
analyzer
传递给它,以便它也将分析器逻辑应用于n-gram,您必须手动进行检查。但默认行为假设stopword detection不能应用于n-gram,只适用于单个单词。在下面是针对您的案例的自定义分析器函数的示例。这是based on this answer。。。注意,我没有测试它,所以可能有bug。在
这是一个适合我的自定义分析器。它有点老套,但实际上只需一步就可以完成所有文本处理,而且速度相当快:
相关问题 更多 >
编程相关推荐