代码之家  ›  专栏  ›  技术社区  ›  Anurag Sharma

spacy中的深度复制PhraseMatcher对象无效

  •  1
  • Anurag Sharma  · 技术社区  · 6 年前

    import copy
    import spacy
    from spacy.matcher import PhraseMatcher
    
    
    nlp = spacy.load('en')
    color_patterns = [nlp(text) for text in ('red', 'green', 'yellow')]
    product_patterns = [nlp(text) for text in ('boots', 'coats', 'bag')]
    material_patterns = [nlp(text) for text in ('silk', 'yellow fabric')]
    
    matcher = PhraseMatcher(nlp.vocab)
    matcher.add('COLOR', None, *color_patterns)
    matcher.add('PRODUCT', None, *product_patterns)
    matcher.add('MATERIAL', None, *material_patterns)
    
    
    matcher2 = copy.deepcopy(matcher)
    
    doc = nlp("yellow fabric")
    matches = matcher2(doc)
    for match_id, start, end in matches:
        rule_id = nlp.vocab.strings[match_id]  # get the unicode ID, i.e. 'COLOR'
        span = doc[start : end]  # get the matched slice of the doc
        print(rule_id, span.text)
    

    matcher2 对象,它不提供任何输出,但是 matcher 我能得到结果。

    COLOR yellow
    MATERIAL yellow fabric
    

    我被困在这两天。任何帮助都将不胜感激。

    非常感谢。

    1 回复  |  直到 6 年前
        1
  •  1
  •   gdaras    6 年前

    问题的根源是PhraseMatcher是Cython类,在matcher.pyx文件中定义和实现,Cython不能与deepcopy一起正常工作。

    this 堆栈溢出问题:

    Cython不喜欢在具有函数/方法引用变量的类上使用deepcopy。这些可变副本将失败。

    不过,还有其他选择。如果您想对多个文档并行运行PhraseMatcher,可以使用PhraseMatcher的pipe方法进行多线程处理。

    import copy
    import spacy
    from spacy.matcher import PhraseMatcher
    
    
    nlp = spacy.load('en_core_web_sm')
    color_patterns = [nlp(text) for text in ('red', 'green', 'yellow')]
    product_patterns = [nlp(text) for text in ('boots', 'coats', 'bag')]
    material_patterns = [nlp(text) for text in ('silk', 'yellow fabric')]
    
    matcher = PhraseMatcher(nlp.vocab)
    matcher.add('COLOR', None, *color_patterns)
    matcher.add('PRODUCT', None, *product_patterns)
    matcher.add('MATERIAL', None, *material_patterns)
    
    doc1 = nlp('yellow fabric')
    doc2 = nlp('red lipstick and big black boots')
    
    for doc in matcher.pipe([doc1, doc2], n_threads=4):
        matches = matcher(doc)
        for match_id, start, end in matches:
            rule_id = nlp.vocab.strings[match_id]
            span = doc[start : end]
            print(rule_id, span.text)
    

    希望有帮助!