Глубокое обучение Python - Реализации

В этой реализации глубокого обучения наша цель состоит в том, чтобы спрогнозировать убыль клиентов или отток данных для определенного банка - какие клиенты могут покинуть эту банковскую службу. Используемый набор данных относительно невелик и содержит 10000 строк с 14 столбцами. Мы используем дистрибутив Anaconda и такие фреймворки, как Theano, TensorFlow и Keras. Keras построен на основе Tensorflow и Theano, которые функционируют как его серверные части.

# Artificial Neural Network
# Installing Theano
pip install --upgrade theano

# Installing Tensorflow
pip install –upgrade tensorflow

# Installing Keras
pip install --upgrade keras

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

In[]:

# Importing the libraries
   import numpy as np
   import matplotlib.pyplot as plt
   import pandas as pd
 
# Importing the database
   dataset = pd.read_csv('Churn_Modelling.csv')

Шаг 2

Мы создаем матрицы характеристик набора данных и целевой переменной, которая представляет собой столбец 14, помеченный как «Exited».

Первоначальный вид данных показан ниже -

In[]:
X = dataset.iloc[:, 3:13].values
Y = dataset.iloc[:, 13].values
X

Вывод

Шаг 3

Y

Вывод

array([1, 0, 1, ..., 1, 1, 0], dtype = int64)

Шаг 4

Мы упрощаем анализ, кодируя строковые переменные. Мы используем функцию ScikitLearn LabelEncoder для автоматического кодирования различных меток в столбцах со значениями от 0 до n_classes-1.

from sklearn.preprocessing import LabelEncoder, OneHotEncoder
labelencoder_X_1 = LabelEncoder() 
X[:,1] = labelencoder_X_1.fit_transform(X[:,1]) 
labelencoder_X_2 = LabelEncoder() 
X[:, 2] = labelencoder_X_2.fit_transform(X[:, 2])
X

Вывод

В приведенных выше выходных данных названия стран заменены на 0, 1 и 2; в то время как мужчина и женщина заменяются на 0 и 1.

Шаг 5

Labelling Encoded Data

Мы используем то же самое ScikitLearn библиотека и другая функция, называемая OneHotEncoder просто передать номер столбца, создав фиктивную переменную.

onehotencoder = OneHotEncoder(categorical features = [1])
X = onehotencoder.fit_transform(X).toarray()
X = X[:, 1:]
X

Теперь первые 2 столбца представляют страну, а 4-й столбец - пол.

Вывод

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

Шаг 6

Мы используем ScikitLearn's train_test_splitфункция для разделения наших данных на обучающий набор и тестовый набор. Мы сохраняем соотношение между поездами и тестами как 80:20.

#Splitting the dataset into the Training set and the Test Set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)

Некоторые переменные имеют значения в тысячах, а некоторые - в десятках или единицах. Мы масштабируем данные, чтобы они были более репрезентативными.

Шаг 7

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

# Feature Scaling
fromsklearn.preprocessing import StandardScaler 
sc = StandardScaler() 
X_train = sc.fit_transform(X_train) 
X_test = sc.transform(X_test)

Вывод

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

Шаг 8

Мы импортируем сюда необходимые модули. Нам нужен модуль Sequential для инициализации нейронной сети и плотный модуль для добавления скрытых слоев.

# Importing the Keras libraries and packages 
import keras 
from keras.models import Sequential 
from keras.layers import Dense

Шаг 9

Мы назовем эту модель классификатором, поскольку наша цель - классифицировать отток клиентов. Затем мы используем модуль Sequential для инициализации.

#Initializing Neural Network 
classifier = Sequential()

Шаг 10

Мы добавляем скрытые слои один за другим, используя функцию плотности. В приведенном ниже коде мы увидим множество аргументов.

Наш первый параметр output_dim. Это количество узлов, которые мы добавляем к этому слою.initэто инициализация Stochastic Gradient Decent. В нейронной сети мы назначаем веса каждому узлу. При инициализации веса должны быть близки к нулю, и мы случайным образом инициализируем веса, используя равномерную функцию. Вinput_dimПараметр нужен только для первого слоя, так как модели не известно количество наших входных переменных. Здесь общее количество входных переменных равно 11. На втором уровне модели автоматически известно количество входных переменных из первого скрытого слоя.

Выполните следующую строку кода, чтобы добавить входной слой и первый скрытый слой -

classifier.add(Dense(units = 6, kernel_initializer = 'uniform', 
activation = 'relu', input_dim = 11))

Выполните следующую строку кода, чтобы добавить второй скрытый слой -

classifier.add(Dense(units = 6, kernel_initializer = 'uniform', 
activation = 'relu'))

Выполните следующую строку кода, чтобы добавить выходной слой -

classifier.add(Dense(units = 1, kernel_initializer = 'uniform', 
activation = 'sigmoid'))

Шаг 11

Compiling the ANN

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

Вот краткое объяснение аргументов.

