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

В этой статье давайте проведем вас через конкурс Kaggle по обнаружению мошенничества с кредитными картами. Глубокая нейронная сеть и две модели машинного обучения будут построены для решения этой проблемы и сравнения производительности различных моделей. Кроме того, для улучшения модели будут реализованы методы выборки данных. Как обычно, разделен на 9 частей:

  1. Бизнес-вызов
  2. Обзор данных
  3. Обработка данных
  4. DNN Модель здания
  5. Оценка модели DNN
  6. Древо решений
  7. Случайный лес
  8. Отбор проб
  9. Резюме

А теперь давайте начнем путешествие 🏃‍♂️🏃‍♀️.

1. Деловая задача

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

2. Обзор данных

Набор данных - это набор данных Kaggle по обнаружению мошенничества с кредитными картами здесь. Он содержит двухдневные транзакции, совершенные 09/2013 европейскими держателями карт. Набор данных содержит 492 мошенничества из 284 807 транзакций. Таким образом, он сильно несбалансирован: на позитив (мошенничество) приходится всего 0,17%.

Глядя на данные, показанные в видео, вы можете обнаружить, что они содержат только числовые переменные. Возможности V1, V2,… V28 - это основные компоненты, полученные с помощью преобразования PCA. Единственные функции, которые не были преобразованы, - это «Время» и «Количество». «Время» - это секунды, прошедшие между каждой транзакцией и первой. «Сумма» - это сумма транзакции. «Класс» - это переменная ответа, где 1 означает мошенничество, а 0 - в противном случае.

3. Обработка данных

Чтобы быстро понять распределение каждой переменной, давайте попробуем ниже.

Как вы заметили, переменная Сумма находится в диапазоне от 0 до 25 691,16. Чтобы уменьшить его широкий диапазон, мы используем Стандартизацию для удаления среднего и масштабирования до единичной дисперсии, так что 68% значений находятся между (-1, 1). Если вы хотите более подробно ознакомиться с этой темой, прочтите эту статью.

Конкретно,

scaler = StandardScaler()
data[‘NormalizedAmount’] = scaler.fit_transform(data[‘Amount’].values.reshape(-1, 1))

Обратите внимание, что мы должны использовать «.values.reshape (-1, 1)» для преобразования серии в массив и преобразования формы в 2D множество. Попробуйте удалить эту часть и увидите ошибку, которую вы получите. Это обычный 📣📣 !!

Теперь давайте разделим данные на X и y. Конкретно,

data = data.drop([‘Amount’, ‘Time’], axis = 1)
y = data[‘Class’]
X = data.drop([‘Class’], axis = 1)

Столбец [‘Amount’, ‘Time’] опущен, поскольку он не нужен для построения модели. Обратите внимание, что при удалении столбца мы устанавливаем ось = 1. Это еще одна распространенная ошибка, если вы не знакомы с функцией перетаскивания 📣📣!

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

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 0)

4. Построение модели DNN

Здесь мы построим 5-уровневую глубокую нейронную сеть, используя последовательную модель в Keras. Конкретно,

model = Sequential([
Dense(input_dim = 29, units = 16, activation = ‘relu’),
Dense(units = 24, activation = ‘relu’),
Dropout(0.5),
Dense(units = 20, activation = ‘relu’),
Dense(units = 24, activation = ‘relu’),
Dense(units =1, activation = ‘sigmoid’),])

Для 1-го скрытого слоя «input_dim» - это количество входных переменных. ‘units’ - количество узлов или нейронов в каждом слое.

Мы используем Rectified Linear Unit (ReLU) в качестве функции активации для скрытых слоев. ReLU обычно работает лучше, чем сигмовидная и гиперболическая касательная функции при построении глубоких нейронных сетей. Это связано с тем, что сигмоид и Тан имеют тенденцию к насыщению, когда входное значение слишком велико или слишком мало. Кроме того, они показывают только высокий градиент вокруг своих средних точек, например 0,5 для сигмовидной и 0 для tanh. Если вы хотите получить более подробную информацию о ReLU, не стесняйтесь читать это « статья".

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

5. Оценка модели DNN

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

model.compile(optimizer = ‘adam’, loss = ‘binary_crossentropy’, metrics = [‘accuracy’])
model.fit(X_train, y_train, batch_size = 15, epochs = 5)

Обратите внимание, что выше мы используем binary_crossentropy в качестве функции потерь и Adam для обновления весов сети. Адам - популярный алгоритм для быстрого достижения хороших результатов в области глубокого обучения. Если вы хотите узнать больше об Адаме, не стесняйтесь читать эту статью.

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

Большой. Теперь давайте оценим модель. Конкретно,

Помните, что мы используем "точность" в качестве показателей. Модель найдена с точностью 99,94% ✨✨!

