Наряду с решенным набором данных Kaggle с SVM

СОДЕРЖАНИЕ

В этом посте мы рассмотрим:

(i) Роль опорных векторов в SVM

(ii) Функция затрат для SVM

(iii) SVM как классификатор большой маржи

(iv) Нелинейные границы принятия решений через SVM с помощью ядер

(v) Обнаружение набора данных Kaggle для мошеннических транзакций по кредитной карте с использованием SVM.

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

Машины опорных векторов (SVM)

SVM - это контролируемый метод машинного обучения, который решает проблемы как регрессии, так и классификации. Тем не менее, он в основном используется в задачах классификации, где он строит гиперплоскости в n-пространственных измерениях. N-мерное пространство признаков имеет гиперплоскость n-1 размеров. Например. В наборе данных с двумя признаками (двумерное пространство признаков) гиперплоскость, построенная с помощью SVM, представляет собой кривую (линия, круг и т. Д.). Если мы решаем задачу классификации по 2 классам, то задача классификатора SVM следующая. найти гиперплоскость, которая максимизирует разницу между двумя классами. Прежде чем мы рассмотрим, как работают SVM, давайте разберемся, откуда взялось название Support Vector Machine.

Что такое опорный вектор?

Мы знаем, что классификатор SVM строит гиперплоскости для классификации. Но как классификатор SVM построить гиперплоскость? Давайте разовьем интуицию, рассмотрев всего 2 занятия. Мы знаем, что гиперплоскость должна проходить где-то посередине двух классов. Хорошее разделение между этими классами достигается за счет гиперплоскости, которая имеет наибольшее расстояние до ближайших точек обучающих данных из обоих классов. На рисунке 2 пунктирные линии, обозначающие крайние точки каждого класса, составляют опорные векторы для каждого класса. Эти опорные векторы помогают найти гиперплоскость, которая максимизирует расстояние (запас) гиперплоскости от каждого из 2 классов с помощью их опорных векторов.

Работа SVM

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

Функция стоимости

Вспомним функцию стоимости бинарной кроссэнтропии, используемую для бинарной классификации в логистической регрессии. Здесь, для упрощения, мы проигнорируем термин смещения, поэтому окончательный прогноз, который мы делаем для i-го обучающего примера из общего количества обучающих примеров 'm' с помощью логистической регрессии, будет представлен как h (x (i )) = сигмовидная (W * x (i))

Эту функцию стоимости можно разделить на 2 части: когда y (i) = 1, член (1 - y (i)) * log (1 - h (x (i))) становится 0, а когда y (i) = 0 , член y (i) * log (h (x (i))) становится 0. Соответствующие графики для этих уравнений (Стоимость против W * x) (исключая член регуляризации, поскольку он является общим для обоих):

SVM использует небольшую модификацию этой функции стоимости, которая обеспечивает вычислительные преимущества перед логистической регрессией. Для случая y = 1 мы видим, что функция стоимости имеет все значения, близкие к 0, когда W * x ›= 1 и когда W * x‹ 1, значения функции -log (h (x)) аппроксимируются прямая линия путем вычисления производной функции стоимости, когда W * x = 0. Аналогично для случая y = 0 мы видим, что функция стоимости имеет все свои значения, близкие к 0, когда W * x ‹= -1 и когда W * x ›1, значения -log (1 - h (x)) аппроксимируются прямой линией путем вычисления производной функции стоимости, когда W * x = 0.

Теперь, когда мы больше не используем логарифмическую функцию стоимости, давайте переименуем логарифмическую часть в функции стоимости логистической регрессии. Заменим -log (h (x)) на cost1 (h (x)) и -log (1 - h (x)) на cost0 (h (x)) . Здесь мы игнорируем константу (1 / m), поскольку она не влияет на нашу цель минимизации и помогает нам упростить наши вычисления. Итак, окончательная функция стоимости для машины опорных векторов выглядит так:

Это приводит к следующему математическому уравнению для функции стоимости:

В отличие от логистической регрессии, которая выводит значения вероятности, SVM выводят 0/1. Когда h (x) ›= 1, SVM выводит 1, а когда h (x)‹ = -1, SVM выводит 0. В логистической регрессии мы видели, что когда h (x) ›0, выходом была вероятность› 0,5, который был округлен до 1, а когда h (x) дополнительным запасом безопасности. фактор, который позволяет SVM делать более надежные прогнозы, чем логистическая регрессия.