Первый аргумент OptimizerЭто алгоритм, используемый для поиска оптимального набора весов. Этот алгоритм называетсяStochastic Gradient Descent (SGD). Здесь мы используем один из нескольких типов, называемый «оптимизатором Адама». SGD зависит от потерь, поэтому наш второй параметр - это убытки. Если наша зависимая переменная является двоичной, мы используем функцию логарифмических потерь, называемую‘binary_crossentropy’, и если наша зависимая переменная имеет более двух категорий на выходе, мы используем ‘categorical_crossentropy’. Мы хотим улучшить производительность нашей нейронной сети на основеaccuracy, поэтому мы добавляем metrics как точность.

# Compiling Neural Network 
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

Шаг 12

На этом шаге необходимо выполнить ряд кодов.

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

Теперь мы обучаем нашу модель на обучающих данных. Мы используемfitметод, чтобы соответствовать нашей модели. Мы также оптимизируем веса, чтобы повысить эффективность модели. Для этого нам нужно обновить веса.Batch size - количество наблюдений, после которых мы обновляем веса. Epoch- общее количество итераций. Значения размера пакета и эпохи выбираются методом проб и ошибок.

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

Прогнозы и оценка модели

# Predicting the Test set results
y_pred = classifier.predict(X_test)
y_pred = (y_pred > 0.5)

Прогнозирование одного нового наблюдения

