В этой статье мы построим простую нейронную сеть с помощью Keras. Мы предполагаем, что вы уже знакомы с пакетами машинного обучения, такими как scikit-learn, и другими научными пакетами, такими как Pandas и Numpy.

Обучение искусственной нейронной сети

Обучение искусственной нейронной сети включает следующие этапы:

  1. Веса случайным образом инициализируются числами, которые близки к нулю, но не равны нулю.
  2. Подайте наблюдения вашего набора данных на входной слой.
  3. Прямое распространение (слева направо): нейроны активируются, и получаются предсказанные значения.
  4. Сравните прогнозируемые результаты с фактическими значениями и измерьте ошибку.
  5. Обратное распространение (справа налево): веса корректируются.
  6. Повторите шаги 1–5.
  7. Одна эпоха достигается, когда весь обучающий набор прошел через нейронную сеть.

Деловая проблема

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

Предварительная обработка данных

Как и во многих других бизнес-задачах, предоставленные данные не будут обрабатываться за нас. Поэтому мы должны подготовить его таким образом, чтобы наш алгоритм его принял. Мы видим из набора данных, что у нас есть несколько категориальных столбцов. Нам нужно преобразовать их в нули и единицы, чтобы наша модель глубокого обучения могла их понять. Также следует отметить, что мы должны передать наш набор данных в модель в виде массивов numpy. Ниже мы импортируем необходимые пакеты и загружаем их в наш датасет.

import pandas as pd
import numpy as np
df = pd.read_csv(‘Datasets/claims/insurance_claims.csv’)

Затем мы преобразовываем категориальные столбцы в фиктивные переменные.

В этом случае мы используем drop_first=True, чтобы избежать ловушки фиктивной переменной. Например, если у вас есть категории a, b, c, d, вы можете удалить d как фиктивную переменную. Это потому, что если что-то не попадает ни в a, ни в b, ни в c, то оно определенно попадает в d. Это называется мультиколлинеарностью.

Мы используем sklearn’s train_test_split для разделения данных на обучающий набор и тестовый набор.

from sklearn.model_selection import train_test_split

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

Затем мы разбиваем данные на обучающий и тестовый набор. Мы используем 0,7 данных для обучения и 0,3 для тестирования.

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

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

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

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

Создание искусственной нейронной сети (ИНС)

Первое, что нам нужно сделать, это импортировать Keras. По умолчанию Keras будет использовать TensorFlow в качестве бэкэнда.

import keras

Далее нам нужно импортировать несколько модулей из Keras. Модуль Sequential требуется для инициализации ИНС, а модуль Dense требуется для построения слоев нашей ИНС.

from keras.models import Sequential
from keras.layers import Dense

Затем нам нужно инициализировать нашу ANN, создав экземпляр Sequential. Функция Sequential инициализирует линейный стек слоев. Это позволяет нам добавить больше слоев позже, используя модуль Dense.

classifier = Sequential()

Добавление входного слоя (первый скрытый слой)

Мы используем метод add для добавления различных слоев к нашей ИНС. Первый параметр - это количество узлов, которые вы хотите добавить к этому слою. Эмпирического правила относительно того, сколько узлов вам следует добавить, не существует. Однако распространенной стратегией является выбор количества узлов как среднего числа узлов во входном слое и количества узлов в выходном слое.

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

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

classiifier.add(
        Dense(3, kernel_initializer = ‘uniform’,
              activation = ‘relu’, input_dim=5))

Добавление второго скрытого слоя

Добавление второго скрытого слоя аналогично добавлению первого скрытого слоя.

classiifier.add(
      Dense(3, kernel_initializer = ‘uniform’,
            activation = ‘relu’))

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

Добавление выходного слоя

classifier.add(
     Dense(1, kernel_initializer = ‘uniform’,
           activation = ‘sigmoid’))

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

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

Составление ИНС

classifier.compile(optimizer= ‘adam’,
                  loss = ‘binary_crossentropy’,
                  metrics = [‘accuracy’])

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

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

Подгонка нашей ИНС к обучающей выборке

classifier.fit(X_train, y_train, batch_size = 10, epochs = 100)

X_train представляет независимые переменные, которые мы используем для обучения нашей ИНС, а y_train представляет столбец, который мы прогнозируем. Эпохи - это количество раз, которое мы собираемся передать полный набор данных через ИНС. Batch_size - количество наблюдений, после которых будут обновлены веса.

Прогнозирование с использованием обучающей выборки

y_pred = classifier.predict(X_test)

Это покажет нам вероятность того, что претензия является мошеннической. Затем мы устанавливаем порог в 50% для классификации претензии как мошеннической. Это означает, что любая претензия с вероятностью 0,5 и более будет классифицирована как мошенническая.

y_pred = (y_pred > 0.5)

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

Проверка матрицы неточностей

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)

Матрицу неточностей можно интерпретировать следующим образом. Из 2000 наблюдений 1550 + 175 наблюдений были предсказаны правильно, а 230 + 45 - неверно. Вы можете рассчитать точность, разделив количество правильных прогнозов на общее количество прогнозов. В данном случае (1550 + 175) / 2000, что дает вам 86%.

Создание единого прогноза

