Изображение автора
Изображение автора

Мой open-source продукт. Rete neurale per la previsione di Dati tabulari. (it.)

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

В данной статье рассмотрим причину создания данной библиотеки, проведем "туториал" и сравним точность прогнозирования DatRetClassifier и DatRetRegressor с классическими методами машинного обучения.


Введение

Для прогнозирования табличных данных чаще всего используются классические методы машинного обучения. Наиболее часто реализованные в scikit-learn. Одним из преимуществ данной библиотеки является простота использования. Предподготавливаем данные, делаем fit и predict, готово.

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000, n_features=4,
                            n_informative=2, n_redundant=0,
                           random_state=0, shuffle=False)
clf = RandomForestClassifier(max_depth=2, random_state=0)
clf.fit(X, y)
print(clf.predict([[0, 0, 0, 0]]))

Использование нейронных сетей, в частности библиотек Tensorflow или PyTorch предполагает построение архитектуры модели нейронной сети и затем обучение и прогнозирование. Требует более высокий порог вхождения.

Реализовано много готовых архитектур нейронных сетей для работы с изображениями, текстом, звуком. Не так много для работы с табличными данными - пример TabNet.

Основной целью создания DatRet ставил понижение порога вхождения для работы с нейронными сетями. Реализовал обучение и прогнозирование данных, как в классических методах, например RandomForestClassifier или CatBoostClassifier. Для этого создал автоматическую генерацию архитектуры нейронной сети, исходя из количества выбранных нейронов в первом полносвязном слое. Второй целью, ставил попытку приблизиться по точности прогнозирования структурированных табличных данных к классическим методам.

В модели реализовано три класса:

  • DatRetClassifier для задач классификации.

  • DatRetRegressor для задач регресии

  • DatRetMultilabelClassifier для "многометочной" классификации.

Преимущества

  • простота и удобство использования. Fit и predict et Voila!

  • автоматическая генерация архитектуры нейроннной сети

  • быстрая настройка параметров модели

  • поддержка GPU

  • высокая точность прогнозирования

  • поддержка multilabel классификации

  • Tensorflow под капотом ;)

Установка

Исходный код в настоящее время размещен на GitHub по адресу: GitHub — AbdualimovTP/datret: реализация Tensorflow для структурированных табличных данных Двоичные установщики последней выпущенной версии доступны на веб-сайте Python. Индекс пакетов (PyPI)

# PyPI
pip install datret

Зависимости

Быстрый старт

Обучение и прогнозирование модели реализовано как в scikit-learn. Подготовьте трейновую и тестовую выборку и запустите обучение модели. Поддержка автоматической нормализации данных для нейронных сетей.

NB! Не забудьте установить зависимости перед использованием модели. Вам понадобятся установленные Tensorflow, Numpy, Pandas и Scikit-Learn.

NB! Нет необходимости выполнять one-hot encoding прогнозируюмых значений для задачи классификации. Модель сделает автоматически.

# load library
from datret.datret import DatRetClassifier, DatRetRegressor, DatRetMultilabelClassifier

# prepare train, test split. As in sklearn.
# for example
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=i)

# Call the regressor or classifier and train the model.
DR = DatRetClassifier() # DatRetRegressor works on the same principle
DR.fit(X_train, y_train)
# predict the actual label (or class) over a new set of data.
DR_predict = DR.predict(X_test)
# predict the class probabilities for each data point.
DR_predict_proba = DR.predict_proba(X_test) # Missing in DatRetRegressor, DatRetMultilabelClassifier

Настраиваемые параметры модели

Параметры :

  • epoch: int, по умолчанию = 30. Количество эпох для обучения модели.

  • optimizer: str, (имя оптимизатора) или экземпляра оптимизатора. См. tf.keras.optimizers, по умолчанию = Adam(learning_rate=0.001). В DatRetRegressor скорость обучения по умолчанию = 0,01.

  • loss: функция потери. str. См. tf.keras.losses , значение по умолчанию для DatRetClassifier = CategoricalCrossentropy(), для DatRetRegressor = MeanSquaredError().

  • verbose: 'авто', 0, 1 или 2, по умолчанию = 0. Выводит обучение модели по эпохам.

  • number_neurons: int, по умолчанию = 500. Количество слоев в первом полносвязном слое. Последующие слои генерируются автоматически с вдвое меньшим количеством нейронов.

  • validation_split: float от 0 до 1, по умолчанию = 0. Доля данных обучения, которые будут использоваться в качестве данных проверки. Модель будет выделять эту часть обучающих данных, не будет обучаться на ней и будет оценивать потери и любые метрики модели на этих данных в конце каждой эпохи.

  • batch_size: int , по умолчанию = 1. Количество выборок на обновление градиента. Steps_per_epoch рассчитывается автоматически, X_train.shape[0] // batch_size

  • shuffle: True или False, по умолчанию = True. "Перемешивание" обучающей выборки.

  • callback: [], по умолчанию = [EarlyStopping(monitor='loss', mode='auto', patience=7, verbose=1), ReduceLROnPlateau(monitor='loss', factor=0.2, patience=3, min_lr=0.00001, verbose=1)]. Сallbacks : утилиты, вызываемые в определенные моменты во время обучения модели.

Настраиваемые параметры метода fit .

Параметры:

  • normalize: True or False, по умолчание True. Автоматическая нормализация входящих данных. Используется MinMaxScaler.

Пример настройки модели:

# load library
import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam, Nadam
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
from tensorflow.keras.losses import CategoricalCrossentropy, MeanSquaredError, BinaryCrossentropy
from datret.datret import DatRetClassifier, DatRetRegressor, DatRetMultilabelClassifier