# Predicting a single new observation
"""Our goal is to predict if the customer with the following data will leave the bank:
Geography: Spain
Credit Score: 500
Gender: Female
Age: 40
Tenure: 3
Balance: 50000
Number of Products: 2
Has Credit Card: Yes
Is Active Member: Yes

Шаг 13

Predicting the test set result

Результат прогноза даст вам вероятность ухода клиента из компании. Мы преобразуем эту вероятность в двоичные 0 и 1.

# Predicting the Test set results 
y_pred = classifier.predict(X_test) 
y_pred = (y_pred > 0.5)
new_prediction = classifier.predict(sc.transform
(np.array([[0.0, 0, 500, 1, 40, 3, 50000, 2, 1, 1, 40000]])))
new_prediction = (new_prediction > 0.5)

Шаг 14.

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

Making the Confusion Matrix

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

Вывод

loss: 0.3384 acc: 0.8605
[ [1541 54]
[230 175] ]

Из матрицы путаницы точность нашей модели может быть рассчитана как -

Accuracy = 1541+175/2000=0.858

We achieved 85.8% accuracy, и это хорошо.

Алгоритм прямого распространения

В этом разделе мы узнаем, как написать код для прямого распространения (прогнозирования) для простой нейронной сети.

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

Входные данные предварительно загружаются как входные данные, а веса находятся в словаре, называемом весами. Массив весов для первого узла в скрытом слое представлен в весах ['node_0'], а для второго узла в скрытом слое - в весах ['node_1'] соответственно.

Веса, подаваемые в выходной узел, доступны в весах.

Выпрямленная функция линейной активации

«Функция активации» - это функция, которая работает на каждом узле. Он преобразует ввод узла в некоторый вывод.

Выпрямленная функция линейной активации (называемая ReLU ) широко используется в высокопроизводительных сетях. Эта функция принимает на входе одно число, возвращая 0, если ввод отрицательный, и ввод как вывод, если ввод положительный.

Вот несколько примеров -

  • relu (4) = 4
  • relu (-2) = 0

Заполняем определение функции relu () -

  • Мы используем функцию max (), чтобы вычислить значение для вывода relu ().
  • Мы применяем функцию relu () к node_0_input, чтобы вычислить node_0_output.
  • Мы применяем функцию relu () к node_1_input для вычисления node_1_output.
import numpy as np
input_data = np.array([-1, 2])
weights = {
   'node_0': np.array([3, 3]),
   'node_1': np.array([1, 5]),
   'output': np.array([2, -1])
}
node_0_input = (input_data * weights['node_0']).sum()
node_0_output = np.tanh(node_0_input)
node_1_input = (input_data * weights['node_1']).sum()
node_1_output = np.tanh(node_1_input)
hidden_layer_output = np.array(node_0_output, node_1_output)
output =(hidden_layer_output * weights['output']).sum()
print(output)

def relu(input):
   '''Define your relu activation function here'''
   # Calculate the value for the output of the relu function: output
   output = max(input,0)
      # Return the value just calculated
   return(output)
# Calculate node 0 value: node_0_output
node_0_input = (input_data * weights['node_0']).sum()
node_0_output = relu(node_0_input)

# Calculate node 1 value: node_1_output
node_1_input = (input_data * weights['node_1']).sum()
node_1_output = relu(node_1_input)

# Put node values into array: hidden_layer_outputs
hidden_layer_outputs = np.array([node_0_output, node_1_output])

# Calculate model output (do not apply relu)
odel_output = (hidden_layer_outputs * weights['output']).sum()
print(model_output)# Print model output

Вывод

0.9950547536867305
-3

Применение сети ко многим наблюдениям / строкам данных

В этом разделе мы узнаем, как определить функцию под названием pred_with_network (). Эта функция будет генерировать прогнозы для нескольких наблюдений данных, взятых из сети выше, взятой как input_data. Используются веса, указанные в приведенной выше сети. Также используется определение функции relu ().

Давайте определим функцию под названием pred_with_network (), которая принимает два аргумента - input_data_row и weights - и возвращает прогноз из сети в качестве вывода.

Мы вычисляем входные и выходные значения для каждого узла, сохраняя их как: node_0_input, node_0_output, node_1_input и node_1_output.

Чтобы вычислить входное значение узла, мы умножаем соответствующие массивы вместе и вычисляем их сумму.

Чтобы вычислить выходное значение узла, мы применяем функцию relu () к входному значению узла. Мы используем цикл for для перебора input_data -

Мы также используем наш pred_with_network () для генерации прогнозов для каждой строки input_data - input_data_row. Мы также добавляем каждый прогноз к результатам.

# Define predict_with_network()
def predict_with_network(input_data_row, weights):
   # Calculate node 0 value
   node_0_input = (input_data_row * weights['node_0']).sum()
   node_0_output = relu(node_0_input)
   
   # Calculate node 1 value
   node_1_input = (input_data_row * weights['node_1']).sum()
   node_1_output = relu(node_1_input)
   
   # Put node values into array: hidden_layer_outputs
   hidden_layer_outputs = np.array([node_0_output, node_1_output])
   
   # Calculate model output
   input_to_final_layer = (hidden_layer_outputs*weights['output']).sum()
   model_output = relu(input_to_final_layer)
# Return model output
   return(model_output)

# Create empty list to store prediction results
results = []
for input_data_row in input_data:
   # Append prediction to results
   results.append(predict_with_network(input_data_row, weights))
print(results)# Print results

Вывод

[0, 12]

Здесь мы использовали функцию relu, где relu (26) = 26, relu (-13) = 0 и так далее.

Глубокие многослойные нейронные сети

Здесь мы пишем код для прямого распространения для нейронной сети с двумя скрытыми слоями. Каждый скрытый слой имеет два узла. Входные данные были предварительно загружены какinput_data. Узлы в первом скрытом слое называются node_0_0 и node_0_1.

Их веса предварительно загружаются как веса ['node_0_0'] и веса ['node_0_1'] соответственно.

Узлы во втором скрытом слое называются node_1_0 and node_1_1. Их веса предварительно загружены какweights['node_1_0'] и weights['node_1_1'] соответственно.

Затем мы создаем вывод модели из скрытых узлов, используя веса, предварительно загруженные как weights['output'].

Мы вычисляем node_0_0_input, используя его веса weights ['node_0_0'] и заданные input_data. Затем примените функцию relu (), чтобы получить node_0_0_output.

Мы делаем то же самое, что и выше, для node_0_1_input, чтобы получить node_0_1_output.

Мы вычисляем node_1_0_input, используя его весовые коэффициенты ['node_1_0'] и выходы из первого скрытого слоя - hidden_0_outputs. Затем мы применяем функцию relu (), чтобы получить node_1_0_output.

Мы делаем то же, что и выше, для node_1_1_input, чтобы получить node_1_1_output.

Мы вычисляем model_output, используя веса ['output'] и выходы из массива hidden_1_outputs второго скрытого слоя. Мы не применяем функцию relu () к этому выводу.

import numpy as np
input_data = np.array([3, 5])
weights = {
   'node_0_0': np.array([2, 4]),
   'node_0_1': np.array([4, -5]),
   'node_1_0': np.array([-1, 1]),
   'node_1_1': np.array([2, 2]),
   'output': np.array([2, 7])
}
def predict_with_network(input_data):
   # Calculate node 0 in the first hidden layer
   node_0_0_input = (input_data * weights['node_0_0']).sum()
   node_0_0_output = relu(node_0_0_input)
   
   # Calculate node 1 in the first hidden layer
   node_0_1_input = (input_data*weights['node_0_1']).sum()
   node_0_1_output = relu(node_0_1_input)
   
   # Put node values into array: hidden_0_outputs
   hidden_0_outputs = np.array([node_0_0_output, node_0_1_output])
   
   # Calculate node 0 in the second hidden layer
   node_1_0_input = (hidden_0_outputs*weights['node_1_0']).sum()
   node_1_0_output = relu(node_1_0_input)
   
   # Calculate node 1 in the second hidden layer
   node_1_1_input = (hidden_0_outputs*weights['node_1_1']).sum()
   node_1_1_output = relu(node_1_1_input)
   
   # Put node values into array: hidden_1_outputs
   hidden_1_outputs = np.array([node_1_0_output, node_1_1_output])
   
   # Calculate model output: model_output
   model_output = (hidden_1_outputs*weights['output']).sum()
      # Return model_output
   return(model_output)
output = predict_with_network(input_data)
print(output)

Вывод

364