Допустим, страховая компания подает вам единовременную претензию. Они хотели бы знать, является ли претензия мошеннической. Что бы вы сделали, чтобы узнать?

new_pred = classifier.predict(sc.transform(np.array([[a,b,c,d]])))

где a, b, c, d представляют имеющиеся у вас функции.

new_pred = (new_prediction > 0.5)

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

Оценка нашей ИНС

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

Чтобы решить эту проблему, мы используем перекрестную проверку K-кратности с K, равным 10. Это разделит обучающую выборку на 10 крат. Затем мы обучим нашу модель 9 сгибам и протестируем ее с оставшимися сгибами. Поскольку у нас есть 10 складок, мы собираемся делать это итеративно, используя 10 комбинаций. Каждая итерация дает нам свою точность. Затем мы найдем среднее значение всех погрешностей и будем использовать его в качестве точности нашей модели. Мы также рассчитываем дисперсию, чтобы убедиться, что она минимальна.

У Keras есть оболочка scikit learn (KerasClassifier), которая позволяет нам включать K-кратную перекрестную проверку в наш код Keras.

from keras.wrappers.scikit_learn import KerasClassifier

Затем мы импортируем k-кратную функцию перекрестной проверки из scikit_learn

from sklearn.model_selection import cross_val_score

KerasClassifier ожидает, что одним из его аргументов будет функция, поэтому нам нужно построить эту функцию. Цель этой функции - построить архитектуру нашей ИНС.

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

Затем мы создаем новый классификатор, используя перекрестную проверку в K-кратном порядке, и передаем параметр build_fn в качестве функции, которую мы только что создали. Затем мы передаем размер пакета и количество эпох, как мы это делали в предыдущем классификаторе.

classiifier = KerasClassifier(build_fn = make_classifier,
                            batch_size=10, nb_epoch=100)

Чтобы применить k-кратную функцию перекрестной проверки, мы можем использовать функцию cross_val_score scikit-learn. Оценщик - это классификатор, который мы только что построили с make_classifier, и n_jobs=-1 будет использовать все доступные процессоры. cv - количество складок, 10 - типичный выбор. cross_val_score вернет десять значений точности десяти тестовых складок, использованных в вычислениях.

accuracies = cross_val_score(estimator = classifier,
                             X = X_train,
                             y = y_train,
                             cv = 10,
                             n_jobs = -1)

Чтобы получить относительную точность, мы получаем среднее значение точности.

mean = accuracies.mean()

Дисперсию можно получить следующим образом:

variance = accuracies.var()

Цель состоит в том, чтобы иметь небольшую разницу между точностями.

Борьба с переобучением

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

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

В этом случае мы применяем выпадение после первого скрытого слоя и после второго скрытого слоя. Использование коэффициента 0,1 означает, что 1% нейронов будет отключен на каждой итерации. Желательно начинать со ставки 0,1. Однако вы никогда не должны выходить за рамки 0,4, потому что теперь вы начнете недообучаться.

Настройка параметров

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

Первым шагом здесь является импорт модуля GridSearchCV из sklearn.

from sklearn.model_selection import GridSearchCV

Нам также необходимо изменить нашу make_classifier функцию следующим образом. Мы создаем новую переменную с именем optimizer , которая позволит нам добавить более одного оптимизатора в нашу переменную params.

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

classifier = KerasClassifier(build_fn = make_classifier)

Следующим шагом является создание словаря с параметрами, которые мы хотим настроить - в данном случае размер пакета, количество эпох и функция оптимизатора. Мы по-прежнему используем Адама в качестве оптимизатора и добавляем новый под названием rmsprop. Документация Keras рекомендует использовать rmsprop при работе с Рекуррентными нейронными сетями. Однако мы можем попробовать это для этой ИНС, чтобы увидеть, дает ли она лучший результат.

params = {
    'batch_size':[20,35],
    'nb_epoch':[150,500],
    'Optimizer':['adam','rmsprop']
}

Затем мы используем Grid Search для проверки этих параметров. Функция поиска по сетке ожидает нашу оценку, параметры, которые мы только что определили, показатель оценки и количество k-кратных значений.

grid_search = GridSearchCV(estimator=classifier,
                           param_grid=params,
                           scoring=’accuracy’,
                           cv=10)

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

grid_search = grid_search.fit(X_train,y_train)

Мы можем получить лучший выбор параметров, используя best_params из объекта поиска по сетке. Точно так же мы используем best_score_, чтобы получить лучший результат.

best_param = grid_search.best_params_
best_accuracy = grid_search.best_score_

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

Заключение

Искусственные нейронные сети - это всего лишь один из типов глубоких нейронных сетей. Существуют и другие сети, такие как рекуррентные нейронные сети (RNN), сверточные нейронные сети (CNN) и машины Больцмана.

RNN могут предсказать, пойдет ли цена акции вверх или вниз в будущем. CNN используются в компьютерном зрении - распознавании кошек и собак по набору изображений или распознавании присутствия раковых клеток в изображении мозга. Машины Больцмана используются при программировании рекомендательных систем. Возможно, мы сможем охватить одну из этих нейронных сетей в будущем.



Обсудите этот пост в Hacker News

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

Являясь независимой редакцией, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по данным и группам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим участникам и не продаем рекламу.

Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее создавать лучшие модели машинного обучения.