Это вторая часть задачи классификации текста (Первая).

В этом посте мы собираемся создать модель для задачи классификации с помощью:

  • scikit-learn:SVC, MultinomialNB, LogisticRegression.
  • Tensorflow:LSTM, CNN.

Сначала мы импортируем необходимые классы.

Так же, как и в предыдущем посте, будем читать текст и очищать его (расширенно объяснено в Первом посте)

['politics',
 'exploration',
 'intelligence',
 'weapons',
 'headhunters',
 'transportation',
 'logistics']
CPU times: user 4.79 s, sys: 34.9 ms, total: 4.83 s
Wall time: 5.18 s

Моделирование

Чтобы провести исследование модели, мы начнем с базовых моделей, тестирующих MultinomialNB, SVC и логистическую регрессию, все они с преобразованием текста в TF-IDF. Среди них метод перекрестной проверки будет использоваться для проверки того, какой из них дает нам наилучшие результаты, и для него будет проведено финальное тестирование.

Эта базовая модель будет сравниваться с моделью LSTM и сверточной моделью.

Мы импортируем все зависимости sklearn.

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

Мы также будем использовать TF-IDF (термин частота — обратная частота документа). Этот метод дает нам числовое представление терминов в тексте.

['aa', 'aaa', 'aaaa', 'aaaaaaaaaaaa', 'aaah', 'aaef', 'aah', 'aalborg', 'aamir', 'aammmaaaazzzzzziinnnnggggg']
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
array([6.08295596, 5.70566172, 8.56786261, ..., 8.56786261, 8.56786261, 8.1623975 ])
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

Как рассчитывается TF*IDF? TF (частота терминов) слова — это частота слова (т. е. количество раз, когда оно появляется) в документе. Когда вы знаете TF, вы можете увидеть, используете ли вы термин слишком много или слишком мало. Например, если документ из 100 слов содержит термин «ольборг» 12 раз, TF для слова «ольборг» равен

IDF (обратная частота документа) слова является мерой того, насколько значим этот термин во всем корпусе.

Допустим, размер корпуса составляет 10 000 000 миллионов документов. Если мы предположим, что существует 0,3 миллиона документов, содержащих термин «aalborg», то IDF (т. е. log {DF}) определяется как общее количество документов (10 000 000), деленное на количество документов, содержащих термин «aalborg» ( 300 000).

Базовые модели

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

model_name
LogisticRegression    0.934610
MultinomialNB         0.929186
SVC                   0.943398
Name: accuracy, dtype: float64

Проанализировав 3 модели, мы видим, что SVC ведет себя лучше, чем другие, и более стабильно, поэтому с этой моделью будет проведено более исчерпывающее тестирование.

Для проведения этого теста будут использоваться данные, обработанные с помощью TF-IDF, и данные будут разделены, чтобы получить 70% данных для обучения модели и 30% данных, которые модель не видела, чтобы проверить, что правильно или неправильно. что обобщает.

Как видно из матрицы путаницы в модели, она довольно хорошо обобщается, отмечая, что класс «Охотники за головами» имеет определенное отклонение, которое можно неправильно предсказать как «Исследование».

Далее мы проанализируем точность, отзыв и счет f1.

Но прежде чем анализировать его, мы должны понять, к чему относится каждое значение:

  • точность: количество случаев, классифицированных правильно, по сравнению с общим количеством случаев, которые должны быть правильными. Если количество ложных срабатываний имеет большое значение, этому показателю следует уделять больше внимания.
  • напомнить: количество случаев, классифицированных как положительные, прежде всего, которые были положительными, что было предсказано по сравнению с тем, что не было предсказано правильно. Если вам нужно уменьшить число ложноотрицательных результатов, этому показателю следует уделить наибольшее внимание.
  • f1score: это баланс между двумя предыдущими
precision    recall  f1-score   support

   exploration       0.96      0.95      0.96       199
   headhunters       0.91      0.97      0.94       179
  intelligence       0.96      0.94      0.95       133
     logistics       0.99      0.96      0.97       137
      politics       0.97      0.96      0.97       185
transportation       0.93      0.96      0.95       165
       weapons       0.99      0.94      0.97       163

      accuracy                           0.96      1161
     macro avg       0.96      0.96      0.96      1161
  weighted avg       0.96      0.96      0.96      1161

