Вы можете найти примеры обучающих и тестовых данных в репозитории crf++ здесь. Обучающие данные для фрагментации именной фразы выглядят следующим образом:
Confidence NN B
in IN O
the DT B
pound NN I
is VBZ O
widely RB O
expected VBN O
... etc ...
Столбцы произвольны в том смысле, что они могут быть любыми. CRF++ требует, чтобы каждая строка имела одинаковое количество столбцов (или была пустой для разделения предложений), но не все пакеты CRF требуют этого. Вам нужно будет предоставить значения данных самостоятельно, это данные, на которых учится классификатор.
Хотя в разных столбцах может быть что угодно, вы должны знать одно соглашение: Формат IOB. Чтобы иметь дело с объектами, потенциально состоящими из нескольких токенов, вы помечаете их как Inside/Outside/Beginning. Может быть полезно привести пример. Представим, что мы обучаем классификатор обнаруживать имена — для компактности я напишу это в одну строку:
John/B Smith/I ate/O an/O apple/O ./O
В столбцовом формате это будет выглядеть так:
John B
Smith I
ate O
an O
apple O
. O
С этими тегами B
(начало) означает, что слово является первым в объекте, I
означает, что слово находится внутри объекта (оно идет после тега B
), а O
означает, что слово не является объектом. Если у вас несколько типов объектов, обычно используются такие метки, как B-PERSON
или I-PLACE
.
Причина использования тегов IOB заключается в том, что классификатор может изучить различные вероятности перехода для начальных, продолжающихся и конечных объектов. Итак, если вы изучаете названия компаний, вы узнаете, что Inc./I-COMPANY
обычно переходит в метку O
, потому что Inc.
обычно является последней частью названия компании.
Еще одной проблемой являются шаблоны, и CRF++ использует свой собственный специальный формат, но опять же, в исходном дистрибутиве есть примеры, которые вы можете посмотреть. Также см. этот вопрос.
Чтобы ответить на комментарий к моему ответу, вы можете сгенерировать теги POS, используя любой тег POS. Вам даже не нужно предоставлять POS-теги, хотя они обычно полезны. Другие метки могут быть добавлены вручную или автоматически; например, вы можете использовать список известных существительных в качестве отправной точки. Вот пример использования spaCy для простого детектора имен:
import spacy
nlp = spacy.load('en')
names = ['John', 'Jane', etc...]
text = nlp("John ate an apple.")
for word in text:
person = 'O' # default not a person
if str(word) in names:
person = 'B-PERSON'
print(str(word), word.pos_, person)
person
polm23
schedule
13.06.2018