Библиотеки PyTorch и TensorFlow – это две наиболее часто используемые библиотеки Python для глубокого обучения. PyTorch разрабатывается Facebook, в то время как TensorFlow-это проект Google. В этой статье вы увидите, как библиотека Pitch может быть использована для решения задач классификации.
Задачи классификации относятся к категории задач машинного обучения, где задается набор признаков, задача состоит в том, чтобы предсказать дискретное значение. Предсказание того, является ли опухоль злокачественной или нет, а также вероятность того, что студент сдаст или провалит экзамен, – вот некоторые из распространенных примеров проблем классификации.
В этой статье, учитывая определенные характеристики клиента банка, мы спрогнозироваем, покинет ли клиент банк через 6 месяцев. Феномен, когда клиент покидает организацию, также называется оттоком клиентов. Поэтому наша задача-прогнозировать отток клиентов на основе различных характеристик клиентов.
Прежде чем продолжить, предполагается, что вы владеете языком программирования Python среднего уровня и установили библиотеку PyTorch. Кроме того, может помочь знание основных концепций машинного обучения. Если вы еще не установили Pitch, вы можете сделать это с помощью следующей команды pip:
$ pip install pytorch
Набор данных
Набор данных, который мы собираемся использовать в этой статье, находится в свободном доступе по этой ссылке Kaggle . Давайте импортируем необходимые библиотеки и набор данных в наше приложение Python:
import torch import torch.nn as nn import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline
Мы можем использовать метод read_csv()
библиотеки pandas
для импорта CSV-файла, содержащего наш набор данных.
dataset = pd.read_csv(r'E:Datasets\customer_data.csv')
Давайте напечатаем форму нашего набора данных:
dataset.shape
Выход:
(10000, 14)
Вывод показывает, что набор данных содержит 10 тысяч записей и 14 столбцов.
Мы можем использовать метод head()
фрейма данных pandas для печати первых пяти строк нашего набора данных.
dataset.head()
Выход:
Вы можете увидеть 14 столбцов в нашем наборе данных. Основываясь на первых 13 столбцах, наша задача состоит в том, чтобы предсказать значение для 14-го столбца, т. е. Exited
. Важно отметить, что значения для первых 13 столбцов записываются за 6 месяцев до получения значения для столбца Exited
, поскольку задача состоит в том, чтобы предсказать отток клиентов через 6 месяцев с момента записи информации о клиентах.
Исследовательский Анализ Данных
Давайте проведем некоторый исследовательский анализ данных в нашем наборе данных. Сначала мы спрогнозироваем отношение клиентов, которые фактически покинули банк через 6 месяцев, и используем круговую диаграмму для визуализации.
Давайте сначала увеличим размер графика по умолчанию для графиков:
fig_size = plt.rcParams["figure.figsize"] fig_size[0] = 10 fig_size[1] = 8 plt.rcParams["figure.figsize"] = fig_size
Следующий сценарий рисует круговую диаграмму для столбца Excited
.
dataset.Exited.value_counts().plot(kind='pie', autopct='%1.0f%%', colors=['skyblue', 'orange'], explode=(0.05, 0.05))
Выход:
Вывод показывает, что в нашем наборе данных 20% клиентов покинули банк. Здесь 1 относится к случаю, когда клиент покинул банк, где 0 относится к сценарию, когда клиент не покинул банк.
Давайте построим график количества клиентов из всех географических местоположений в наборе данных:
sns.countplot(x='Geography', data=dataset)
Выход:
Результаты показывают, что почти половина клиентов принадлежит Франции, в то время как соотношение клиентов, принадлежащих Испании и Германии, составляет 25% каждый.
Давайте теперь построим график количества клиентов из каждого уникального географического местоположения вместе с информацией об оттоке клиентов. Для этого мы можем использовать функцию count plot()
из библиотеки seaborn
.
sns.countplot(x='Exited', hue='Geography', data=dataset)
Выход:
Результаты показывают, что, хотя общее число французских клиентов в два раза превышает число испанских и немецких клиентов, соотношение клиентов, покинувших банк, одинаково для французских и немецких клиентов. Точно так же общее число немецких и испанских клиентов одинаково, но число немецких клиентов, покинувших банк, в два раза превышает число испанских клиентов, что показывает, что немецкие клиенты с большей вероятностью покинут банк через 6 месяцев.
В этой статье мы не будем визуально отображать информацию, связанную с остальными столбцами нашего набора данных, но если вы хотите сделать это, вы можете проверить мою статью о том, как выполнить исследовательский анализ данных с помощью библиотеки Python Seaborn .
Предварительная обработка данных
Прежде чем обучать нашу модель PyTorch, мы должны предварительно обработать наши данные. Если вы посмотрите на набор данных, вы увидите, что он имеет два типа столбцов: числовые и Категориальные. Числовые столбцы содержат числовую информацию. Кредитный рейтинг
, Баланс
, Возраст
и т. Д. Аналогично, География
и Пол
являются категориальными столбцами, поскольку они содержат категориальную информацию, такую как местоположение и пол клиентов. Есть несколько столбцов, которые можно рассматривать как числовые, так и категориальные. Например, столбец HasCrCard
может иметь в качестве значений 1 или 0. Однако столбцы HasCrCard
содержат информацию о том, есть ли у клиента кредитная карта. Рекомендуется, чтобы столбцы, которые могут рассматриваться как категориальные, так и числовые, рассматривались как категориальные. Однако это полностью зависит от знания предметной области набора данных.
Давайте снова напечатаем все столбцы в нашем наборе данных и выясним, какие из столбцов можно рассматривать как числовые, а какие-как категориальные. Атрибут columns
фрейма данных выводит все имена столбцов:
dataset.columns
Выход:
Index(['RowNumber', 'CustomerId', 'Surname', 'CreditScore', 'Geography', 'Gender', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'HasCrCard', 'IsActiveMember', 'EstimatedSalary', 'Exited'], dtype='object')
Из столбцов нашего набора данных мы не будем использовать столбцы RowNumber
, CustomerID
и Name
, поскольку значения для этих столбцов полностью случайны и не имеют никакого отношения к выходным данным. Например, фамилия клиента никак не влияет на то, покинет ли он банк или нет. Среди остальных столбцов Geography
, Gender
, HasCrCard
и Is Active Member
столбцы можно рассматривать как категориальные столбцы. Давайте создадим список этих столбцов:
categorical_columns = ['Geography', 'Gender', 'HasCrCard', 'IsActiveMember']
Все остальные столбцы, кроме столбца Excited
, можно рассматривать как числовые столбцы.
numerical_columns = ['CreditScore', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'EstimatedSalary']
Наконец, выходные данные (значения из столбца Excited
) хранятся в переменной outputs
.
outputs = ['Exited']
Мы создали списки категориальных, числовых и выходных столбцов. Однако на данный момент тип категориальных столбцов не является категориальным. Вы можете проверить тип всех столбцов в наборе данных с помощью следующего скрипта:
dataset.dtypes
Выход:
RowNumber int64 CustomerId int64 Surname object CreditScore int64 Geography object Gender object Age int64 Tenure int64 Balance float64 NumOfProducts int64 HasCrCard int64 IsActiveMember int64 EstimatedSalary float64 Exited int64 dtype: object
Вы можете видеть, что тип для столбцов Geography
и Gender
является объектом, а тип для Nascar cars
и isActive
columns – это int64. Нам нужно преобразовать типы категориальных столбцов в category
. Мы можем сделать это с помощью функции astype ()
, как показано ниже:
for category in categorical_columns: dataset[category] = dataset[category].astype('category')
Теперь, если вы снова построите типы столбцов в нашем наборе данных, вы увидите следующие результаты:
dataset.dtypes
Выход
RowNumber int64 CustomerId int64 Surname object CreditScore int64 Geography category Gender category Age int64 Tenure int64 Balance float64 NumOfProducts int64 HasCrCard category IsActiveMember category EstimatedSalary float64 Exited int64 dtype: object
Теперь давайте посмотрим все категории в столбце География
:
dataset['Geography'].cat.categories
Выход:
Index(['France', 'Germany', 'Spain'], dtype='object')
При изменении типа данных столбца на категорию каждой категории в столбце присваивается уникальный код. Например, давайте построим первые пять строк столбца Geography
и выведем значения кода для первых пяти строк:
dataset['Geography'].head()
Выход:
0 France 1 Spain 2 France 3 France 4 Spain Name: Geography, dtype: category Categories (3, object): [France, Germany, Spain]
Следующий сценарий строит коды для значений в первых пяти строках столбца Geography
:
dataset['Geography'].head().cat.codes
Выход:
0 0 1 2 2 0 3 0 4 2 dtype: int8
Вывод показывает, что Франция была закодирована как 0, а Испания-как 2.
Основная цель отделения категориальных столбцов от числовых заключается в том, что значения в числовом столбце могут быть непосредственно введены в нейронные сети. Однако сначала значения категориальных столбцов должны быть преобразованы в числовые типы. Кодирование значений в категориальном столбце частично решает задачу численного преобразования категориальных столбцов.
Поскольку мы будем использовать шаг для обучения модели, нам нужно преобразовать наши категориальные и числовые столбцы в тензоры.
Давайте сначала преобразуем категориальные столбцы в тензоры. В PyTorch тензоры могут быть созданы с помощью массивов numpy. Сначала мы преобразуем данные в четырех категориальных столбцах в массивы numpy, а затем складываем все столбцы горизонтально, как показано в следующем сценарии:
geo = dataset['Geography'].cat.codes.values gen = dataset['Gender'].cat.codes.values hcc = dataset['HasCrCard'].cat.codes.values iam = dataset['IsActiveMember'].cat.codes.values categorical_data = np.stack([geo, gen, hcc, iam], 1) categorical_data[:10]
Приведенный выше сценарий печатает первые десять записей из категориальных столбцов, расположенных горизонтально. Результат выглядит следующим образом:
Выход:
array([[0, 0, 1, 1], [2, 0, 0, 1], [0, 0, 1, 0], [0, 0, 0, 0], [2, 0, 1, 1], [2, 1, 1, 0], [0, 1, 1, 1], [1, 0, 1, 0], [0, 1, 0, 1], [0, 1, 1, 1]], dtype=int8)
Теперь, чтобы создать тензор из вышеупомянутого массива numpy, вы можете просто передать массив в класс tensor
модуля torch
. Помните, что для категориальных столбцов тип данных должен быть torch.int64
.
categorical_data = torch.tensor(categorical_data, dtype=torch.int64) categorical_data[:10]
Выход:
tensor([[0, 0, 1, 1], [2, 0, 0, 1], [0, 0, 1, 0], [0, 0, 0, 0], [2, 0, 1, 1], [2, 1, 1, 0], [0, 1, 1, 1], [1, 0, 1, 0], [0, 1, 0, 1], [0, 1, 1, 1]])
В выходных данных вы можете видеть, что массив категориальных данных numpy теперь преобразован в объект tensor
.
Таким же образом мы можем преобразовать наши числовые столбцы в тензоры:
numerical_data = np.stack([dataset[col].values for col in numerical_columns], 1) numerical_data = torch.tensor(numerical_data, dtype=torch.float) numerical_data[:5]
Выход:
tensor([[6.1900e+02, 4.2000e+01, 2.0000e+00, 0.0000e+00, 1.0000e+00, 1.0135e+05], [6.0800e+02, 4.1000e+01, 1.0000e+00, 8.3808e+04, 1.0000e+00, 1.1254e+05], [5.0200e+02, 4.2000e+01, 8.0000e+00, 1.5966e+05, 3.0000e+00, 1.1393e+05], [6.9900e+02, 3.9000e+01, 1.0000e+00, 0.0000e+00, 2.0000e+00, 9.3827e+04], [8.5000e+02, 4.3000e+01, 2.0000e+00, 1.2551e+05, 1.0000e+00, 7.9084e+04]])
В выходных данных вы можете увидеть первые пять строк, содержащих значения для шести числовых столбцов нашего набора данных.
Последний шаг-преобразование выходного массива numpy в объект tensor
.
outputs = torch.tensor(dataset[outputs].values).flatten() outputs[:5]
Выход:
tensor([1, 0, 1, 0, 0])
Давайте теперь построим форму наших категориальных данных, числовых данных и соответствующих выходных данных:
print(categorical_data.shape) print(numerical_data.shape) print(outputs.shape)
Выход:
torch.Size([10000, 4]) torch.Size([10000, 6]) torch.Size([10000])
Есть один очень важный шаг, прежде чем мы сможем обучить нашу модель. Мы преобразовали наши категориальные столбцы в числовые, где уникальное значение представлено одним целым числом. Например, в столбце География
мы увидели, что Франция представлена 0, а Германия-1. Мы можем использовать эти значения для обучения нашей модели. Однако лучшим способом является представление значений в категориальном столбце в виде N-мерного вектора, а не одного целого числа. Вектор способен захватывать больше информации и может находить отношения между различными категориальными значениями более подходящим способом. Поэтому мы будем представлять значения в категориальных столбцах в виде N-мерных векторов. Этот процесс называется внедрением.
Нам нужно определить размер вложения (векторные размеры) для всех категориальных столбцов. Нет жесткого и быстрого правила относительно количества измерений. Хорошее эмпирическое правило для определения размера вложения для столбца состоит в том, чтобы разделить количество уникальных значений в столбце на 2 (но не более 50). Например, для столбца Geography
число уникальных значений равно 3. Соответствующий размер вложения для столбца Geography
будет равен.5 (округление).
Следующий сценарий создает кортеж, содержащий количество уникальных значений и размеры измерений для всех категориальных столбцов:
categorical_column_sizes = [len(dataset[column].cat.categories) for column in categorical_columns] categorical_embedding_sizes = [(col_size, min(50, (col_size+1)//2)) for col_size in categorical_column_sizes] print(categorical_embedding_sizes)
Выход:
[(3, 2), (2, 1), (2, 1), (2, 1)]
Модель контролируемого глубокого обучения, подобная той, которую мы разрабатываем в этой статье, обучается с использованием обучающих данных, а производительность модели оценивается на основе тестового набора данных. Поэтому нам нужно разделить наш набор данных на обучающие и тестовые наборы, как показано в следующем сценарии:
total_records = 10000 test_records = int(total_records * .2) categorical_train_data = categorical_data[:total_records-test_records] categorical_test_data = categorical_data[total_records-test_records:total_records] numerical_train_data = numerical_data[:total_records-test_records] numerical_test_data = numerical_data[total_records-test_records:total_records] train_outputs = outputs[:total_records-test_records] test_outputs = outputs[total_records-test_records:total_records]
У нас есть 10 тысяч записей в нашем наборе данных, из которых 80% записей, то есть 8000 записей, будут использоваться для обучения модели, а остальные 20% записей будут использоваться для оценки производительности нашей модели. Обратите внимание, что в приведенном выше сценарии категориальные и числовые данные, а также выходные данные были разделены на обучающие и тестовые наборы.
Чтобы убедиться, что мы правильно разделили данные на обучающие и тестовые наборы, давайте распечатаем длины обучающих и тестовых записей:
print(len(categorical_train_data)) print(len(numerical_train_data)) print(len(train_outputs)) print(len(categorical_test_data)) print(len(numerical_test_data)) print(len(test_outputs))
Выход:
8000 8000 8000 2000 2000 2000
Создание модели для прогнозирования
Мы разделили данные на обучающие и тестовые наборы, теперь пришло время определить нашу модель обучения. Для этого мы можем определить класс с именем Model
, который будет использоваться для обучения модели. Посмотрите на следующий сценарий:
class Model(nn.Module): def __init__(self, embedding_size, num_numerical_cols, output_size, layers, p=0.4): super().__init__() self.all_embeddings = nn.ModuleList([nn.Embedding(ni, nf) for ni, nf in embedding_size]) self.embedding_dropout = nn.Dropout(p) self.batch_norm_num = nn.BatchNorm1d(num_numerical_cols) all_layers = [] num_categorical_cols = sum((nf for ni, nf in embedding_size)) input_size = num_categorical_cols + num_numerical_cols for i in layers: all_layers.append(nn.Linear(input_size, i)) all_layers.append(nn.ReLU(inplace=True)) all_layers.append(nn.BatchNorm1d(i)) all_layers.append(nn.Dropout(p)) input_size = i all_layers.append(nn.Linear(layers[-1], output_size)) self.layers = nn.Sequential(*all_layers) def forward(self, x_categorical, x_numerical): embeddings = [] for i,e in enumerate(self.all_embeddings): embeddings.append(e(x_categorical[:,i])) x = torch.cat(embeddings, 1) x = self.embedding_dropout(x) x_numerical = self.batch_norm_num(x_numerical) x = torch.cat([x, x_numerical], 1) x = self.layers(x) return x
Если вы никогда раньше не работали с Pitch, приведенный выше код может показаться устрашающим, однако я постараюсь разбить его для вас.
В первой строке мы объявляем класс Model
, который наследуется от класса Module
от модуля nn
PyTorch. В конструкторе класса (метод __init__ ()
) передаются следующие параметры:
embedding_size
: Содержит размер вложения для категориальных столбцовnum_numerical_cols
: Хранит общее количество числовых столбцовoutput_size
: Размер выходного слоя или количество возможных выходов.layers
: Список, содержащий количество нейронов для всех слоев.p
: Выпадение со значением по умолчанию 0,5
Внутри конструктора инициализируется несколько переменных. Во-первых, переменная all_embeddings
содержит список объектов Module List
для всех категориальных столбцов. Параметр embedding_dropout
сохраняет значение выпадения для всех слоев. Наконец, batch_norm_num
хранит список объектов BatchNorm1d
для всех числовых столбцов.
Затем, чтобы найти размер входного слоя, количество категориальных и числовых столбцов складывается вместе и сохраняется в переменной input_size
. После этого выполняется итерация цикла for
, и соответствующие слои добавляются в список all_layers
. Добавленные слои являются:
Linear
: Используется для вычисления точечного произведения между входными данными и весовыми матрицамиReLU
: Который применяется в качестве функции активацииBatchNorm1d
: Используется для применения пакетной нормализации к числовым столбцамОтсев
: Используется для предотвращения переобучения
После цикла for
выходной слой добавляется в список слоев. Поскольку мы хотим, чтобы все слои в нейронных сетях выполнялись последовательно, список слоев передается классу nn.Sequential
.
Далее в методе forward
в качестве входных данных передаются как категориальные, так и числовые столбцы. Встраивание категориальных столбцов происходит в следующих строках.
embeddings = [] for i, e in enumerate(self.all_embeddings): embeddings.append(e(x_categorical[:,i])) x = torch.cat(embeddings, 1) x = self.embedding_dropout(x)
Пакетная нормализация числовых столбцов применяется со следующим сценарием:
x_numerical = self.batch_norm_num(x_numerical)
Наконец, встроенные категориальные столбцы x
и числовые столбцы x_numerical
объединяются вместе и передаются последовательным слоям .
Обучение модели
Чтобы обучить модель, сначала мы должны создать объект класса Model
, который мы определили в предыдущем разделе.
model = Model(categorical_embedding_sizes, numerical_data.shape[1], 2, [200,100,50], p=0.4)
Вы можете видеть, что мы передаем размер вложения категориальных столбцов, количество числовых столбцов, размер вывода (в нашем случае 2) и нейроны в скрытых слоях. Вы можете видеть, что у нас есть три скрытых слоя с 200, 100 и 50 нейронами соответственно. Вы можете выбрать любой другой размер, если хотите.
Давайте распечатаем нашу модель и посмотрим как она выглядит:
print(model)
Выход:
Model( (all_embeddings): ModuleList( (0): Embedding(3, 2) (1): Embedding(2, 1) (2): Embedding(2, 1) (3): Embedding(2, 1) ) (embedding_dropout): Dropout(p=0.4) (batch_norm_num): BatchNorm1d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (layers): Sequential( (0): Linear(in_features=11, out_features=200, bias=True) (1): ReLU(inplace) (2): BatchNorm1d(200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (3): Dropout(p=0.4) (4): Linear(in_features=200, out_features=100, bias=True) (5): ReLU(inplace) (6): BatchNorm1d(100, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (7): Dropout(p=0.4) (8): Linear(in_features=100, out_features=50, bias=True) (9): ReLU(inplace) (10): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (11): Dropout(p=0.4) (12): Linear(in_features=50, out_features=2, bias=True) ) )
Вы можете видеть, что в первом линейном слое значение переменной in_features
равно 11, так как у нас есть 6 числовых столбцов, а сумма вложенных измерений для категориальных столбцов равна 5, следовательно. Аналогично, в последнем слое out_features
имеет значение 2, так как у нас есть только 2 возможных выхода.
Прежде чем мы действительно сможем обучить нашу модель, нам нужно определить функцию потерь и оптимизатор, который будет использоваться для обучения модели. Поскольку мы решаем задачу классификации, мы будем использовать кросс-энтропийные потери . Для функции оптимизатора мы будем использовать adam optimizer .
Следующий сценарий определяет функцию потерь и оптимизатор:
loss_function = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
Теперь у нас есть все, что нужно для обучения модели. Следующий сценарий обучает модель:
epochs = 300 aggregated_losses = [] for i in range(epochs): i += 1 y_pred = model(categorical_train_data, numerical_train_data) single_loss = loss_function(y_pred, train_outputs) aggregated_losses.append(single_loss) if i%25 == 1: print(f'epoch: {i:3} loss: {single_loss.item():10.8f}') optimizer.zero_grad() single_loss.backward() optimizer.step() print(f'epoch: {i:3} loss: {single_loss.item():10.10f}')
Число эпох установлено равным 300, что означает, что для обучения модели полный набор данных будет использоваться 300 раз. Цикл for
выполняется 300 раз, и во время каждой итерации потери вычисляются с помощью функции потерь. Потери во время каждой итерации добавляются в список aggregated_loss
. Для обновления весов вызывается функция backward()
объекта single_loss
. Наконец, метод step()
функции optimizer
обновляет градиент. Потеря печатается через каждые 25 эпох.
Вывод приведенного выше скрипта выглядит следующим образом:
epoch: 1 loss: 0.71847951 epoch: 26 loss: 0.57145703 epoch: 51 loss: 0.48110831 epoch: 76 loss: 0.42529839 epoch: 101 loss: 0.39972275 epoch: 126 loss: 0.37837571 epoch: 151 loss: 0.37133673 epoch: 176 loss: 0.36773482 epoch: 201 loss: 0.36305946 epoch: 226 loss: 0.36079505 epoch: 251 loss: 0.35350436 epoch: 276 loss: 0.35540250 epoch: 300 loss: 0.3465710580
Следующий сценарий строит потери против эпох:
plt.plot(range(epochs), aggregated_losses) plt.ylabel('Loss') plt.xlabel('epoch');
Выход:
Вывод показывает, что первоначально потери быстро уменьшаются. Примерно после 250-й эпохи потери уменьшаются очень незначительно.
Делать Прогнозы
Последний шаг-сделать прогнозы по тестовым данным. Для этого нам просто нужно передать categorical_test_data
и numerical_test_data
классу model
. Затем возвращенные значения можно сравнить с фактическими выходными значениями теста. Следующий сценарий делает прогнозы для тестового класса и выводит кросс-энтропийные потери для тестовых данных.
with torch.no_grad(): y_val = model(categorical_test_data, numerical_test_data) loss = loss_function(y_val, test_outputs) print(f'Loss: {loss:.8f}')
Выход:
Loss: 0.36855841
Потеря на тестовом наборе составляет 0,3685, что немного больше, чем 0,3465, достигнутое на тренировочном наборе, что показывает, что наша модель немного переоснащена.
Важно отметить, что поскольку мы указали, что наш выходной слой будет содержать 2 нейрона, каждое предсказание будет содержать 2 значения. Например, первые 5 прогнозируемых значений выглядят следующим образом:
print(y_val[:5])
Выход:
tensor([[ 1.2045, -1.3857], [ 1.3911, -1.5957], [ 1.2781, -1.3598], [ 0.6261, -0.5429], [ 2.5430, -1.9991]])
Идея таких прогнозов заключается в том, что если фактический выход равен 0, то значение индекса 0 должно быть выше значения индекса 1, и наоборот. Мы можем получить индекс самого большого значения в списке с помощью следующего скрипта:
y_val = np.argmax(y_val, axis=1)
Выход:
Давайте теперь снова выведем первые пять значений для списка y_val
:
print(y_val[:5])
Выход:
tensor([0, 0, 0, 0, 0])
Поскольку в списке первоначально предсказанных выходов для первых пяти записей значения нулевых индексов больше значений первых индексов, мы можем видеть 0 в первых пяти строках обработанных выходов.
Наконец, мы можем использовать классы confusion_matrix
, accuracy_score
и classification_report
из модуля sklearn.metrics
для поиска значений точности , точности и отзыва для тестового набора вместе с матрицей путаницы.
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score print(confusion_matrix(test_outputs,y_val)) print(classification_report(test_outputs,y_val)) print(accuracy_score(test_outputs, y_val))
Выход:
[[1527 83] [ 224 166]] precision recall f1-score support 0 0.87 0.95 0.91 1610 1 0.67 0.43 0.52 390 micro avg 0.85 0.85 0.85 2000 macro avg 0.77 0.69 0.71 2000 weighted avg 0.83 0.85 0.83 2000 0.8465
Результат показывает, что наша модель достигает точности 84,65%, что довольно впечатляет, учитывая тот факт, что мы случайным образом выбрали все параметры для нашей нейросетевой модели. Я бы посоветовал вам попробовать изменить параметры модели, то есть обучить/протестировать расщепления, количество и размер скрытых слоев и т. Д. чтобы увидеть, сможете ли вы получить лучшие результаты.
Вывод
Pitch-это широко используемая библиотека глубокого обучения, разработанная Facebook, которая может быть использована для различных задач, таких как классификация, регрессия и кластеризация. В этой статье объясняется, как использовать библиотеку Python для классификации табличных данных.