使它更快地缩编(PyMorphy2,PyMystem3和一些魔术)

我是一名程序员,包括与文本分析有关的机器学习。处理自然语言时,需要进行文档的初步准备,其中一种方法是去词义化-考虑到上下文,将文本的所有单词恢复为正常形式。

最近,我们面临着此过程的大量时间成本的问题。在一个特定的任务中,有超过100,000个文档,平均长度约为1000个字符,因此有必要在常规本地计算机上进行处理,而不是在我们的服务器上进行计算。我们无法在Internet上找到解决方案,但我们自己找到了它,我想与大家分享-在本文中对两种最受欢迎​​的词形库进行比较分析。



变形2


最受欢迎的软件之一是PyMorphy2-几乎可以在网络上找到的每个解决方案中找到它。我们还使用了这个库,它完美地展示了自己,直到需要对整个数据库进行lemmatization(如我上面所写的,这些都是10万多个小文档)。为了分析如此大量的文档,PyMorphy2将花费近10个小时,而这段时间处理器负载平均大约为30%(Intel Core i7 7740X)。

Pymystem3


为了寻找另一种解决方案,我们分析了Yandex PyMystem3中的库,但结果(时间上)几乎比PyMorphy2差两倍:处理10万个文档需要16个小时。

一些魔术


对于我们来说,处理器的负载几乎为零似乎很奇怪。同样奇怪的是,为了从一个文本(甚至是一个大文本(3-4 000个字符))获得结果,PyMystem3花费了大约1秒的时间。因此,我们决定通过在文本之间添加某种分隔符来组合文本,从而可以再次返回文档列表的结构并将其提供给词条化。

Python解决方案代码:

def checkExecTimeMystemOneText(texts):
    lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)]
    txtpart = lol(texts, 1000)
    res = []
    for txtp in txtpart:
        alltexts = ' '.join([txt + ' br ' for txt in txtp])

        words = mystem.lemmatize(alltexts)
        doc = []
        for txt in words:
            if txt != '\n' and txt.strip() != '':
                if txt == 'br':
                    res.append(doc)
                    doc = []
                else:
                    doc.append(txt)

我们为工会准备了1000个文档,每个文档之间的分隔符为“ br”(应注意,以前删除的是俄语,拉丁字母和特殊字符)。该解决方案极大地加速了词根还原:平均而言,对于所有10万份文档而言,大约需要25分钟,处理器负载为20%至40%。的确,此解决方案会加载更多RAM:平均大约3-7GB,但这是一个很好的结果。如果没有足够的内存,则可以更改要合并的文档数量,尽管这会减慢处理速度,但仍然比一次文本快得多。另外,如果内存量允许,则可以增加该值并使结果更快。

下表显示了在本地计算机(Intel Core i7 7740X,32 GB RAM)上处理过程中库的比较:
方法时间内存(Mb)百分
变形2〜9.5小时500-60025-30%
PyMystem3由1句子〜16小时500-7000-1%
PyMystem3有1000个报价26分钟2000年-7000年25-40%

了解其他专家的观点很有趣。也许有人找到了一种使短文本定形的更省时的方法?

Mikhail Kabakov,高级软件工程师,
Anna Mikhailova
,Codex联盟数据挖掘主管

All Articles