О разборе скобок в английской модели - PullRequest
0 голосов
/ 19 марта 2019

Это предложение является частью упрощенной Википедии:

В воздухе есть три вещи: азот (79%), кислород (20%) и другие типы газов (1%).

Процентные значения в скобках плохо обрабатываются в spaCy 2.0 и 2.1. Каков наилучший способ справиться с этим классом проблем?

Вот визуализация: visualization of parse of above sample sentence

Ответы [ 2 ]

1 голос
/ 19 марта 2019
  • Используйте метод слияния / повторного выражения regex & spacy, чтобы объединить содержимое в скобках как один токен.

    >>> import spacy
    >>> import re
    >>> my_str = "There are three things in air, Nitrogen (79%), oxygen (20%), and other types of gases (1%)."
    >>> nlp = spacy.load('en')
    >>> parsed = nlp(my_str)
    >>> [(x.text,x.pos_) for x in parsed]
    [('There', 'ADV'), ('are', 'VERB'), ('three', 'NUM'), ('things', 'NOUN'), ('in', 'ADP'), ('air', 'NOUN'), (',', 'PUNCT'), ('Nitrogen', 'PROPN'), ('(', 'PUNCT'), ('79', 'NUM'), ('%', 'NOUN'), (')', 'PUNCT'), (',', 'PUNCT'), ('oxygen', 'NOUN'), ('(', 'PUNCT'), ('20', 'NUM'), ('%', 'NOUN'), (')', 'PUNCT'), (',', 'PUNCT'), ('and', 'CCONJ'), ('other', 'ADJ'), ('types', 'NOUN'), ('of', 'ADP'), ('gases', 'NOUN'), ('(', 'PUNCT'), ('1', 'NUM'), ('%', 'NOUN'), (')', 'PUNCT'), ('.', 'PUNCT')]
    
    >>> indexes = [m.span() for m in re.finditer('\([\w%]{0,5}\)',my_str,flags=re.IGNORECASE)]
    >>> indexes
    [(40, 45), (54, 59), (86, 90)]
    >>> for start,end in indexes:
    ...     parsed.merge(start_idx=start,end_idx=end)
    ...
    (79%)
    (20%)
    (1%)
    >>> [(x.text,x.pos_) for x in parsed]
    [('There', 'ADV'), ('are', 'VERB'), ('three', 'NUM'), ('things', 'NOUN'), ('in', 'ADP'), ('air', 'NOUN'), (',', 'PUNCT'), ('Nitrogen', 'PROPN'), ('(79%)', 'PUNCT'), (',', 'PUNCT'), ('oxygen', 'NOUN'), ('(20%)', 'PUNCT'), (',', 'PUNCT'), ('and', 'CCONJ'), ('other', 'ADJ'), ('types', 'NOUN'), ('of', 'ADP'), ('gases', 'NOUN'), ('(1%)', 'PUNCT'), ('.', 'PUNCT')]
    
0 голосов
/ 21 марта 2019

Первоначально написал ответ на трекер проблем здесь , но переполнение стека, безусловно, лучшее место для такого рода вопросов.

Я только что проверил ваш пример с последней версией, и токенизация выглядит так:

['There', 'are', 'three', 'things', 'in', 'air', ',', 'Nitrogen', '(', '79', '%', ')', ',', 
'oxygen', '(', '20', '%', ')', ',', 'and', 'other', 'types', 'of', 'gases', '(', '1', '%', ')', '.']

Вот дерево разбора, которое выглядит прилично для меня. (Если вы хотите попробовать это сами, обратите внимание, что я установил options={'collapse_punct': False, 'compact': True}, чтобы показать все жетоны пунктуации отдельно и облегчить чтение большого дерева.)

displacy

Тем не менее, вы также можете найти множество крайних случаев и примеров, когда готовые правила токенизации не могут обобщать для всех комбинаций знаков препинания и скобок, или где предварительно обученный парсер или Tagger делает неправильный прогноз. Поэтому, если вы имеете дело с более длинными вставками в круглых скобках и парсер пытается с ними справиться, вы можете настроить его с помощью большего количества примеров, подобных этому.

Рассматривать отдельное предложение изолированно не очень полезно, потому что оно не дает хорошего представления об общей точности ваших данных и о том, на чем следует сосредоточиться. Даже если вы обучаете причудливую современную модель, которая обеспечивает точность ваших данных на 90%, это все равно означает, что каждый десятый прогноз, который она делает, неверен.

...