?

Log in

No account? Create an account

Компьютерная лингвистика

Новостная лента www.solarix.ru

Previous Entry Share Next Entry
Слишком хороший f1 и roc-auc score в моделях релевантности/синонимичности с triple loss
kelijah
1. Что выдает модель сама по себе

Как работают эти модели? В качестве обучающих данных используются триады, содержащие опорное предложение, нерелевантное предложение и релевантное предложение. Для модели синонимичности эта тройка может выглядеть так:

(anchor) кошка ловит мышку
(positive) на мышку охотится кошка
(negative) дети играют в кошки-мышки

Функция потерь, в исходниках незатейливо названая triplet_loss, представляет из себя комбинацию из евклидова расстояния для пар векторов (anchor, positive) и (anchor, negative). Все делает модель - учится генерировать для предложений такие вектора, чтобы для пары (anchor, positive) расстояние было меньше, чем для (anchor, negative). Это можно сказать и так, что модель учится ранжировать группу из двух предложений.

Выдываемые по ходу обучения значение функции потерь, к сожалению, малоинформативны. Не считая, само собой, того факта, что меньшее значение означает лучшее качество. Вот так примерно выглядит кривая обучения для модели синонимичности (ссылка на тетрадку):


Нет никакой возможности понять, насколько хороша модель, которой при валидации выходит на уровень loss=0.1 или 0.01. Отсюда и желание выдать какую-то другую, более интерпретабельную, оценку точности.

2.  Расчет точности ранжирования в триплетах

Сначала я сделал примитивный подсчет точности ранжирования в триплетах:

1) берем список сэмплов для валидации
2) прогоняем предложения через модель, получаем векторы для anchor, positive и negative
3) вычисляем расстояния между векторами для (anchor, positive) и (anchor, negative)
4) если |anchor-positive| < |anchor-negative|, то успех, иначе ошибка, соответственно увеличиваем счетчики успехов или ошибок
5) в конце просто выводим долю успешных п.4 среди всех сэмплов - получается некая оценка ошибки.

Например, для модели детектора синонимов и перефразировок получается ~0.97...0.99 при повторных запусках. Уже понятнее. Но и такая оценка не позволяет напрямую понять, как модель будет работать в чатботе при выборе ближайшего предложения среди множества кандидатов.

2. AUC ROC метрика

Пробуем изменить расчет.

1) рассматриваем пары (anchor, positive) как сэмплы с label=1, а пары (anchor, negative) как сэмплы с label=0
2) прогоняем пары предложений чез модель, получаем векторы предложений в паре, расчитываем косинус между векторами. Это будет оценка близости, находящаяся в диапазоне -1, 1.
3) выбираем значение порога threshold
4) если у пары предложений cosine получился больше порога, то считаем, что модель выдала label=1, иначе label=0
5) пройдя по всем парам, вычисляем recall и precision для текущего theshold.
6) повторяя для разных threshold, получаем таблицу - см. ниже.

По сути, мы "врукопашную" реализуем sklearn.metrics.precision_recall_curve.

Получается примерно так:

threshold precision recall
0.0 0.497504634251 1.0
0.02 0.502491718277 0.999942676985
0.04 0.509328739525 0.999942676985
0.06 0.51750326332 0.999942676985
0.08 0.528383618078 0.99988535397
0.1 0.541982597887 0.999770707939
0.12 0.559537943206 0.999598738894
0.14 0.581169805032 0.999598738894
0.16 0.605900545575 0.999484092863
0.18 0.632836037606 0.999369446833
0.2 0.662006079027 0.998796216681
0.22 0.69438462152 0.998051017484
0.24 0.72767577063 0.997305818286
0.26 0.762410103491 0.996617942104
0.28 0.795255758575 0.9954714818
0.3 0.824806053972 0.993407853253
0.32 0.853550076585 0.990255087418
0.34 0.881037658616 0.987044998567
0.36 0.905146476643 0.982975064488
0.38 0.923923056082 0.977414732015
0.4 0.940383014155 0.971109200344
...     ...             ...
0.76 0.999497234791 0.455832616796
0.78 0.999442741711 0.411235310977
0.8 0.999536965581 0.371223846374
0.82 0.999479166667 0.330008598452
0.84 0.999607843137 0.292232731442
0.86 0.999776536313 0.256463169963
0.88 1.0 0.22562338779
0.9 1.0 0.196503296073
0.92 1.0 0.172714244769
0.94 1.0 0.152937804529
0.96 1.0 0.139065634852
0.98 1.0 0.131842934938
1.0 1.0 0.0290627687016



Я не очень люблю roc auc метрику, так как она кмк плохо интерпретируются, но с помошью sklearn.metrics.roc_curve по вышеописанным расчетным значениям можно получить и нарисовать нечто такое:
Если верить этим результатам, модель определения синонимичности работает невероятно точно. Площадь под ROC кривой, рассчитанная с помощью sklearn.metrics.roc_auc_score, дает результат ~0.992.


  • 1
AUC хороший критерий. Он интегральный для всех условий в которых будет применяться модель, поэтому можно сказать о некоторой трудности интерпретации. Но можно искать трешоилд в конкретной области, или искать оптимальный трешоилд по Йоудену (учитывая и частоту исхода нужного в популяции и цену ошибки).

Здесь конечно очень высокие значения. Если это получено при кроссвалидации (и протечки обучающей выборки не прошло случайно) то очень круто.

>Здесь конечно очень высокие значения. Если это получено при кроссвалидации (и протечки обучающей выборки не прошло случайно) то очень круто.

Безусловно слишком высокие. Должно быть в районе 0.97-0.98 в лучшем случае по результатам других, не сеточных моделей. Так что в общем да, надо искать какую-то бяку в датасете.

  • 1