Давайте теперь немного повторно параметризуем функцию стоимости. В настоящее время наша функция стоимости имеет вид A + λ * B, где A - функция стоимости, а B - член регуляризации. Преобразуем его в форму C * A + B, где C играет роль, аналогичную 1 / λ.

SVM как классификатор большой маржи

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

Мы повторно параметризовали функцию стоимости SVM на C * A + B, где A - это потери, связанные с выходными данными SVM (компонент стоимости), B - член регуляризации (компонент регуляризации), а C играет роль, аналогичную 1 / λ. Когда мы выбираем C как очень большой, наша модель будет подвержена переобучению. Чтобы противостоять этому, мы хотели бы, чтобы A было близко к нулю, иначе возникнут огромные затраты, что нежелательно. Поскольку значение A прямо пропорционально параметру W (представленному на рисунках тэтой), это означает, что сами параметры будут иметь очень маленькие значения. Таким образом, в случае большого C цель оптимизации - просто найти минимальное значение параметров обучения, представленных в B. Формально определяя, цель минимизации в этом случае:

При реализации SVM используется векторизация и вычисляется скалярное произведение вектора W («тета на рисунке») и вектора признаков (X). Зная умножение матриц, мы знаем, что когда вычисляется скалярное произведение двух векторов (скажем, u и v), мы получаем проекцию вектора u на вектор v. Таким же образом, когда вычисляется скалярное произведение W и X, мы получаем проекцию вектора X на W, а длина проекции (P) равна

где || thetha || является L2-нормой тэты. Это уравнение можно представить в виде:

Итак, цель минимизации можно перефразировать следующим образом:

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

Рассмотрим следующую задачу двоичной классификации, где «X» представляет признак x1, а «O» представляет признак x2. Из нашей текущей цели оптимизации мы знаем, что SVM минимизирует функцию затрат только тогда, когда p. || theta || ‹= -1 для y = 0 (x1) и p. || theta || ›= 1 для y = 1 (x2), т.е. угол между проекцией обучающего примера и вектором параметров находится в диапазоне 900–1800 и 2700–3600 соответственно.

На изображении ниже рассмотрите границу решения на левом изображении (зеленом). Вектор параметров (тета-вектор) перпендикулярен ему, поскольку область справа от вектора параметров имеет углы от 900 до 1800, а область слева от границы принятия решения имеет углы от 2700 до 3600. Для этой границы решения мы видим, что длина проекций обучающих примеров (представленных красным и розовым) довольно мала. Чтобы удовлетворить условиям p. || theta || ‹= -1 для y = 0 (x1) и p. || theta || ›= 1 (x2) в этом случае тета должна иметь большое значение. Из-за этого значение функции стоимости не минимизируется, и, следовательно, граница принятия решения, представленная зеленым на левом изображении, не будет выбрана SVM.

Теперь рассмотрим границу принятия решения (зеленую) для изображения ниже справа. Для тех же обучающих примеров мы видим, что их проекция на вектор параметров больше по сравнению с предыдущей границей решения. Теперь, чтобы удовлетворить условиям p. || theta || ‹= -1 для y = 0 (x1) и p. || theta || ›= 1 (x2), у нас уже есть большое значение вектора проекции« p ». Это означает, что будет достаточно небольшого значения тета, что, в свою очередь, также минимизирует функцию стоимости. Следовательно, граница решения, представленная на изображении справа, скорее всего, будет выбрана SVM для задачи двоичной классификации, и, сравнив обе границы решения, мы можем ясно увидеть, что классификатор, выбранный SVM, действительно является классификатором с большим запасом.

Напомним, что сделанный выше вывод подтверждается, когда параметр C в уравнении SVM C * A + B был очень большим. Мы можем получить аналогичные результаты, когда значение C невелико, и поэтому мы обобщаем это утверждение. Я призываю читателя задуматься над этим. Это поможет еще больше прояснить математику, лежащую в основе SVM.

SVM для нелинейных границ принятия решений

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