Как мы видим, модель ведет себя очень хорошо и надежна.

Тензорный поток

Давайте проверим, есть ли доступные графические процессоры, чтобы сделать обучение более эффективным.

Num GPUs Available:  1
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 11162430468200319055
, name: "/device:XLA_CPU:0"
device_type: "XLA_CPU"
memory_limit: 17179869184
locality {
}
incarnation: 233496321260097046
physical_device_desc: "device: XLA_CPU device"
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 6961726752
locality {
  bus_id: 1
  links {
  }
}
incarnation: 15285252465848281027
physical_device_desc: "device: 0, name: GeForce RTX 2070, pci bus id: 0000:01:00.0, compute capability: 7.5"
, name: "/device:XLA_GPU:0"
device_type: "XLA_GPU"
memory_limit: 17179869184
locality {
}
incarnation: 17115642552350290797
physical_device_desc: "device: XLA_GPU device"
]


[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]

Если у нас есть GPU, мы настраиваем тензорный поток так, чтобы он использовал его память без ограничений.

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

Таким образом, будет 7 столбцов, показывающих, к какому классу принадлежит каждая строка, и, следовательно, 7 выходных нейронов.

Из-за этой конкретной проблемы мы знаем, что каждый текст принадлежит только к ОДНОМУ классу, поэтому каждая строка может иметь только ОДИН и только ОДИН класс (столбец с «1»), это называется Mультиклассовая классификация. Если бы наша проблема могла иметь более одного класса, это была бы классификация с несколькими метками.

Давайте снова Tokenize (как и прежде, мы векторизируем ввод), используя библиотеку Tokenizer keras.

[4, 4318, 127, 2696, 2, 1845, 906, 3803, 3, 4, 11450, 2640, 127, 2175, 2, 1329, 10290, 3, 4798, 7039, 8635, 4319, 145, 4798, 7039, 3,
 1459, 416, 132, 1098]

151.14913414318946

6050

Как мы видим, длина текстов в среднем составляет 151, а максимальная — 6050, поэтому для нормализации входной длины размеченных текстовых последовательностей мы будем использовать длину 200.

Для тестирования этой архитектуры будут использоваться токенизированные данные. Данные будут разделены на 70% для обучения модели и 30% для тестирования, модель не видела, как выглядят эти 30%, поэтому мы можем проверить, насколько хорошо или плохо она обобщает.

Модель состоит из:

  • слой внедрения С длиной токенов + 1 (добавление 1 для «неизвестного» токена, любого токена, который не входит в список токенов) и длиной вектора внедрения 64 (это гиперпараметр модели)
  • Двунаправленный слой LSTM 64 (гиперпараметр)
  • Двунаправленный слой LSTM 32 (гиперпараметр)
  • слой из 64 (гиперпараметр) полностью связанных нейронов с активацией сопротивления
  • слой отсева
  • слой из 7 полностью связанных нейронов с активацией softmax

Последний слой имеет 7 нейронов, относящихся к 7 классам, которые должны быть предсказаны, и активация является softmax, поскольку она выполняет распределение вероятностей по всем нейронам, и нейрон с наибольшей вероятностью будет относиться к связанному классу, являющемуся предсказанным.

Модель будет использовать расчет потерь с помощью алгоритма categorical_crossentropy. Для проведения обучения оптимизатор для расчета градиента будет "adam", а вычисляемая метрика будет "accuracy".

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

