Решение тестового задания на позицию Data Scientist в Cloud.ru
Была обучена сеть для задачи Named Entity Recognition на датасете NERUS. В качестве модели была выбрана модель ruBERT. От неё я взял токенизатор и энкодер, добавив к ним классификатор для токенов. Поверх обучения использовался pytorch lightning, а для логирования - tensorboard.
Для оценки качества моделей в задаче Named Entity Recognition (NER) используют метрики:
- Entity-Level Micro/Macro F1-score
В качестве метрики будем использовать её. В наших данных будет наблюдатсья сильный дизбаланс классов, т.к. сущностей с меткой 'O' будет больше всего. Micro F1-score рассчитывается на уровне всего набора данных, объединяя предсказания и истинные метки для каждой сущности. Это подразумевает, что все предсказанные и истинные метки рассматриваются как один большой класс. Macro F1-score рассчитывается, усредняя F1-score для каждой индивидуальной сущности. Так мы можем равномерно оценить качество извлечения для всех сущностей, даже если некоторые из них представлены в данных редко.
- Exact Match
Измеряет процент точного совпадения между предсказанными и действительными именованными сущностями. Полезен, когда важно достичь точного соответствия.
- IOB Metrics (IOB Precision, IOB Recall, IOB F1-score):
Рассматривает только те предсказанные именованные сущности, которые правильно начинаются и заканчиваются.
- Span-Level Metrics
Span Precision, Span Recall, Span F1-score оценивают точность, полноту и F1-score, сосредотачиваясь на предсказанных именованных сущностях как на целых фрагментах текста.
Первая метрика была выбрана, потому что объединение всех именованных сущностей в единый показатель F1-score делает эту метрику всесторонней и информативной. Микроусреднение и макроусреднение обеспечивают учет качества предсказаний для каждого класса и предоставляют общую оценку производительности модели.
Метрика Exact Match оценивает только полное совпадение между предсказанными и истинными тегами. Это может быть слишком строгим условием, особенно когда модель делает небольшие ошибки в границах или несколько ошибок в предсказании.
Метрики IOB не обобщают оценку для всех классов, и, таким образом, могут предоставить неполное представление о производительности модели.
Span-Level метрики оценивают точность границ именованных сущностей, но, подобно IOB-метрикам, не учитывают их типы. Они не уделяют внимания полноте и точности для каждого класса.
Подсчитанные метрики для обученной модели:
precision | recall | f1-score | общее количество экземпляров | |
---|---|---|---|---|
LOC | 0.98 | 0.97 | 0.97 | 19616 |
ORG | 0.91 | 0.91 | 0.91 | 18305 |
PER | 0.98 | 0.96 | 0.97 | 16157 |
micro avg | 0.95 | 0.95 | 0.95 | 54078 |
macro avg | 0.96 | 0.95 | 0.95 | 54078 |
weighted avg | 0.95 | 0.95 | 0.95 | 54078 |
Перед запуском убедитесь, что в системе установлен docker
и docker-compose
коомандами:
sudo docker --version
sudo docker-compose --version
Далее проверьте, запущен ли демон docker
sudo docker ps
Тогда можно поднимать сервис
git clone https://github.com/t041lk8/DS-Cloud-test.git
sudo docker compose up
kubectl apply -f ./manifests
curl -X POST "http://localhost:8080/v1/models/NERtagger:predict" \
-H "Content-Type: application/json" \
-d '{"text": "Глава компании Apple Тим Кук осенью представил новый телефон в штаб квартире Apple Inc в Купертино"}'
status_code: 200
{
'entities': [
{'text': 'глава', 'type': 'O', 'start': 0, 'end': 5},
{'text': 'компании', 'type': 'O', 'start': 0, 'end': 14},
{'text': 'apple', 'type': 'ORG', 'start': 6, 'end': 20},
{'text': 'тим кук', 'type': 'PER', 'start': 18, 'end': 28},
{'text': 'осенью', 'type': 'O', 'start': 27, 'end': 35},
{'text': 'представил', 'type': 'O', 'start': 29, 'end': 46},
{'text': 'новыи', 'type': 'O', 'start': 36, 'end': 52},
{'text': 'телефон', 'type': 'O', 'start': 51, 'end': 60},
{'text': 'в', 'type': 'O', 'start': 53, 'end': 62},
{'text': 'штаб', 'type': 'O', 'start': 61, 'end': 67},
{'text': 'квартире', 'type': 'O', 'start': 63, 'end': 76},
{'text': 'apple inc', 'type': 'ORG', 'start': 68, 'end': 86},
{'text': 'в', 'type': 'O', 'start': 83, 'end': 88},
{'text': 'купертино', 'type': 'LOC', 'start': 87, 'end': 98}
],
'text': 'Глава компании Apple Тим Кук осенью представил новый телефон в штаб '
'квартире Apple Inc в Купертино'
}
curl -X POST "http://<your_any_node_external_ip>:30180/v1/models/NERtagger:predict" \
-H "Content-Type: application/json" \
-d '{"text": "Глава компании Apple Тим Кук осенью представил новый телефон в штаб квартире Apple Inc в Купертино"}'
status_code: 200
{
'entities': [
{'text': 'глава', 'type': 'O', 'start': 0, 'end': 5},
{'text': 'компании', 'type': 'O', 'start': 0, 'end': 14},
{'text': 'apple', 'type': 'ORG', 'start': 6, 'end': 20},
{'text': 'тим кук', 'type': 'PER', 'start': 18, 'end': 28},
{'text': 'осенью', 'type': 'O', 'start': 27, 'end': 35},
{'text': 'представил', 'type': 'O', 'start': 29, 'end': 46},
{'text': 'новыи', 'type': 'O', 'start': 36, 'end': 52},
{'text': 'телефон', 'type': 'O', 'start': 51, 'end': 60},
{'text': 'в', 'type': 'O', 'start': 53, 'end': 62},
{'text': 'штаб', 'type': 'O', 'start': 61, 'end': 67},
{'text': 'квартире', 'type': 'O', 'start': 63, 'end': 76},
{'text': 'apple inc', 'type': 'ORG', 'start': 68, 'end': 86},
{'text': 'в', 'type': 'O', 'start': 83, 'end': 88},
{'text': 'купертино', 'type': 'LOC', 'start': 87, 'end': 98}
],
'text': 'Глава компании Apple Тим Кук осенью представил новый телефон в штаб '
'квартире Apple Inc в Купертино'
}