Теперь один вопрос к вам: свидетельствует ли такая высокая точность о хорошей производительности? Если вы помните, точность - это сумма Ture Negative и True Positive, деленная на общий размер набора данных. Если 95% набора данных является отрицательным (без мошенничества), сеть умело предсказывает, что все данные будут отрицательными, что приведет к 95% точности. Однако для обнаружения мошенничества обнаружение положительных значений важнее, чем обнаружение отрицательных. Следовательно, нам нужны более точные показатели.

На рис.3 показана матрица неточностей с использованием тестового набора данных. DNN показывает точность 85,3%, отзыв 78,9% и оценку F1 82,0%. Около 20% мошенничества ошибочно классифицируются как не-мошенничество, что приводит к этим дополнительным платежам для клиентов, хотя точность составляет 99,94%. Так что есть достаточно места для улучшения модели DNN 📣📣.

6. Дерево решений

Как утверждает Википедия, дерево решений - это структура, похожая на блок-схему, в которой каждый внутренний узел представляет тест на функции (например, погода в солнечную или дождливую погоду), а каждый листовой узел представляет собой метку класса, созданную после всех тестов. Дерево решений направлено на изучение способов разделения наборов данных на основе условий. Итак, он непараметрический.

Теперь давайте построим модель дерева решений. Конкретно,

from sklearn.tree import DecisionTreeClassifier
decision_tree_model = DecisionTreeClassifier()
decision_tree_model.fit(X_train, y_train)
y_pred = decision_tree_model.predict(X_test)

На рис.4 показана матрица неточностей модели. Дерево решений дает точность 82,7%, отзыв 74,8% и оценку F1 78,6%, что хуже, чем модель DNN 😥😥!

7. Случайный лес

По сути, случайный лес (RF) - это набор деревьев решений. Каждое дерево голосует за класс, и класс, получивший наибольшее количество голосов, является прогнозируемым классом. Дерево решений строится на основе всего набора данных, а случайный лес случайным образом выбирает функции для построения нескольких деревьев решений и усреднения результата. Если вы хотите узнать больше о принципах работы RF и оптимизации параметров, прочтите эту статью.

Конкретно,

from sklearn.ensemble import RandomForestClassifier
rf_model = RandomForestClassifier(n_estimators = 100)
rf_model.fit(X_train, y_train)
y_pred = rf_model.predict(X_test)

Обучение модели занимает несколько минут. В итоге RF показывает точность 95%, отзыв 77,5% и оценку F1 85,3%, что лучше, чем DNN и модель дерева решений 🤪!

8. Выборка

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

8.1 Недостаточная выборка

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

Давайте сначала реализуем эту стратегию. Конкретно,

fraud_ind = np.array(data[data.Class == 1].index)
normal_ind = data[data.Class == 0].index
random_normal_ind = np.random.choice(normal_ind, num_frauds, replace = False)
random_normal_ind = np.array(random_normal_ind)
under_sample_data = data.iloc[under_sample_ind, :]
X_undersample = under_sample_data.iloc[:, under_sample_data.columns != ‘Class’]
y_undersample = under_sample_data.iloc[:, under_sample_data.columns == ‘Class’]

Выше мы случайным образом выбрали такое же количество не-мошенников, что и мошенничество, и создали новый набор данных. С уменьшенными данными повторно обучите модель DNN. В конце концов, недостаточная выборка дает точность 100%, отзыв - 87,6% и оценку F1 - 93,4%. Намного лучше, чем DNN без недостаточной выборки 😇!

8.2 SMOTE

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

SMOTE, впервые представленный Нитешем Чавлой в 2002 году, работает, выбирая данные, которые близки или похожи друг на друга в пространстве объектов, и проводит линию между данными, создавая новые данные в точке на этой линии. Это эффективно. потому что новые данные близки к классу меньшинства в пространстве функций. Если вы хотите узнать о SMOTE, не стесняйтесь читать статью Нитеша.

Теперь давайте реализуем SMOTE и повторно обучим модель. Конкретно,

from imblearn.over_sampling import SMOTE
X_resample, y_resample = SMOTE().fit_sample(X, y)

Приведенный выше код создал сбалансированный «y_resample» с 284 315 мошенничеством и 284 315 не-мошенничеством. После повторного обучения модели DNN SMOTE дает точность 99,8%, отзыв 100% и оценку F1 99,9%. Намного лучше, чем DNN с недовыборкой и без нее 😇😇!

9. Резюме

В итоге мы создали 5 моделей: DNN, Дерево решений и Случайный лес, DNN с недостаточной выборкой и DNN с SMOTE. Как показано в таблице ниже, DNN с SMOTE работает лучше всего.

Отлично! Вот и все путешествия. Если хотите посмотреть код, загляните в мой репозиторий здесь 🤞🤞.