# prepare train, test split. As in sklearn.
# for example
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=i)

# Call the regressor or classifier and train the model.
DR = DatRetClassifier(epoch=50,
                      optimizer=Nadam(learning_rate=0.001),
                      loss=BinaryCrossentropy(),
                      verbose=1,
                      number_neurons=1000,
                      validation_split = 0.1,
                      batch_size=100,
                      shuffle=True,
                      callback=[])
DR.fit(X_train, y_train, normalize=True)
# predict the actual label (or class) over a new set of data.
DR_predict = DR.predict(X_test)
# predict the class probabilities for each data point.
DR_predict_proba = DR.predict_proba(X_test)

Архитектура модели

Модель генерирует архитектуру автоматически, исходя из количества нейронов в первом полносвязном слое. Например, при использовании number_neurons = 500в первом полносвязном слое и наличием 2-х прогнозируемых классов (0, 1) - нейронная сеть автоматически будет иметь данную архитектуру.

Model: "DatRet with number_neurons = 500"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, X_train.shape[0)]      0         

 dense (Dense)               (None, 500)               150500    

 dense_1 (Dense)             (None, 250)               125250    

 dense_2 (Dense)             (None, 125)               31375     

 dense_3 (Dense)             (None, 62)                7812      

 dense_4 (Dense)             (None, 31)                1953      

 dense_5 (Dense)             (None, 15)                480       

 dense_6 (Dense)             (None, 7)                 112       

 dense_7 (Dense)             (None, 3)                 24        

 dense_8 (Dense)             (None, 2)                 8         
                       (2 predictable classes)                               
=================================================================
Total params: 317,514
Trainable params: 317,514
Non-trainable params: 0

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

DatRetClassifier для задач классификации

Чтобы оценить точность классификатора, мы будем использовать Pima Indians Diabetes Database | Kaggle. Метрика RocAucScore. Буду сравнивать DatRet с RandomForest и CatBoost «из коробки». Полная версия ноутбука реализована в GitHub.

for i in [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]:
    X_train, X_test, y_train, y_test = train_test_split(data.drop(["Outcome"], axis=1), data["Outcome"],
                                                random_state=10, test_size=i)
    #RandomForest
    RF = RandomForestClassifier(random_state=0)
    RF.fit(X_train, y_train)
    RF_pred = RF.predict_proba(X_test)
    dataFrameRocAuc.loc['RandomForest'][f'{int(i*100)}%'] = np.round(roc_auc_score(y_test, RF_pred[:,1]), 2)
    
    #Catboost
    CB = CatBoostClassifier(random_state=0, verbose=0)
    CB.fit(X_train, y_train)
    CB_pred = CB.predict_proba(X_test)
    dataFrameRocAuc.loc['CatBoost'][f'{int(i*100)}%'] = np.round(roc_auc_score(y_test, CB_pred[:,1]), 2)
    
    #DatRet
    DR = DatRetClassifier(optimizer=Adam(learning_rate=0.001))
    DR.fit(X_train, y_train)
    DR_pred = DR.predict_proba(X_test)
    dataFrameRocAuc.loc['DatRet'][f'{int(i*100)}%'] = np.round(roc_auc_score(y_test, DR_pred[:,1]), 2)

10%

20%

30%

40%

50%

60%

RandomForest

0.79

0.81

0.81

0.79

0.82

0.82

CatBoost

0.78

0.82

0.82

0.8

0.81

0.82

DatRet

0.79

0.84

0.82

0.81

0.84

0.81

DatRetRegressor для задач регресии

Чтобы оценить точность регрессора, мы будем использовать наборы данных Medical Cost Personal Datasets | Kaggle. Метрика среднеквадратическая ошибка . Буду сравнивать DatRet с RandomForest и CatBoost «из коробки». Полная версия ноутбука реализована в GitHub.

for i in [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]:
    X_train, X_test, y_train, y_test = train_test_split(data.drop(["charges"], axis=1), data["charges"],
                                                random_state=10, test_size=i)
    #RandomForest
    RF = RandomForestRegressor(random_state=0)
    RF.fit(X_train, y_train)
    RF_pred = RF.predict(X_test)
    dataFrameRMSE.loc['RandomForest'][f'{int(i*100)}%'] = np.round(mean_squared_error(y_test, RF_pred, squared=False), 2)
    
    #Catboost
    CB = CatBoostRegressor(random_state=0, verbose=0)
    CB.fit(X_train, y_train)
    CB_pred = CB.predict(X_test)
    dataFrameRMSE.loc['CatBoost'][f'{int(i*100)}%'] = np.round(mean_squared_error(y_test, CB_pred, squared=False), 2)
    
    #DatRet
    DR = DatRetRegressor(optimizer=Adam(learning_rate=0.01))
    DR.fit(X_train, y_train)
    DR_pred = DR.predict(X_test)
    dataFrameRMSE.loc['DatRet'][f'{int(i*100)}%'] = np.round(mean_squared_error(y_test, DR_pred, squared=False), 2)

10%

20%

30%

40%

50%

60%

RandomForest

5736

5295

4777

4956

4904

4793

CatBoost

5732

5251

4664

4986

5044

4989

DatRet

5860

5173

4610

4927

5047

5780

Неплохие результаты для работы модели "из коробки".

В задаче классификации на 10%, 20%, 30%, 40%, 50% от общего датасета тестовой выборки DatRet показал лучшие результаты.

В задаче регресии на 20%, 30%, 40% от общего датасета тестовой выборки DatRet выдает лучшую точность.

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

Комментарии (0)