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

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

Previous Entry Share Next Entry
Нелюбовь чатбота к букве 'п' (и еще про sklearn.metrics.classification_report)
kelijah
Модель посимвольной генерации ответа чатбота была кратко описана здесь, а ее исходный текст лежит тут.

Кроме финальной оценки качества модели через per instance accuracy (доля полностью правильно сгенерированных ответов, когда один неверный символ относит ответ к невалидным), я добавил туда расширенную диагностику с помощью sklearn.metrics.classification_report, см. строки 693 и 694. Вот что она показывает:

             precision    recall  f1-score   support

         \r       0.96      0.98      0.97     10418
          —       0.00      0.00      0.00         2
          5       0.97      0.98      0.97       241
                  0.95      0.91      0.93      4937
          %       1.00      1.00      1.00         1
          0       0.98      1.00      0.99       174
          ъ       1.00      1.00      1.00        16
          3       0.98      0.99      0.99       263
          б       0.93      0.96      0.95      1053
          а       0.97      0.97      0.97      6555
          г       0.95      0.94      0.94      1065
          в       0.95      0.95      0.95      2814
          е       0.96      0.96      0.96      4879
          д       0.95      0.95      0.95      2067
          з       0.94      0.93      0.93       934
          ж       0.94      0.95      0.94       493
          й       0.95      0.95      0.95       961
          и       0.96      0.96      0.96      5134
          л       0.96      0.96      0.96      2975
          к       0.96      0.95      0.95      3284
          н       0.96      0.96      0.96      4929
          м       0.95      0.95      0.95      2738
          п       0.92      0.92      0.92      1537
          4       0.98      0.99      0.98       243
          с       0.95      0.95      0.95      3676
          р       0.96      0.96      0.96      3787
          у       0.97      0.97      0.97      2802
          т       0.97      0.97      0.97      5224
          х       0.92      0.96      0.94       578
          ф       0.97      0.98      0.97       315
          ч       0.97      0.97      0.97      1412
          ц       0.96      0.98      0.97       402
          щ       0.95      0.97      0.96       185
          ш       0.95      0.97      0.96       660
          ы       0.98      0.98      0.98      2484
          6       0.98      0.96      0.97       130
          э       0.96      0.93      0.94       163
          ь       0.97      0.97      0.97      1001
          я       0.98      0.98      0.98      2809
          ю       0.96      0.96      0.96       567
          9       0.99      0.98      0.98       151
          8       1.00      0.97      0.98       120
          2       0.98      0.98      0.98       406
          7       1.00      0.96      0.98       140
          1       0.98      0.99      0.99       572
          о       0.96      0.96      0.96      7100

avg / total       0.96      0.96      0.96     92397


Символ \r это специальный маркер конца ответа.

Можно заметить, что худшая точность (0.92) наблюдается для буквы 'п'. Удивительно при этом, что это достаточно частотная буква, в частности для данного набора ответов она встречается 1537 раз. Разумеется, в тренировочном наборе она тоже весьма частотна, потому классификатор видел ее в разных контекстах много раз, и тем не менее вот такой bias...

По поводу использованной функции sklearn.metrics.classification_report, кстати, есть одна неприятная засада. Она на входе принимает опционально наименования классов, чтобы сделать отчет более читабельным. В данном случае названиями классов являются символы. Все прекрасно до тех пор, пока передаваемые в функцию y_true и y_pred содержат одинаковое по мощности множество классов. Но если в y_pred встречаются не все классы (всякое бывает, например маленький набор для валидации или сильный дисбаланс классов), то происходит следующее. наименования классов, заботливо передаваемые в аргументе target_names, не будут правильно соотнесены с вариантами классов из y_pred, и в консоли появится предупреждение. Отчет будет содержать неправильно поименованные класса! Чтобы исключить такой неприятный ход событий, в строке 692 я пересекаю множества классов в y_true и y_pred, и затем сортирую их по возрастанию:

class_names = [encode_char(id2outchar[y]) for y in sorted(set(y_test) | set(y_pred))]

Полученный список class_names гарантирует консистентность результатов работы sklearn.metrics.classification_report.

?

Log in

No account? Create an account