【发布时间】:2019-10-09 00:51:02
【问题描述】:
我有一个 NLTK 解析函数,用于解析 TREC 数据集的 ~2GB 文本文件。该数据集的目标是对整个集合进行标记,执行一些计算(例如计算 TF-IDF 权重等),然后针对我们的集合运行一些查询以使用余弦相似度并返回最佳结果。
就目前而言,我的程序可以运行,但运行需要一个多小时(通常在 44-61 分钟之间)。时间细分如下:
TOTAL TIME TO COMPLETE: 4487.930628299713
TIME TO GRAB SORTED COSINE SIMS: 35.24157094955444
TIME TO CREATE TFIDF BY DOC: 57.06743311882019
TIME TO CREATE IDF LOOKUP: 0.5097501277923584
TIME TO CREATE INVERTED INDEX: 2.5217013359069824
TIME TO TOKENIZE: 4392.5711488723755
很明显,代币化占了约 98% 的时间。我正在寻找一种方法来加快速度。
标记化代码如下:
def remove_nums(arr):
pattern = '[0-9]'
arr = [re.sub(pattern, '', i) for i in arr]
return arr
def get_words(para):
stop_words = list(stopwords.words('english'))
words = RegexpTokenizer(r'\w+')
lower = [word.lower() for word in words.tokenize(para)]
nopunctuation = [nopunc.translate(str.maketrans('', '', string.punctuation)) for nopunc in lower]
no_integers = remove_nums(nopunctuation)
dirty_tokens = [data for data in no_integers if data not in stop_words]
tokens = [data for data in dirty_tokens if data.strip()]
def driver(file):
myfile = get_input(file)
p = r'<P ID=\d+>.*?</P>'
paras = RegexpTokenizer(p)
document_frequency = collections.Counter()
collection_frequency = collections.Counter()
all_lists = []
currWordCount = 0
currList = []
currDocList = []
all_doc_lists = []
num_paragraphs = len(paras.tokenize(myfile))
print()
print(" NOW BEGINNING TOKENIZATION ")
print()
for para in paras.tokenize(myfile):
group_para_id = re.match("<P ID=(\d+)>", para)
para_id = group_para_id.group(1)
tokens = get_words(para)
tokens = list(set(tokens))
collection_frequency.update(tokens)
document_frequency.update(set(tokens))
para = para.translate(str.maketrans('', '', string.punctuation))
currPara = para.lower().split()
for token in tokens:
currWordCount = currPara.count(token)
currList = [token, tuple([para_id, currWordCount])]
all_lists.append(currList)
currDocList = [para_id, tuple([token, currWordCount])]
all_doc_lists.append(currDocList)
d = {}
termfreq_by_doc = {}
for key, new_value in all_lists:
values = d.setdefault(key, [])
values.append(new_value)
for key, new_value in all_doc_lists:
values = termfreq_by_doc.setdefault(key, [])
values.append(new_value)
我对优化很陌生,正在寻找一些反馈。我确实看到this post 谴责我的许多列表理解为“邪恶”,但我想不出办法绕过我正在做的事情。
代码没有注释很好,所以如果由于某种原因无法理解,那也没关系。我在这个论坛上看到了其他问题:在没有很多反馈的情况下加速 NLTK 标记化,所以我希望有一个关于标记化优化编程实践的积极线程。
【问题讨论】:
-
我投票决定将此问题作为离题结束,因为应该在 codereview stackexchange 中代替。
-
强制“不要使用正则表达式解析 XML”:stackoverflow.com/a/1732454/1319284
-
不是 XML,但是谢谢
标签: python python-3.x optimization nltk tokenize