如何使用 gensim wikicorpus 获取带有标点符号的维基百科语料库文本?

Gha*_*mus 6 python nlp gensim doc2vec

我正在尝试获取带有标点符号的文本,因为在我的 doc2vec 模型中考虑后者很重要。然而,维基语料库只检索文本。在网上搜索后,我找到了这些页面:

  1. 来自 gensim github 问题部分的页面。这是某个人提出的问题,答案是对 WikiCorpus 进行子类化(由 Piskvorky 回答)。幸运的是,在同一页面中,有一个代表建议的“子类”解决方案的代码。代码由 Rhazegh 提供。(链接
  2. 来自 stackoverflow 的页面,标题为:“在解析 wiki 语料库时禁用 Gensim 删除标点符号等”。但是,没有提供明确的答案,并在 spaCy 的上下文中进行了处理。(链接

我决定使用第 1 页中提供的代码。我当前的代码 (mywikicorpus.py):

import sys
import os
sys.path.append('C:\\Users\\Ghaliamus\\Anaconda2\\envs\\wiki\\Lib\\site-packages\\gensim\\corpora\\')

from wikicorpus import *

def tokenize(content):
    # override original method in wikicorpus.py
    return [token.encode('utf8') for token in utils.tokenize(content, lower=True, errors='ignore')
        if len(token) <= 15 and not token.startswith('_')]

def process_article(args):
   # override original method in wikicorpus.py
    text, lemmatize, title, pageid = args
    text = filter_wiki(text)
    if lemmatize:
        result = utils.lemmatize(text)
    else:
        result = tokenize(text)
    return result, title, pageid


class MyWikiCorpus(WikiCorpus):
def __init__(self, fname, processes=None, lemmatize=utils.has_pattern(), dictionary=None, filter_namespaces=('0',)):
    WikiCorpus.__init__(self, fname, processes, lemmatize, dictionary, filter_namespaces)

    def get_texts(self):
        articles, articles_all = 0, 0
        positions, positions_all = 0, 0
        texts = ((text, self.lemmatize, title, pageid) for title, text, pageid in extract_pages(bz2.BZ2File(self.fname), self.filter_namespaces))
        pool = multiprocessing.Pool(self.processes)
        for group in utils.chunkize(texts, chunksize=10 * self.processes, maxsize=1):
            for tokens, title, pageid in pool.imap(process_article, group):  # chunksize=10):
                articles_all += 1
                positions_all += len(tokens)
            if len(tokens) < ARTICLE_MIN_WORDS or any(title.startswith(ignore + ':') for ignore in IGNORED_NAMESPACES):
                continue
            articles += 1
            positions += len(tokens)
            if self.metadata:
                yield (tokens, (pageid, title))
            else:
                yield tokens
    pool.terminate()

    logger.info(
        "finished iterating over Wikipedia corpus of %i documents with %i positions"
        " (total %i articles, %i positions before pruning articles shorter than %i words)",
        articles, positions, articles_all, positions_all, ARTICLE_MIN_WORDS)
    self.length = articles  # cache corpus length
Run Code Online (Sandbox Code Playgroud)

然后,我使用了 Pan Yang 的另一个代码(链接)。此代码启动 WikiCorpus 对象并检索文本。我当前代码中唯一的变化是启动 MyWikiCorpus 而不是 WikiCorpus。代码(process_wiki.py):

from __future__ import print_function
import logging
import os.path
import six
import sys
import mywikicorpus as myModule



if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])
    logger = logging.getLogger(program)

    logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))

    # check and process input arguments
    if len(sys.argv) != 3:
        print("Using: python process_wiki.py enwiki-20180601-pages-    articles.xml.bz2 wiki.en.text")
        sys.exit(1)
    inp, outp = sys.argv[1:3]
    space = " "
    i = 0

    output = open(outp, 'w')
    wiki = myModule.MyWikiCorpus(inp, lemmatize=False, dictionary={})
    for text in wiki.get_texts():
        if six.PY3:
            output.write(bytes(' '.join(text), 'utf-8').decode('utf-8') + '\n')
        else:
            output.write(space.join(text) + "\n")
        i = i + 1
        if (i % 10000 == 0):
            logger.info("Saved " + str(i) + " articles")

    output.close()
    logger.info("Finished Saved " + str(i) + " articles")
Run Code Online (Sandbox Code Playgroud)

通过命令行,我运行了 process_wiki.py 代码。我在命令提示符的最后一行得到了语料库的文本:

(2018-06-05 09:18:16,480: INFO: Finished Saved 4526191 文章)

当我在python中阅读文件时,我检查了第一篇文章,它没有标点符号。例子:

(无政府主义是一种政治哲学,提倡基于自愿机构的自治社会,这些社会通常被描述为无国籍社会,尽管一些作者更具体地将它们定义为基于非等级或自由协会的机构。无政府主义认为国家是不可取的、不必要的和有害的反对国家是中央无政府主义,特别是需要反对权威或等级)

我的两个相关问题,我希望你能帮我解决,请:

  1. 我上面报告的管道有什么问题吗?
  2. 不管这样的管道,如果我打开 gensim wikicorpus python 代码(wikicorpus.py)并想编辑它,我应该添加或删除它或更新它的行是什么(如果可能的话)以获得相同的结果但是带标点?

非常感谢您花时间阅读这篇长文。

最好的祝愿,

加利亚姆斯

Mai*_*ong 3

问题在于您定义的 tokenize 函数

def tokenize(content):
    return [token.encode('utf8') for token in utils.tokenize(content, 
            lower=True, errors='ignore') if len(token) <= 15 and not 
            token.startswith('_')]
Run Code Online (Sandbox Code Playgroud)

func utils.tokenize(content, lower=True, error='ignore') 只是将文章标记为标记列表。但是,.../site-packages/gensim/utils.py 中该函数的实现忽略了标点符号。

例如,当您调用 utils.tokenize("我喜欢吃香蕉,苹果") 时,它返回 ["I", "love","eating","banana","apple"]

无论如何,您可以定义自己的 tokenize 函数,如下所示以保留标点符号。

def tokenize(content):
    #override original method in wikicorpus.py
    return [token.encode('utf8') for token in content.split() 
           if len(token) <= 15 and not token.startswith('_')]
Run Code Online (Sandbox Code Playgroud)

  • 虽然此代码可以回答问题,但提供有关如何以及为何解决问题的信息可以提高其长期价值。 (4认同)