В линейной регрессии для обучающих данных с входными функциями ’n’ мы представляем выходные данные следующим образом:

у = W1x1 + W2x2 + W3x3 + ………. + Wnxn.

Результат, который мы получаем для обучающих примеров «m», представляет собой прямую линию. Итак, как мы можем сделать это, чтобы получить нелинейную границу принятия решения? Что ж, мы знаем, что многочлены степени ›1 дают нелинейные результаты. Но использование этих многочленов в качестве входных функций имеет следующие проблемы:

(i) Для такого небольшого количества функций, как 5, существует множество возможностей для выбора функций. Примерное представление результатов может быть следующим: y = W1x1² + W2x2³x3² + W3x1²x4²x5 + W4x2x4³ + ……… (может быть множество возможностей). Помните, что многочлен 5-й степени не обязательно должен обладать всеми характеристиками 5-й степени.

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

(iii) Кроме того, вычисление этих сложных функций требует больших вычислительных ресурсов и, следовательно, нежелательно.

Методы ядра

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

Здесь, хотя мы ограничиваем использование ядер SVM, важно отметить одну важную вещь: любой алгоритм машинного обучения, который можно выразить с помощью точечных произведений, можно заменить ядрами. Затем мы можем использовать любой из этих алгоритмов машинного обучения с ядрами, которые дают быстрые и лучшие результаты. Хотя существуют разные типы методов ядра, я буду использовать ядро ​​Гаусса для дальнейшей иллюстрации.

Построение нелинейных границ принятия решений

Если ядра не выполняют таких сложных вычислений, то как они генерируют такие хорошие нелинейные границы принятия решений? Некоторые ориентиры определены для обучающих примеров, и схожесть каждого из примеров вычисляется с каждым определенным ориентиром с использованием функции подобия (ядра). Ядро Гаусса или функция подобия Гаусса для обучающего примера xi и ориентир lj представлены как exp (- || xi - lj || 2 / 2σ2). Отсюда мы видим, что для обучающего примера xi рядом с ориентиром его значение функции fi близко к 1, а для обучающего примера xi довольно далеко от ориентира, его значение характеристики близко к 0, что кажется хорошим показателем сходства.

Вычисленные значения подобия с использованием ядра Гаусса рассматриваются как новые значения функций соответствующих обучающих примеров, которые затем могут быть присоединены с их весовыми параметрами (W / theta) для вычисления окончательного выходного класса. Ранее в этом посте мы видели, что цель минимизации подчинялась условиям, когда скалярное произведение вектора весов и вектора входных признаков было либо ›= 1, либо‹ = -1. После вычисления новых значений характеристик с использованием ядер условия цели оптимизации немного меняются. Хотя значения неравенства остаются прежними, скалярное произведение теперь вычисляется между вектором весов и вектором нового признака, вычисленным с использованием ядра Гаусса. Чтобы уточнить, хотя результат метода ядра является скалярным значением, это скалярное значение вычисляется относительно одного ориентира. Для L ориентиров вычисляются L-значения, которые затем формируют вектор признаков для данного обучающего примера.

Рассмотрим набор обучающих данных (с двумя функциями только для демонстрационных целей) с двумя выходными классами, которые не имеют линейной границы решения. Давайте посмотрим, как определение нескольких ориентиров (скажем, 3) на обучающем наборе помогает в решении нелинейных границ принятия решений. На рисунке ниже мы видим, что для учебного примера X, выделенного розовым цветом, он довольно близко расположен к ориентиру L1 по сравнению с ориентирами L2 и L3. Вычисляя подобие с использованием ядра Гаусса для этого примера, мы получаем значение признака f1, соответствующее L1, как можно ближе к 1, а значения, соответствующие L2 и L3 (f2 и f3) как можно ближе к 0. В соответствии с приведенным выше уравнением мы прогнозируем единицу. когда theta * f ›= 1. Теперь, если значения theta, соответствующие этим характеристикам, равны 2, 0,5 и 1, тогда 2 * 1 + 0,5 * 0 + 1 * 0 = 2, т.е.› = 1. Выполнение того же шага для несколько обучающих примеров дают нам правильную нелинейную границу решения с высокой точностью.

Выбор ориентиров

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

