Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种更快的方法来循环一个集合并替换句子中的MWEpython_Python_Loops_Dictionary_Set_Nlp - Fatal编程技术网

有没有一种更快的方法来循环一个集合并替换句子中的MWEpython

有没有一种更快的方法来循环一个集合并替换句子中的MWEpython,python,loops,dictionary,set,nlp,Python,Loops,Dictionary,Set,Nlp,任务是对由多个单词组成的表达式进行分组(也称为多单词表达式) 给定一个MWE字典,我需要在检测到MWE的输入句子中添加破折号,例如 **Input:** i have got an ace of diamonds in my wet suit . **Output:** i have got an ace-of-diamonds in my wet-suit . 目前,我循环浏览已排序的词典,查看MWE是否出现在句子中,并在出现时替换它们。但是有很多浪费的迭代 有没有更好的办法?一种解决方案是

任务是对由多个单词组成的表达式进行分组(也称为
多单词表达式

给定一个MWE字典,我需要在检测到MWE的输入句子中添加破折号,例如

**Input:** i have got an ace of diamonds in my wet suit .
**Output:** i have got an ace-of-diamonds in my wet-suit .
目前,我循环浏览已排序的词典,查看MWE是否出现在句子中,并在出现时替换它们。但是有很多浪费的迭代

有没有更好的办法?一种解决方案是首先产生所有可能的n克,即
chunker2()


我会尝试这样做:

  • 对于每个句子,构造一组n-gram,长度不超过给定长度(列表中最长的MWE)
  • 现在,只需执行
    mwe\u nmgrams.intersection(句子图)
    并搜索/替换它们
您不必通过迭代原始集合中的所有项来浪费时间


下面是一个稍微快一点的
chunker2

def chunker3(sentence):
    tokens = sentence.split(' ')
    len_tokens = len(tokens)
    nodes = set()

    for i in xrange(0, len_tokens):
        for j in xrange(i, len_tokens):
            chunks = tokens[i:j]

            if len(chunks) > 1:
                nodes.add(' '.join(chunks))

    intersect = mwe_list.intersection(n)

    for i in intersect:
        print i
        sentence = sentence.replace(i, i.replace(' ', '-'))

    return sentence

首先,一个2倍的改进:因为您要用连字符版本替换mwe,所以可以预处理字典(wn mwe en.dic)以消除集合中mwe中的所有连字符,从而消除一个字符串比较。如果您允许在句子中使用连字符,那么您还必须对其进行预处理,可能是在线处理,以获得较小的惩罚。这将把你的运行时间减少一半

接下来是一个小的改进:不可变元组通常比集合或列表更快(集合或列表是可变的,迭代器必须在每个步骤中检查内存中元素的移动)。set()转换将按照您的意愿消除重复项。元组位将把它固定在内存中,允许python解释器及其编译的LIB进行低级迭代优化

最后,在进行所有比较之前,您可能应该将句子和MWE解析为单词或标记,这将减少单词平均长度所需的字符串比较(如果单词平均长度为4个字符,则为4倍)。您还可以嵌套另一个循环来搜索MWE中的第一个单词,作为共享该第一个单词的所有MWE的锚点,从而减少所需字符串比较的长度。但我将把这大部分留给你们在真实数据上的实验。根据intepreter与编译库的效率,在python级别执行所有这些拆分嵌套循环实际上可能会降低速度

下面是前两个简单的“确定”赌注的结果。除非你的句子很短,否则尽管进行了预处理,速度还是应该快2倍

mwe_list = set(i.strip() for i in codecs.open("wn-mwe-en.dic", "r", "utf8").readlines())
mwe_list = tuple(mwe.replace('-', ' ').strip() for mwe in mwe_list)
sentence = sentence.replace('-', ' ').strip()

def chunker(sentence):
  for item in mwe_list:
    if item in sentence:
    ...

在我的系统中找不到.dic文件,或者我会为您分析它。

是的,速度非常快,13个单词的句子的时间从11.04秒到0.74秒不等。但是对于较长的句子,这会慢得多,有没有修剪ngram的建议?@2er0:你可以考虑最长的MWE,只需确保
for
的内部
循环从
i
min(i+可能最长的\ngram,len\u标记)
。这应该会加快一点速度。再看看我的答案。我添加了一些细微的更改,这将使您的代码更快一些。谢谢!但这确实起到了更快的作用。希望服务器能够处理2000000个句子的负载,每个句子30-100个单词=)@2er0:没问题。如果您尚未使用它,请查看
多处理
模块。这会给你一个巨大的鼓舞。很好。别忘了先用空格替换dic或句子中的任何连字符,这样你的块就可以拆分并匹配它们应该匹配的位置。我很乐意分享我的字典(我粘贴的内容不能超过500kb)。但字典是从下载、提取和下载的。请从参考文献中适当引用。看来我的答案是OBE。
mwe_list = set(i.strip() for i in codecs.open("wn-mwe-en.dic", "r", "utf8").readlines())
mwe_list = tuple(mwe.replace('-', ' ').strip() for mwe in mwe_list)
sentence = sentence.replace('-', ' ').strip()

def chunker(sentence):
  for item in mwe_list:
    if item in sentence:
    ...