Почему существующие библиотеки неинтересны и как я создал лучшую.

Несколько месяцев назад мне понадобился способ обнаружения ненормативной лексики в отправленных пользователем текстовых строках:

В итоге я собрал и выпустил свою собственную библиотеку для этой цели под названием проверка на ненормативную лексику:



Конечно, прежде чем я это сделал, я поискал в Индексе пакетов Python (PyPI) любые существующие библиотеки, которые могли бы сделать это за меня. Единственными половинками достойных результатов по поисковому запросу ненормативная лексика были:

Однако сторонние библиотеки иногда могут быть отрывочными, поэтому я внимательно изучил эти 4 результата.

ненормативная лексика, улучшенная ненормативная лексика и фильтр ненормативной лексики

Быстро покопавшись в репозитории profanity, я нашел файл с именем wordlist.txt:

Вся profanity библиотека - всего лишь оболочка этого списка из 32 слов! profanity обнаруживает ненормативную лексику, просто ища одно из этих слов.

К моему разочарованию, better-profanity и profanityfilter использовали один и тот же подход:

Это плохо, потому что библиотеки обнаружения ненормативной лексики на основе списков слов крайне субъективны. Например, в словарном списке better-profanity есть слово «отстой». Вы готовы сказать, что любое предложение, содержащее слово «сосать», является оскорбительным? Более того, любой жестко закодированный список плохих слов неизбежно будет неполным - как вы думаете, 32 плохих слова profanity единственные?

Исключив уже 3 библиотеки, я возлагаю надежды на 4-ю и последнюю: profanity-filter.

фильтр ненормативной лексики

profanity-filter использует машинное обучение! Милая!

Оказывается, это действительно медленно. Вот тест, который я провел в декабре 2018 года, сравнивая (1) profanity-filter, (2) мою библиотеку profanity-check и (3) profanity (тот, который содержит список из 32 слов):

Мне нужно было иметь возможность делать много прогнозов в реальном времени, а profanity-filter даже близко не подходил к этому. Но, может быть, это классический компромисс между точностью и скоростью, верно?

Неа.

Ни одна из библиотек, которые я нашел в PyPI, не соответствовала моим потребностям, поэтому я создал свою собственную.

Построение проверки на ненормативную лексику, часть 1: данные

Я знал, что хочу profanity-check основывать свои классификации на данных, чтобы избежать субъективности (читай: чтобы иметь возможность сказать, что я использовал машинное обучение). Я собрал комбинированный набор данных из двух общедоступных источников:

Каждый из этих наборов данных содержит образцы текста, помеченные вручную людьми на краудсорсинговых сайтах, таких как Figure Eight.

Вот как в итоге выглядел мой набор данных:

В наборе данных Twitter есть столбец с именем class, в котором 0, если твит содержит язык вражды, 1, если он содержит оскорбительные выражения, и 2, если он не содержит ни того, ни другого. Я классифицировал любой твит с class из 2 как «Не оскорбительный», а все остальные твиты как «Оскорбительный».

В наборе данных Википедии есть несколько двоичных столбцов (например, toxic или threat), которые показывают, содержит ли этот текст этот тип токсичности. Я классифицировал любой текст, содержащий любой из типов токсичности, как «Оскорбительный», а все другие тексты - как «Не оскорбительный».

Построение проверки на ненормативную лексику, часть 2: Обучение

Теперь, вооружившись очищенным комбинированным набором данных (который вы можете скачать здесь), я был готов обучать модель!

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

Здесь происходит два основных этапа: (1) векторизация и (2) обучение.

Векторизация: мешок слов

Я использовал класс CountVectorizer scikit-learn, который в основном превращает любую текстовую строку в вектор, подсчитывая, сколько раз встречается каждое данное слово. Это известно как представление Мешок слов (ЛУК). Например, если единственными словами на английском языке были the, cat, sat и hat, возможная векторизация предложения the cat sat in the hat могла бы быть:

??? представляет любое неизвестное слово, которое в этом предложении равно in. Любое предложение может быть представлено таким образом как количество the, cat, sat, hat и ???!

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

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

Обучение: линейный SVM

Я решил использовать модель Linear Support Vector Machine (SVM), которая реализована классом LinearSVC scikit-learn. Это и это - хорошее введение, если вы не знаете, что такое SVM.

CalibratedClassifierCV в приведенном выше коде существует как оболочка, чтобы дать мне метод predict_proba(), который возвращает вероятность для каждого класса, а не просто классификацию. Однако вы можете просто проигнорировать это, если последнее предложение не имело для вас смысла.

Вот один (упрощенный) способ понять, почему работает линейная SVM: в процессе обучения модель узнает, какие слова «плохие», а какие «плохие», потому что эти слова чаще встречаются в оскорбительных текстах. Это как если бы процесс обучения подбирал для меня «плохие» слова, что намного лучше, чем использовать список слов, который я пишу сам!

Линейная SVM сочетает в себе лучшие аспекты других библиотек обнаружения ненормативной лексики, которые я обнаружил: она достаточно быстра, чтобы работать в режиме реального времени, но достаточно надежна, чтобы обрабатывать множество различных видов ненормативной лексики.

Предостережения

При этом profanity-check далек от совершенства. Позвольте мне прояснить: относитесь к прогнозам profanity-check с недоверием, потому что он делает ошибки. Например, плохо подбирать менее распространенные варианты ненормативной лексики, такие как «f4ck you» или «you b1tch», потому что они недостаточно часто встречаются в обучающих данных. Вы никогда не сможете обнаружить всю ненормативную лексику (люди будут изобретать новые способы обхода фильтров), но profanity-check неплохо справляется с обнаружением большей части.

проверка ненормативной лексики

profanity-check имеет открытый исходный код и доступен на PyPI! Чтобы использовать это, просто

$ pip install profanity-check

Как profanity-check может быть еще лучше? Не стесняйтесь обращаться или комментировать любые мысли или предложения!



Также размещено на victorzhou.com.