Мой проект с открытым исходным кодом
Простая реализация архитектуры глубокой нейронной сети для табличных данных с настраиваемой генерацией слоев и послойным увеличением количества нейронов. Использование аналогичного классического метода машинного обучения.
В этой статье мы обсудим, зачем нужна эта библиотека, проведем «учебник» и сравним точность предсказания DatRetClassifier и DatRetRegressor с созданием классических методов машинного обучения.
Введение
Для прогнозирования табличных данных чаще всего используются классические методы машинного обучения. Чаще всего реализуется в scikit-learn. Одним из преимуществ этой библиотеки является простота использования. Мы готовим данные, подгоняем и прогнозируем, готово.
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 для классификации с несколькими метками.
Преимущества
- простота и удобство использования. Соответствуйте и прогнозируйте и вуаля!
- автоматическая генерация архитектуры нейронной сети
- быстрая настройка параметров модели
- Поддержка графического процессора
- высокая точность предсказания
- поддержка многоуровневой классификации
- Tensorflow под капотом;)
Где взять?
Исходный код в настоящее время размещен на GitHub по адресу: GitHub — AbdualimovTP/datret: Реализация Tensorflow для структурированных табличных данных
Двоичные установщики для последней выпущенной версии доступны в Python Package Index (PyPI)
# PyPI pip install datret
Зависимости
- Tensorflow — библиотека с открытым исходным кодом в первую очередь для приложений глубокого обучения
- NumPy — добавлена поддержка больших многомерных массивов, матриц и высокоуровневых математических функций для работы с этими массивами
- Документация Pandas — документация pandas 1.5.2)
- Scikit-Learn — машинное обучение на Python
Быстрый старт
Обучение и прогнозирование модели реализовано как в scikit-learn. Подготовьте набор для тестирования и тренировки и запустите подгонку. Поддержка автоматической нормализации данных для нейронных сетей.
Обратите внимание! Не забудьте установить зависимости перед использованием модели. Вам потребуются установленные Tensorflow, Numpy, Pandas и Scikit-Learn.
Обратите внимание! Нет необходимости выполнять однократное кодирование прогнозирующих функций. Модель сделает это автоматически.
# 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. Количество эпох для обучения модели.
- Оптимизатор: строка (имя оптимизатора) или экземпляр оптимизатора. См. tf.keras.optimizers, по умолчанию =
Adam(learning_rate=0.001)
. На DatRetRegressor скорость обучения по умолчанию = 0,01. Встроенные классы оптимизатора тензорного потока. - потеря: функция потери. Может быть строкой (имя функции потерь). См. tf.keras.losses, по умолчанию для DatRetClassifier =
CategoricalCrossentropy()
, для DatRetRegressor =MeanSquaredError()
. Встроенные функции потерь. - подробно: «авто», 0, 1 или 2, по умолчанию = 0. Многословный режим. 0 = без звука, 1 = индикатор выполнения, 2 = одна строка в эпоху. «auto» по умолчанию равно 1 в большинстве случаев, но 2 при использовании с ParameterServerStrategy=0.
- number_neurons: int, по умолчанию = 500. Количество слоев в первом полносвязном слое. Последующие слои генерируются автоматически с вдвое меньшим количеством нейронов.
- validation_split: число с плавающей запятой от 0 до 1, по умолчанию = 0. Доля данных обучения, которые будут использоваться в качестве данных проверки. Модель будет выделять эту часть обучающих данных, не будет обучаться на ней и будет оценивать потери и любые метрики модели на этих данных в конце каждой эпохи.
- batch_size: целое число, по умолчанию = 1. Количество выборок на обновление градиента. Steps_per_epoch рассчитывается автоматически,
X_train.shape[0] // batch_size
- перемешивание: True или False, по умолчанию = True. Этот аргумент игнорируется, когда
x
является генератором или объектом tf.data.Dataset. «пакет» — это специальная опция для работы с ограничениями данных HDF5; он перемешивается кусками размером с пакет. - обратный вызов:
[]
, по умолчанию =[EarlyStopping(monitor='loss', mode='auto', patience=7, verbose=1), ReduceLROnPlateau(monitor='loss', factor=0.2, patience=3, min_lr=0.00001, verbose=1)]
. Обратные вызовы: утилиты, вызываемые в определенные моменты обучения модели.
Настраиваемые параметры метода fit
Параметры:
- нормализовать: True или 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 предсказуемых классов модель автоматически будет иметь эту архитектуру.
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
Для оценки точности классификатора мы будем использовать Базу данных диабета индейцев пима | Каггл. Сопоставимый показатель RocAucScore. Мы будем сравнивать DatRet с RandomForest и CatBoost из коробки.
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
Чтобы оценить точность регрессора, мы будем использовать Персональные наборы данных о медицинских расходах | Каггл. Сопоставимый показатель Среднеквадратическая ошибка. Мы будем сравнивать DatRet с RandomForest и CatBoost из коробки.
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 дает наилучшую точность.
В дальнейшем я планирую оценить точность модели на других наборах данных. Я также вижу возможности для улучшения качества прогнозирования. Планирую реализовать в следующих версиях библиотеки.