С кодами в питоне для классификации текста

После рассмотрения AutoML для классификации и регрессии с использованием MLJAR и прогнозирования временных рядов с использованием AutoTS, на этот раз я получил возможность работать с классификацией с несколькими метками (а не с несколькими классами). Чтобы попробовать что-то новое, я погуглил auto-ml для классификации по нескольким меткам. И после некоторого глубокого погружения я узнал о Ludwig, декларативной платформе машинного обучения, которую можно использовать для классификации по нескольким меткам.

Итак, приступим

Но прежде чем забегать вперед

Что такое декларативная система машинного обучения?

Итак, могут быть типы систем ML

  • Гибкость. В таких системах разработчик кодирует все с нуля, используя такие библиотеки, как TensorFlow, Keras и PyTorch, используя утилиты, предоставляемые этими библиотеками. подвох в том, что вы собираетесь много кодировать. Примером может служить нейронная сеть, которую вы проектируете с нуля с помощью Tensorflow или Keras.
  • AutoML. В AutoML разработчик ничего не делает, кроме как полностью отходит на второй план. Это архитектура AutoML, которая позаботится обо всем, какую модель выбрать и какую предварительную обработку выполнить. Все!! Единственная загвоздка в том, что такие системы обладают оченьнизкой гибкостью, и разработчики не могут много настраивать.
  • Декларативные системы. Это нечто среднее между гибкими системами и системами AutoML, где разработчик может выбирать различные компоненты конвейера (хотя кодирование не требуется), в то время как все, что не указано, переходит к AutoML-части процесса. система. Итак, Декларативные системы поддерживают компромисс между гибкостью и AutoML. Ludwig — одна из таких систем.

При желании вы можете указать каждую деталь пайплайна, если же нет, то обо всем позаботится система AutoML компании Ludwig. Простой !!

Итак, не теряя ни секунды, давайте замараем руки с Людвигом.

Я бы использовал этот набор данных для остальной части поста, разархивируйте его и прочитайте train.csv.

  1. Импортируйте необходимые библиотеки и загрузите набор данных
#pip3 install ludwig

from ludwig.api import LudwigModel
import pandas as pd
import numpy as np
from sklearn.utils import resample
from nltk.corpus import stopwords
from sklearn.model_selection import train_test_split as tts
import re

train = pd.read_csv('train.csv')
labels = train.columns[3:]

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

def label_list(x):
    labels = []
    for key in  [y for y in x.keys()][3:]:
        if x[key]==1:
            labels.append('_'.join(key.split(' ')))
    return ' '.join(labels)
train['labels'] = train.apply(lambda x: label_list(x),axis=1)

Разделение данных в train-test

train, test= tts(train,test_size=0.2)

А вот и Людвиг.

config = {'input_features':[{'name':'TITLE','type':'text',
                            "preprocessing": {"word_tokenizer": "space"},
                            "encoder": {
                                        "type": "bert",
                                        "trainable": False}},
                            {'name':'ABSTRACT','type':'text',
                            "preprocessing": {"word_tokenizer": "space"},
                            "encoder": {
                                        "type": "bert",          
                                        "trainable": False}}],
          
         'output_features':[{'name':'labels','type':'set','loss':{'type': 'sigmoid_cross_entropy'}}],
         'preprocessing':{'split':{'column':'labels','probabilities':[0.7,0.1,0.2]}},
         'trainer':{'type':'trainer',
                    'epochs':100,
                    'batch_size':32,
                    'checkpoints_per_epoch':2,
                    'early_stopping':5,
                    'learning_rate':0.0005,
                    'optimizer':{'type':'adam'}
                   } 
         }
ludwig_model = LudwigModel(config)
train_stats, _, model_dir = ludwig_model.train(train[['TITLE','ABSTRACT','labels']])

Много вещей, чтобы понять

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

input_features: это список словарей, в каждом из которых содержится информация об одной input_feature, такой как имя, тип данных, предварительная обработка, необходимая для функции, и т. д. В нашем случае это 2 столбца «TITLE» и «ABSTRACT». . Мы также предоставили методологию для создания вложений слов.

Output_features: аналогично input_features, но с именами для столбца output_feature/label. В этом разделе мы также можем упомянуть функцию потерь. В данном случае это столбец «метки» с loss=’sigmoid_corss_entropy’. Обратите внимание, что для множественной классификации мы сохранили тип данных как «набор». Это имеет смысл. Верно?

раздел предварительная обработка помогает нам включить выполнение шагов предварительной обработки

1. Для всего набора данных (например, train-test-split)

2. Предварительная обработка для конкретного типа данных (например, для всех строковых или плавающих функций в наборе данных).

Поэтому, если есть какие-то общие этапы предварительной обработки, можно использовать этот раздел. Мы использовали его для внутреннего разделения между обучением, проверкой и тестированием набора данных с использованием случайной стратегии.

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

Людвиг может использовать между моделями «ecd» и «gbm», используя параметр model_type в конфигурации, где по умолчанию используется «ecd».

«gbm» — это не что иное, как алгоритмы повышения дерева (например, Light GBM).

Но что такое «ECD» (кодировщик-объединитель-декодер)?

Это основная архитектура нейронной сети, которой следует Людвиг.

Итак, конструкция проста,

  • Принимать несколько входных функций (также могут быть разные типы данных)
  • Выполните предварительную обработку (предпринимаются шаги по умолчанию, если разработчик ничего не упомянул в конфигурации для функции)
  • Кодировать с помощью модели кодировщика
  • Объединить все вложения, сформированные для разных функций (конкатенация по умолчанию, но возможны и другие операции для объединения разных вложений)
  • Используя шаги декодера и post_preprocessing, сгенерируйте вывод

Ниже вы можете увидеть, как архитектура настраивается в зависимости от различных условий задачи.

Хотя возможны и еще несколько параметров в файле конфигурации, который вы можете прочитать в документации

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

predictions, output_directory = model.predict(test[['TITLE','ABSTRACT']])

«предсказания» — это кадр данных со следующими значениями

Теперь мы будем рассчитывать точность макросов, отзыв и оценку f1, чтобы проанализировать производительность Людвига.

#basic preprocessing required 

test['predictions'] = [x for x in predictions['labels_predictions'].values]
test['labels'] = test['labels'].transform(lambda x:x.split(' '))

#initializing an empy dataframe
predict = pd.DataFrame(index=[x for x in test.index],columns=['TP','FP','FN']).fillna(0)

Расчет FP, FN и TP наряду с классовыми попаданиями и промахами

for index,rows in test.iterrows():
    labels_ = set(rows['labels'])
    predict_ = set(rows['predictions'])
    predict.at[index,'TP'] = len(labels_.intersection(predict_))
    predict.at[index,'FP'] = len(predict_-labels_)
    predict.at[index,'FN'] = len(labels_-predict_)

sum_dict = predict.sum()
precision = sum_dict['TP']/(sum_dict['FP']+sum_dict['TP'])
recall = sum_dict['TP']/(sum_dict['FN']+sum_dict['TP'])
f1 = 2*precision*recall/(precision+recall)
print("precision=",precision)
print("recall=",recall)
print("f1=",f1)

Результаты довольно хорошие, учитывая тот факт, что мы почти ничего не сделали!!

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