После выбора этих ориентиров и расчета этих новых векторов признаков конечная цель оптимизации изменяется на:

где f (i) представляет новые векторы признаков, вычисленные с использованием ядра Гаусса. Здесь следует отметить, что количество векторов признаков (n) будет равно количеству обучающих примеров (m), поскольку каждый обучающий пример является ориентиром.

Расчет весовых параметров

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

W = W - альфа * subgradient_wrt_W (J), где «альфа» - скорость обучения.

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

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

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

До сих пор мы довольно много узнали о SVM. Мы начали с роли опорных векторов, затем поняли, как функция стоимости SVM неявно способствует глубокому классификатору большой маржи с последующим использованием уловки ядра для вычисления нелинейных границ решения с простотой вычислений с помощью различных иллюстраций, чтобы упростить задачу. понимать. В конце концов, мы узнали, как обычный (простой) градиентный спуск не работает для расчета весовых параметров, поэтому появилась необходимость в использовании субградиентного спуска. После того, как мы узнали это, пришло время переключить наше внимание на набор данных Kaggle о транзакциях по кредитным картам, чтобы объединить наши концепции и увидеть SVM в действии.

Постановка задачи

В этом разделе мы будем использовать SVM для определения мошеннических транзакций по кредитным картам. Набор данных для этой задачи можно найти здесь. Здесь следует отметить, что характеристики этого набора данных уже вычислены в результате преобразования PCA (анализ основных компонентов, который мы увидим в более поздней публикации). Это помогает двумя способами:

(i) Сохраняется конфиденциальность пользовательских данных.

(ii) Объекты в наборе данных независимы друг от друга из-за преобразования PCA.

Давайте начнем с загрузки набора данных в память в виде фрейма данных.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import preprocessing, svm
from sklearn.metrics import confusion_matrix
import os
for dirname, _, filenames in os.walk(‘/kaggle/input’):
  for filename in filenames:
    print(os.path.join(dirname, filename))

df = pd.read_csv(“/kaggle/input/creditcardfraud/creditcard.csv”)
df.head()

Набор данных состоит из 31 столбца / объекта, из которых 28 были вычислены с помощью преобразования PCA, а другие объекты являются только числовыми. Давайте теперь посмотрим, как мошеннические и не мошеннические транзакции распределяются в наборе данных.

print(df[‘Class’].value_counts())

Имеется 492 мошеннических (1) транзакций по сравнению с 284315 не-мошенническими (0) транзакциями, что сильно искажено. Ясно, что нам нужно пересчитать наши данные, иначе мы сможем достичь высокой точности, просто предсказав каждую транзакцию как 0 (не мошенническую).

print(“Accuracy by predicting all transactions as non-fraudulent: “ + str((284315 / (284315 + 492)) * 100) + “%”)

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

df_fraud = df[df[‘Class’] == 1]
plt.figure(figsize=(15, 12))
plt.scatter(df_fraud[‘Time’], df_fraud[‘Amount’])
plt.title(“Fraudulent transactions”)
plt.xlabel(“Time”)
plt.ylabel(“Amount”)
plt.show()

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

df_huge_fraud_amounts = df_fraud[df_fraud[‘Amount’] > 1000]
print(“Number of fraudulent transactions over the amount of 1000 are: “ + str((df_huge_fraud_amounts.shape[0])))

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

import seaborn as sns
plt.figure(figsize = (15, 12))
df_correlation = df.corr()
sns.heatmap(df_correlation)
plt.title(“Heatmap representing correlations”)
plt.show()

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

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

df_train = df[:200000]
df_train_fraud = df_train[df_train[‘Class’] == 1]
df_train_not_fraud = df_train[df_train[‘Class’] == 0]
print(df_train_fraud.shape[0]) # 385

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

df_sample = df_train_not_fraud.sample(400)
df_train_final = df_train_fraud.append(df_sample)
df_train_final = df_train_final.sample(frac = 1).reset_index(drop = True)
df_train_final.head()