Epoch 1/4
85/85 [==============================] - 5s 55ms/step - loss: 1.8506 - accuracy: 0.2142 - val_loss: 1.5143 - val_accuracy: 0.3463
Epoch 2/4
85/85 [==============================] - 3s 38ms/step - loss: 1.1420 - accuracy: 0.5251 - val_loss: 0.9627 - val_accuracy: 0.6503
Epoch 3/4
85/85 [==============================] - 3s 38ms/step - loss: 0.6128 - accuracy: 0.7843 - val_loss: 0.6739 - val_accuracy: 0.7933
Epoch 4/4
85/85 [==============================] - 3s 38ms/step - loss: 0.2878 - accuracy: 0.9184 - val_loss: 0.5204 - val_accuracy: 0.8562
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, None, 64)          2457408   
_________________________________________________________________
bidirectional (Bidirectional (None, None, 128)         66048     
_________________________________________________________________
bidirectional_1 (Bidirection (None, 64)                41216     
_________________________________________________________________
dense (Dense)                (None, 64)                4160      
_________________________________________________________________
dropout (Dropout)            (None, 64)                0         
_________________________________________________________________
dense_1 (Dense)              (None, 7)                 455       
=================================================================
Total params: 2,569,287
Trainable params: 2,569,287
Non-trainable params: 0
_________________________________________________________________

Как видно на графиках обучения, модель обучения имеет большую точность, а также при проверке мы должны быть осторожны с переобучением, поскольку мы можем переобучить модель, и тогда она не сможет обобщать.

Перейдем к сверточной модели.

сверточный

Epoch 1/4
43/43 [==============================] - 1s 28ms/step - loss: 1.8761 - accuracy: 0.2371 - val_loss: 1.6784 - val_accuracy: 0.3781
Epoch 2/4
43/43 [==============================] - 1s 21ms/step - loss: 0.6809 - accuracy: 0.8364 - val_loss: 0.3644 - val_accuracy: 0.8906
Epoch 3/4
43/43 [==============================] - 1s 21ms/step - loss: 0.0619 - accuracy: 0.9860 - val_loss: 0.3042 - val_accuracy: 0.9078
Epoch 4/4
43/43 [==============================] - 1s 21ms/step - loss: 0.0170 - accuracy: 0.9970 - val_loss: 0.2632 - val_accuracy: 0.9190

Модель состоит из:

  • слой вложений с длиной токенов + 1 (добавление 1 для «неизвестного» токена, любого токена, не входящего в список токенов) и длиной вектора встраивания 64 (это гиперпараметр модели )
  • Сверточный слой 1 измерения с 50 фильтрами и размером ядра 5 (длина окна, в котором будет двигаться свертка)
  • сгладить слой, чтобы все параметры были в виде списка, а не массива
  • слой из 100 (гиперпараметр) полностью связанных нейронов с активацией сопротивления
  • слой из 7 полностью связанных нейронов с активацией softmax

Как и в предыдущей модели, потому что есть 7 классов.

Результаты аналогичны предыдущей модели, но при проверке она ведет себя несколько лучше.

Мы собираемся классифицировать тестовый набор, чтобы провести анализ матрицы путаницы и метрик.

Получаем позицию нейрона с наибольшим значением и получаем класс, к которому он принадлежит.

precision    recall  f1-score   support

   exploration       0.89      0.95      0.92       199
   headhunters       0.98      0.89      0.93       179
  intelligence       0.95      0.79      0.86       133
     logistics       0.93      0.92      0.92       137
      politics       0.97      0.97      0.97       185
transportation       0.81      0.97      0.88       165
       weapons       0.95      0.91      0.93       163

      accuracy                           0.92      1161
     macro avg       0.92      0.91      0.92      1161
  weighted avg       0.92      0.92      0.92      1161

Как мы видим, транспортная часть имеет некоторые недостатки, но из-за слоев встраивания и сверток она должна лучше абстрагировать модель.

Приложение: Вложения

Вложения — это представления слов в плотной форме, в которых похожие слова имеют сходные кодировки и близки к словам, связанным сами с собой.

Давайте посмотрим на пример, используя данные из слоя встраивания из последнего обучения (свертки). Мы берем данные токенизатора и веса слоя встраивания и сохраняем их в файлах векторов и метаданных соответственно.

Мы можем использовать веб-сайт https://projector.tensorflow.org/, чтобы получить графическую проекцию нашей карты вложений, для этого мы загружаем файлы в раздел Загрузка и помечаем значок А, чтобы показать нам ярлыки в слова.

Как мы видим, ярлык «религиозный» имеет близкие (по косинусному расстоянию) ярлыки «сатана», «иисус» и «независимый».

Хотя наиболее известным примером вложений является представление концепций мужского и женского пола, связанных с понятиями короля и королевы для пола в дополнение к временам вервала и столице страны.

Код (скоро)

Контакт

Купи мне кофе