如何在有效短句的大数据集中使用spacy?

时间:2018-01-11 03:28:16

标签: python nlp spacy

我选择spacy来处理各种文本,因为与nltk相比,它的表现与lelmat相比。但是当我处理数百万个短文本时,它总是耗尽我的所有内存(32G)并崩溃。没有它只需几分钟,消耗不到10G内存。

使用此方法有问题吗?是否有更好的解决方案来改善性能?谢谢!

def tokenizer(text):
    try:
        tokens = [ word for sent in sent_tokenize(text) for word in word_tokenize(sent)]
        tokens = list(filter(lambda t: t.lower() not in stop_words, tokens))
        tokens = list(filter(lambda t: t not in punctuation, tokens))
        tokens = list(filter(lambda t: len(t) > 4, tokens))
        filtered_tokens = []
        for token in tokens:
            if re.search('[a-zA-Z]', token):
                filtered_tokens.append(token)

        spacy_parsed = nlp(' '.join(filtered_tokens))
        filtered_tokens = [token.lemma_ for token in spacy_parsed]
        return filtered_tokens
    except Exception as e:
        raise e

Dask并行计算

ddata = dd.from_pandas(res, npartitions=50)
def dask_tokenizer(df):
    df['text_token'] = df['text'].map(tokenizer)
    return df
%time res_final = ddata.map_partitions(dask_tokenizer).compute(get=get)

有关spaCy的信息

spaCy version      2.0.5          
Location           /opt/conda/lib/python3.6/site-packages/spacy
Platform           Linux-4.4.0-103-generic-x86_64-with-debian-stretch-sid
Python version     3.6.3          
Models             en, en_default 

3 个答案:

答案 0 :(得分:3)

您可以在spacy中使用多线程来创建快速标记化和数据提取管道。

使用nlp.pipe方法重写代码块和功能将如下所示:

import spacy
nlp = spacy.load('en')

docs = df['text'].tolist()

def token_filter(token):
    return not (token.is_punct | token.is_space | token.is_stop | len(token.text) <= 4)

filtered_tokens = []
for doc in nlp.pipe(docs):
    tokens = [token.lemma_ for token in doc if token_filter(token)]
    filtered_tokens.append(tokens)

这种方式将所有过滤放入token_filter函数中,该函数接收spacy标记并仅在标点符号,空格,停用词和4个或更少字符时返回True。然后,当您遍历每个文档中的每个标记时,您将使用此函数,只有在满足所有这些条件时才会返回引理。然后,filtered_tokens是您的标记化文档列表。

自定义此管道的一些有用参考将是:

答案 1 :(得分:2)

您应该在解析后过滤掉标记。通过这种方式,训练好的模型将提供更好的标记(除非它是以类似方式过滤的文本训练,这是不可能的)。 此外,之后进行过滤可以使用nlp.pipe,这被告知速度很快。请参阅http://spacy.io/usage/spacy-101#lightning-tour-multi-threaded上的nlp.pipe示例。

答案 2 :(得分:-1)

此答案基于pmbaumgartner的答案;谢谢pmbaumgartner。可能会有空格或多余的单词;最好使用postags删除空白并根据您要查找的内容过滤令牌:

import spacy

nlp = spacy.load('en')
allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV'] # or any other types

docs = df['text'].tolist()

def token_filter(token):    
    return (token.pos_ in allowed_postags) & (not (token.is_punct | token.is_space | 
    token.is_stop | len(token.text) <= 2))

filtered_tokens = []
for doc in nlp.pipe(docs):
    tokens = [token.lemma_ for token in doc if token_filter(token)]
    filtered_tokens.append(tokens)