Теперь мы видим, что в столбце «Класс» есть как нули, так и единицы. Мы взяли первые 200 000 выборок из набора данных и случайным образом выбрали 400 (около 385) не мошеннических транзакций из общего числа 284 315 не мошеннических транзакций. Таким образом, мы успешно реализовали недостаточную выборку, и наш окончательный обучающий набор состоит из 785 обучающих примеров. Недостаточная выборка может привести к потере некоторых важных функций данных. Но прежде всего давайте посмотрим, какие результаты мы получаем, применяя классификатор SVM. Теперь давайте разделим данные на обучающие и тестовые наборы.

X_train = df_train_final.drop([‘Time’, ‘Class’],axis=1)
y_train = df_train_final[‘Class’]
X_train = np.asarray(X_train)
y_train = np.asarray(y_train)
df_test = df[200000:]
X_test = df_test.drop([‘Time’, ‘Class’],axis=1)
y_test = df_test[‘Class’]
X_test = np.asarray(X_test)
y_test = np.asarray(y_test)
print(df_test[‘Class’].value_counts())

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

classifier = svm.SVC(kernel=’linear’)
classifier.fit(X_train, y_train)

predictions = classifier.predict(X_test)

Теперь мы применили классификатор SVM к набору обучающих данных и сохранили результаты прогнозов в наборе тестовых данных в переменной «прогнозы». Чтобы оценить производительность модели, построим матрицу неточностей и определим следующее:

(i) Истинные положительные результаты: исходный выходной класс был положительным примером (здесь немошенническая транзакция), а прогнозируемый выходной класс также был положительным примером (здесь немошенническая транзакция).

(ii) Ложные срабатывания: исходный выходной класс был положительным примером (здесь немошенническая транзакция), но прогнозируемый выходной класс был Отрицательный пример (здесь мошенническая транзакция).

(iii) Ложноотрицательные: исходный выходной класс был отрицательным примером (здесь мошенническая транзакция), но прогнозируемый выходной класс был положительным примером ( здесь немошенническая транзакция).

(iv) Истинно отрицательные: исходный выходной класс был отрицательным примером (здесь мошенническая транзакция), а прогнозируемый выходной класс также был отрицательным примером. (здесь мошенническая транзакция).

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

import itertools
classes = np.array([‘0’,’1'])
def plot_confusion_matrix(cm, classes,title=’Confusion matrix’, cmap=plt.cm.Blues):
  plt.imshow(cm, interpolation=’nearest’, cmap=cmap)
  plt.title(title)
  plt.colorbar()
  tick_marks = np.arange(len(classes))
  plt.xticks(tick_marks, classes, rotation=45)
  plt.yticks(tick_marks, classes)
  fmt = ‘d’
  thresh = cm.max() / 2.
  for i, j in itertools.product(range(cm.shape[0]),    range(cm.shape[1])):
    plt.text(j, i, format(cm[i, j], fmt),
    horizontalalignment=”center”,
    color=”white” if cm[i, j] > thresh else “black”)
plt.tight_layout()
plt.ylabel(‘True label’)
plt.xlabel(‘Predicted label’)
cm = confusion_matrix(y_test, predictions)
plot_confusion_matrix(cm,classes)

Матрица путаницы имеет

(i) 81746 истинных положительных результатов

(ii) 3224 ложных срабатывания

(iii) 11 ложноотрицательных результатов

(iv) 96 истинных негативов

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

print(‘Total fraudulent transactions detected: ‘ + str(cm[1][1]) + ‘ / ‘ + str(cm[1][1]+cm[1][0]))
print(‘Total non-fraudulent transactions detected: ‘ + str(cm[0][0]) + ‘ / ‘ + str(cm[0][1]+cm[0][0]))
print(‘Probability to detect a fraudulent transaction: ‘ + str(cm[1][1]/(cm[1][1]+cm[1][0])))
print(‘Probability to detect a non-fraudulent transaction: ‘ + str(cm[0][0]/(cm[0][1]+cm[0][0])))
print(“Accuracy of the SVM model : “+str(100*(cm[0][0]+cm[1][1]) / (sum(cm[0]) + sum(cm[1]))) + “%”)

Полный код этого поста можно найти здесь.

Наша основная задача заключалась в том, чтобы зафиксировать как можно больше мошеннических транзакций, и мы проделали отличную работу, обнаружив 96/107 мошеннических транзакций, учитывая, что у нас было всего около 800 мошеннических примеров во всем наборе данных.

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