Ранее мы сформировали задачу и собрали наши данные в виде структурированного DataFrame'а.
Согласно нашей задумке основным признаком для модели должен быть message. Но ничего хорошего не произойдёт, если мы передадим его как есть, так как каждое сообщение уникально и чтобы найти общее мы смотрим как минимум на слова, а не на всё предложение в целом.
Нужно разбить предложение на слова, чтобы алгоритм мог сравнивать сообщения на уровне слов:
Но и массив слов мы не можем использовать в качестве признака для модели. Ну во первых модель не умеет работать с массивами в качестве признаков. Да и каждое сообщение содержит разное количество слов, что опять же мешает преобразовать массив в набор признаков - получится, что каждое сообщение трансформировался в разный набор признаков.
Первое, что мне пришло в голову - это представить все встречающиеся слова в виде бинарных признаков, и для каждого сообщения проставить единицу напротив встречающегося слова. Получается бинарная матрица из нулей и единиц, где колонки - это слова из словаря, а строчки - конкретных сообщения.
В sklearn'е есть ряд утилит, которые уже реализуют ряд часто-встречающихся на этапе подготовки данных преобразований.
Например LabelEncoder позволяет преобразовать классы (они же метки, они же label'ы, они же слова в нашем случае) в уникальные числа. Для этого он собирает словарь классов, а затем заменяет везде класс его индексом из словаря. Так во всех сообщениях слово будет заменено одним и тем же числом.
Далее имея LabelEncoder со справочником классов, мы можем трансформировать наши массивы слов, заменяя слова на цифры:
Но это не совсем, что нам нужно в данном случае. В sklearn есть что-то более нам подходящее - LabelBinarizer.
Ещё один Encoder, который представляет наборы классов в виде бинарной матрицы вхождений того или иного класса в конкретный набор. Выглядит это так:
В следующей статье мы обучим модель Decision Tree на этих данных и попробуем её в деле.