Введение

В предыдущих 4 статьях мы проиллюстрировали использование Google и AWS NLP API. Мы также экспериментировали с библиотекой spacy для извлечения сущностей и существительных из разных документов. Мы показали, как улучшить модель, используя функцию сопоставления с образцом от spaCy.

Мы хотели бы пойти дальше предыдущих статей и поэкспериментировать с расширенными функциями. spaCy позволяет обновлять статистическую модель и обучать модель новым объектам без использования «жестко закодированных» правил сопоставления. Это позволит точно настроить модель для нашей конкретной области. Это весьма полезно для распознавания сущностей или классификации текста.

Мы решили использовать личные профили и описание работы, так как это распространенный вариант использования, который легко понять любому, хотя мы считаем, что использование такого рода алгоритмов для сопоставления кандидатов с вакансиями далеко не достаточно.

Использование предварительно обученной модели

Как показано в предыдущей статье, давайте проанализируем документ с предварительно обученной большой английской моделью в общем документе описания работы и посмотрим, какие сущности были идентифицированы:

import spacy spacy.load('en_core_web_lg') 
docJob=nlp(textCV) 
for ent in docJob.ents: 
   # Print the entity text and its label 
   if ent.label_=='PRODUCT': 
   print(ent.text, ent.label_,) 
SLQ ORG 
7 years DATE 
Statistics ORG 
Mathematics ORG 
C++ LANGUAGE 
Java LOC 
SLQ ORG 
S3 PRODUCT 
Spark ORG 
DigitalOcean ORG 
3rd ORDINAL 
Google Analytics ORG 
Site Catalyst, ORG 
Coremetrics ORG 
Adwords ORG 
Crimson Hexagon ORG 
Facebook Insights ORG 
Hadoop NORP 
Hive ORG 
Gurobi GPE 
MySQL GPE 
Business Objects ORG 
Glassdoor ORG

Интересно, что C++ был обнаружен как язык, а Java как геополитическая сущность, поскольку это индонезийский остров. Например, JavaScript вообще не идентифицирован. Это, очевидно, зависит от того, в каком контексте была обучена модель, и, вероятно, не конкретно в области компьютерных наук.

Ранее мы показали, что можем добавлять в модель свои собственные правила. Итак, давайте добавим в модель собственные правила обнаружения, чтобы приблизиться к тому, к чему мы стремимся, т. е. к выявлению технических навыков в профиле людей:

# define patterns we want to recognize 
patterns = [{"label": "PROG", "pattern": [{"lower": "java"}]}, {"label": "PROG", "pattern": [{"lower": "javascript"}]}] 
# define an entity ruler using predefined patterns 
ruler = EntityRuler(nlp, patterns=patterns,overwrite_ents=True) 
# add the ruler to the nlp pipeline 
nlp.add_pipe(ruler) 
# apply to the job document 
docJob=nlp(textJob) 
for ents in docJob.ents: 
# Print the entity text and its label 
  if ents.label_=='PROG': 
     print(ents.text, ents.label_,) 
Java PROG 
JavaScript PROG

Теперь у нас есть Java и JavaScript, определенные как языки программирования.

Таким образом, мы смогли добавить в статистическую модель распознавание объектов на основе правил. Это позволяет быстро настраивать модели для адаптации к конкретным областям и потребностям.

Это интересно, потому что в данном случае модель определила Java как геополитическую сущность, а JavaScript — как организацию. Он сделал это автоматически, без необходимости кодировать определенные правила для этого конкретного документа.

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

Обучение и обновление модели

spaCy позволяет нам обучать базовую нейронную сеть и обновлять ее с помощью наших конкретных знаний в предметной области. Это общая функция, поскольку это именно то, что мы хотим сделать. Сначала давайте добавим несколько примеров сущностей, которые мы хотим обнаружить в репрезентативных предложениях:

trainData=[('Java is a programming language', {'entities': [(0, 4,'PROG')]}), ('I have 5 years experience in JavaScript', {'entities': [(27, 37,'PROG')]}), ('Extensive Java experience required', {'entities': [(10, 14,'PROG')]}), ('JavaScript is a programming language used mainly in front-end development', {'entities': [(0, 10, 'PROG')]}), ('Java is an object oriented programming language', {'entities': [(0, 4, 'PROG')]}), ('I have a long experience in project management', {'entities': []})]

Также рекомендуется приводить отрицательные примеры, например, предложения без какой-либо сущности.

Давайте теперь обучим и обновим модель с помощью этих новых объектов и обучающих примеров:

# initialize a blank spacy model 
nlp = spacy.blank('en') 
# Create blank entity recognizer and add it to the pipeline 
ner = nlp.create_pipe('ner') 
nlp.add_pipe(ner) 
# Add a new label for programming language 
ner.add_label('PROG') 
# Start the training 
nlp.begin_training() 
# Train for 10 iterations 
for itn in range(10): 
  random.shuffle(trainData) 
  # Divide examples into batches 
  for batch in spacy.util.minibatch(trainData, size=2): 
    texts = [text for text, annotation in batch] 
    annotations = [annotation for text, annotation in batch] 
    # Update the model 
    nlp.update(texts, annotations)

Теперь мы готовы протестировать нашу модель на том же документе, что и раньше.

docJob=nlp(textJob) 
for ents in docJob.ents: 
  # Print the document text and entitites 
  if ents.label_=='PROG': 
  print(ents.text, ents.label_,) 
Data PROG 
Job PROG 
Description PROG 
Job PROG 
Java PROG 
JavaScript PROG 
Site PROG 
Map PROG

Это очень круто, теперь нейросеть spaCy распознала Java и JavaScript. К сожалению, он также классифицировал несколько новых слов как PROG, но это хорошее начало.

Первоначально опубликовано на https://smartlake.ch 26 мая 2019 г.