我试图用标点符号来获取文本,因为在我的doc2vec模型中考虑后者是很重要的。但是,wikicorpus只检索文本。搜索网页后,我找到了以下网页:
我决定使用第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
然后,我使用了Pan Yang(link)的另一个代码。此代码启动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")
通过命令行我运行了process_wiki.py代码。我在命令提示符中输入了最后一行语料库的文本:
(2018-06-05 09:18:16,480:INFO:已完成保存4526191篇)
当我在python中读取文件时,我检查了第一篇文章,它没有标点符号。例:
(无政府主义是一种主张基于自愿制度的自治社会的政治哲学,这些社会通常被描述为无国籍社会,尽管有几位作者将其更具体地定义为基于非等级或自由联合的制度,无政府主义认为国家是不必要的有害和有害的。对国家的反对是中央无政府主义,特别需要反对权威或等级制度)
我的两个相关问题,我希望你能帮助我,请:
非常感谢你花时间阅读这篇长篇文章。
最好的祝愿,
Ghulams
问题在于您定义的tokenize func
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('_')]
func utils.tokenize(content,lower = True,errors ='ignore')简单地将文章标记为标记列表。但是,在... / site-packages / gensim / utils.py中实现此func会忽略标点符号。
例如,当你调用utils.tokenize(“我爱吃香蕉,苹果”)时,它会返回[“我”,“爱”,“吃”,“香蕉”,“苹果”]
无论如何,您可以定义自己的tokenize func,如下所示,以保留标点符号。
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('_')]
在gensim / utils.py中,您可以找到该方法
def save_as_line_sentence(corpus, filename):
with smart_open(filename, mode='wb', encoding='utf8') as fout:
for sentence in corpus:
line = any2unicode(' '.join(sentence) + '\n')
fout.write(line)
您可以使用将语料库写入文本文件。您可以覆盖它或将其作为示例并编写您自己的版本(可能您希望在每个标点处打破行)
def save_sentence_each_line(corpus, filename):
with utils.smart_open(filename, mode='wb', encoding='utf8') as fout:
for sentence in corpus:
line = utils.any2unicode(' '.join(sentence) + '\n')
line = line.replace('. ', '\n').replace('!', '\n').replace('?', '\n') # <- !!
...
你可以称之为
save_sentence_each_line(wiki.get_texts(), out_f)
但是你也需要从utils覆盖PAT_ALPHABETIC,因为标点符号被删除的地方:
PAT_ALPHABETIC = re.compile(r'(((?![\d])[\w\\.\\!\\?])+)', re.UNICODE)
然后,您可能需要覆盖utils.tokenize和utils.simple_tokenize,以防您想要对代码进行进一步更改。