Реализация SVM и Kernel SVM с помощью Python Scikit-Learn

Реализация SVM и Kernel SVM с помощью Python Scikit-Learn

Введение

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

Если вы хотите прочитать все руководства или посмотреть, какие из них вас интересуют больше всего, ниже приведена таблица тем, затронутых в каждом руководстве:

1. Внедрение SVM и Kernel SVM с помощью Python Scikit-Learn

  • Пример использования: забудьте о банкнотах
  • Предыстория SVM
  • Простая (линейная) модель SVM
    • О наборе данных
    • Импорт набора данных
    • Изучение набора данных
  • Внедрение SVM с помощью Scikit-Learn
    • Разделение данных на обучающие/тестовые наборы
    • Обучение модели
    • Делать прогнозы
    • Оценка модели
    • Интерпретация результатов

2. Понимание гиперпараметров SVM (скоро будет!)

  • Гиперпараметр C
  • Гамма-гиперпараметр

3. Реализация других разновидностей SVM с помощью Python Scikit-Learn (скоро будет!)

  • Общая идея SVM (резюме)
  • Ядро (трюк) SVM
  • Внедрение SVM с нелинейным ядром с помощью Scikit-Learn
  • Импорт библиотек
    • Импорт набора данных
    • Разделение данных на функции (X) и цель (y)
    • Разделение данных на обучающие/тестовые наборы
    • Обучение алгоритму
  • Полиномиальное ядро
    • Делать прогнозы
    • Оценка алгоритма
  • Гауссово ядро
    • Прогноз и оценка
  • Сигмовидное ядро
    • Прогноз и оценка
  • Сравнение производительности нелинейного ядра

Вариант использования: поддельные банкноты

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

Но что происходит, когда нет человека, который просматривал бы каждую заметку? Есть ли способ автоматически узнать, являются ли банкноты поддельными или настоящими?

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

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

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

Предыстория SVM

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

Реализация SVM и SVM ядра с помощью Python Scikit-Learn PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

На изображении выше у нас есть линия посередине, некоторые точки которой находятся слева, а другие — справа от этой линии. Обратите внимание, что обе группы точек идеально разделены, между ними нет точек или даже рядом с линией. Кажется, что между сходными точками и линией, которая их разделяет, есть зазор, этот зазор называется граница разделения. Функция поля разделения состоит в том, чтобы увеличить расстояние между похожими точками и линией, которая их разделяет. SVM делает это, используя несколько точек и вычисляя их перпендикулярные векторы, чтобы поддержать решение о границе линии. Это опорные векторы которые являются частью имени алгоритма. Мы узнаем о них больше позже. А прямая линия, которую мы видим посередине, находится методами, которые максимизировать это пространство между линией и точками или максимальное расстояние между точками. Эти методы происходят из области Теория оптимизации.

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

Но что произойдет, если нет способа разделить данные с помощью одной прямой? Если есть грязные неуместные точки или нужна кривая?

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

Любопытно, что только в последние годы SVM получили широкое распространение, в основном из-за их способности достигать иногда более 90% правильных ответов или точность, для сложных задач.

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

В этой статье мы увидим, что такое алгоритмы машины опорных векторов, краткую теорию машины опорных векторов и их реализацию в библиотеке Python Scikit-Learn. Затем мы перейдем к другой концепции SVM, известной как Ядро SVMили Трюк с ядром, а также будет реализовывать его с помощью Scikit-Learn.

Простая (линейная) модель SVM

О наборе данных

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

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

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

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

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

Импорт набора данных

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

Примечание: Вы можете скачать набор данных здесь.

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

Обратите внимание, что данные сохраняются в txt (текстовый) формат файла, разделенный запятыми, и без заголовка. Мы можем реконструировать ее как таблицу, прочитав ее как csv, указав separator через запятую и добавляя имена столбцов с names аргумент.

Давайте выполним эти три шага одновременно, а затем посмотрим на первые пять строк данных:

import pandas as pd data_link = "https://archive.ics.uci.edu/ml/machine-learning-databases/00267/data_banknote_authentication.txt"
col_names = ["variance", "skewness", "curtosis", "entropy", "class"] bankdata = pd.read_csv(data_link, names=col_names, sep=",", header=None)
bankdata.head()

Это приводит к:

	variance skewness curtosis entropy class
0 3.62160 8.6661 -2.8073 -0.44699 0
1 4.54590 8.1674 -2.4586 -1.46210 0
2 3.86600 -2.6383 1.9242 0.10645 0
3 3.45660 9.5228 -4.0112 -3.59440 0
4 0.32924 -4.4552 4.5718 -0.98880 0

Примечание: Вы также можете сохранить данные локально и заменить data_link для data_pathи укажите путь к вашему локальному файлу.

Мы видим, что в нашем наборе данных есть пять столбцов, а именно: variance, skewness, curtosis, entropyи class. В пяти строках первые четыре столбца заполнены числами, такими как 3.62160, 8.6661, -2.8073 или (CIJ) значения, а последний class первые пять строк столбца заполнены нулями или дискретный значения.

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

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

  • skewness изображения, преобразованного вейвлетом. Асимметрия — это непрерывное значение, указывающее на асимметрию распределения. Если слева от среднего больше значений, распределение равно отрицательно перекошенный, если справа от среднего больше значений, распределение равно положительно перекошенный, а если среднее значение, мода и медиана совпадают, распределение симметричный. Чем более симметрично распределение, тем ближе оно к нормальному распределению, а его значения также более хорошо распределены. В данном контексте это асимметрия коэффициентов, полученных в результате вейвлет-преобразования. Чем более симметрично, тем ближе коэффициенты, которые мыvariance, skewness, curtosis, entropyre к переводу фактического изображения.

Реализация SVM и SVM ядра с помощью Python Scikit-Learn PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

  • curtosis (или эксцесс) вейвлет-преобразованного изображения. Эксцесс — это непрерывная величина, которая, как и асимметрия, также описывает форму распределения. В зависимости от коэффициента эксцесса (k) распределение — по сравнению с нормальным распределением может быть более или менее плоским — или иметь больше или меньше данных на концах или хвостах. Когда распределение более расплывчатое и плоское, это называется платикуртический; когда оно менее рассредоточено и более сконцентрировано в середине, мезокуртный; а когда распределение почти полностью сосредоточено в середине, его называют лептокуртный. Это тот же случай, что и предыдущие случаи дисперсии и асимметрии: чем более мезокуртически распределение, тем ближе коэффициенты были к переводу фактического изображения.

Реализация SVM и SVM ядра с помощью Python Scikit-Learn PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

  • entropy изображения. Энтропия также является непрерывной величиной, она обычно измеряет случайность или беспорядок в системе. В контексте изображения энтропия измеряет разницу между пикселем и соседними пикселями. Для нашего контекста чем больше энтропия у коэффициентов, тем больше потерь при преобразовании изображения — и чем меньше энтропия, тем меньше потери информации.

Реализация SVM и SVM ядра с помощью Python Scikit-Learn PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

Пятой переменной была class переменная, которая, вероятно, имеет значения 0 и 1, которые говорят, была ли банкнота настоящей или поддельной.

Мы можем проверить, содержит ли пятый столбец нули и единицы с помощью Pandas. unique() Метод:

bankdata['class'].unique()

Вышеупомянутый метод возвращает:

array([0, 1]) 

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

  • class изображения. Это целочисленное значение, оно равно 0, если изображение подделано, и 1, если изображение настоящее.

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

Совет: чтобы узнать больше о причинах вейвлет-преобразования на изображениях банкнот и использовании SVM, прочитайте опубликованную статью авторов.

Мы также можем увидеть, сколько записей или изображений у нас есть, просмотрев количество строк в данных через shape имущество:

bankdata.shape

Это выводит:

(1372, 5)

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

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

Изучение набора данных

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

Чтобы узнать пропорцию, мы можем подсчитать каждое из нулевых и единичных значений в данных с помощью value_counts() Метод:

bankdata['class'].value_counts()

Это выводит:

0 762
1 610
Name: class, dtype: int64

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

Мы уже знаем, что есть еще 152 поддельных банкноты, но можем ли мы быть уверены, что этих примеров достаточно для обучения модели? Очень сложно ответить на вопрос, сколько примеров необходимо для обучения, вместо этого мы можем попытаться понять в процентах, насколько велика эта разница между классами.

Первый шаг — использовать pandas value_counts() еще раз, но теперь давайте посмотрим на процент, включив аргумент normalize=True:

bankdata['class'].value_counts(normalize=True)

Ассоциация normalize=True вычисляет процент данных для каждого класса. На данный момент процент поддельных (0) и реальных данных (1) составляет:

0 0.555394
1 0.444606
Name: class, dtype: float64

Это означает, что примерно (~) 56% нашего набора данных являются поддельными, а 44% — реальными. Это дает нам соотношение 56%-44%, что соответствует разнице в 12%. Статистически это считается небольшой разницей, поскольку она чуть выше 10%, поэтому данные считаются сбалансированными. Если бы вместо пропорции 56:44 была пропорция 80:20 или 70:30, то наши данные считались бы несбалансированными, и нам нужно было бы провести некоторую обработку дисбаланса, но, к счастью, это не так.

Мы также можем увидеть эту разницу визуально, взглянув на класс или целевое распределение с помощью гистограммы, наполненной Pandas, используя:

bankdata['class'].plot.hist();

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

Реализация SVM и SVM ядра с помощью Python Scikit-Learn PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

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

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

Мы можем взглянуть на статистические измерения с describe() метод фрейма данных. Мы также можем использовать .T транспонирования — для инвертирования столбцов и строк, что упрощает сравнение значений:

Ознакомьтесь с нашим практическим руководством по изучению Git с рекомендациями, принятыми в отрасли стандартами и прилагаемой памяткой. Перестаньте гуглить команды Git и на самом деле изучить это!

bankdata.describe().T

Это приводит к:

 count mean std min 25% 50% 75% max
variance 1372.0 0.433735 2.842763 -7.0421 -1.773000 0.49618 2.821475 6.8248
skewness 1372.0 1.922353 5.869047 -13.7731 -1.708200 2.31965 6.814625 12.9516
curtosis 1372.0 1.397627 4.310030 -5.2861 -1.574975 0.61663 3.179250 17.9274
entropy 1372.0 -1.191657 2.101013 -8.5482 -2.413450 -0.58665 0.394810 2.4495
class 1372.0 0.444606 0.497103 0.0000 0.000000 0.00000 1.000000 1.0000

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

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

Давайте начнем с распределения каждой функции и построим гистограмму каждого столбца данных, кроме class колонка. class столбец не будет учитываться его положением в массиве столбцов bankdata. Будут выбраны все столбцы, кроме последнего с columns[:-1]:

import matplotlib.pyplot as plt for col in bankdata.columns[:-1]: plt.title(col) bankdata[col].plot.hist() plt.show();

После запуска приведенного выше кода мы видим, что оба skewness и entropy распределения данных имеют отрицательную асимметрию и curtosis имеет положительный перекос. Все распределения симметричны и variance единственное распределение, близкое к нормальному.

Теперь мы можем перейти ко второй части и построить диаграмму рассеяния каждой переменной. Для этого мы также можем выбрать все столбцы, кроме класса, с columns[:-1], используйте Seaborn's scatterplot() и два цикла for для получения вариантов сопряжения для каждой функции. Мы также можем исключить сопряжение признака с самим собой, проверив, равен ли первый признак второму с помощью if statement.

import seaborn as sns for feature_1 in bankdata.columns[:-1]: for feature_2 in bankdata.columns[:-1]: if feature_1 != feature_2: print(feature_1, feature_2) sns.scatterplot(x=feature_1, y=feature_2, data=bankdata, hue='class') plt.show();

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

Но смотреть на все эти графики последовательно может быть немного сложно. У нас есть альтернатива просмотру всех графиков распределения и рассеяния вместе с помощью Seaborn. pairplot().

Оба предыдущих цикла for, которые мы сделали, могут быть заменены только этой строкой:

sns.pairplot(bankdata, hue='class');

Глядя на парный сюжет, кажется, что на самом деле curtosis и variance было бы самой простой комбинацией функций, поэтому разные классы можно было бы разделить линией или линейно отделимый.

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

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

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

Примечание: Обычно в статистике при построении моделей принято следовать процедуре, зависящей от типа данных (дискретные, непрерывные, категориальные, числовые), их распределения и допущений модели. В то время как в компьютерных науках (CS) больше места для проб, ошибок и новых итераций. В CS обычно есть базовый уровень для сравнения. В Scikit-learn есть реализация фиктивных моделей (или фиктивных оценщиков), некоторые не лучше, чем подбрасывание монеты, и просто ответ Да (или 1) 50% времени. Интересно использовать фиктивные модели в качестве основы для реальной модели при сравнении результатов. Ожидается, что фактические результаты модели лучше, чем случайное предположение, в противном случае использование модели машинного обучения не было бы необходимо.

Внедрение SVM с помощью Scikit-Learn

Прежде чем углубиться в теорию работы SVM, мы можем построить нашу первую базовую модель с данными, а Scikit-Learn’s Классификатор опорных векторов or SVC класса.

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

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

Некоторые люди говорят, что оценочный набор является этим промежуточным набором, другие говорят, что тестовый набор является промежуточным набором, а оценочный набор является окончательным набором. Это еще один способ попытаться гарантировать, что модель каким-либо образом не увидит тот же самый пример или что какой-то утечка данных не происходит, и что происходит обобщение модели путем улучшения показателей последнего набора. Если вы хотите следовать этому подходу, вы можете еще раз разделить данные, как описано в этом Train_test_split() от Scikit-Learn — наборы для обучения, тестирования и проверки руководства.

Разделение данных на обучающие/тестовые наборы

На предыдущей сессии мы поняли и изучили данные. Теперь мы можем разделить наши данные на два массива — один для четырех функций, а другой — для пятой или целевой функции. Поскольку мы хотим предсказать класс в зависимости от вейвлет-коэффициентов, наша y будет class колонка и наш X будет ли variance, skewness, curtosisи entropy колонны.

Чтобы разделить цель и функции, мы можем атрибутировать только class столбец к y, а затем удалив его из фрейма данных, чтобы атрибутировать оставшиеся столбцы X .drop() Метод:

y = bankdata['class']
X = bankdata.drop('class', axis=1) 

Как только данные разделены на атрибуты и метки, мы можем разделить их на обучающие и тестовые наборы. Это можно сделать вручную, но model_selection библиотека Scikit-Learn содержит train_test_split() метод, который позволяет нам случайным образом делить данные на обучающие и тестовые наборы.

Чтобы использовать его, мы можем импортировать библиотеку, вызвать train_test_split() метод, пройти X и y данные и определить test_size пройти как аргумент. В этом случае мы определим его как 0.20— это означает, что 20% данных будут использоваться для тестирования, а остальные 80% — для обучения.

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

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

Для этого вы можете выполнить следующий скрипт:

from sklearn.model_selection import train_test_split SEED = 42 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = SEED)

Обратите внимание, что train_test_split() метод уже возвращает X_train, X_test, y_train, y_test устанавливает в таком порядке. Мы можем напечатать количество выборок, разделенных для обучения и тестирования, получив первый (0) элемент shape кортеж, возвращенный свойством:

xtrain_samples = X_train.shape[0]
xtest_samples = X_test.shape[0] print(f'There are {xtrain_samples} samples for training and {xtest_samples} samples for testing.')

Это показывает, что имеется 1097 образцов для обучения и 275 для тестирования.

Обучение модели

Мы разделили данные на обучающие и тестовые наборы. Теперь пришло время создать и обучить модель SVM на данных поезда. Для этого мы можем импортировать Scikit-Learn's svm библиотека вместе с Классификатор опорных векторов класс, или SVC класса.

После импорта класса мы можем создать его экземпляр — поскольку мы создаем простую модель SVM, мы пытаемся разделить наши данные линейно, поэтому мы можем провести линию для разделения наших данных — это то же самое, что использовать линейная функция - путем определения kernel='linear' в качестве аргумента классификатора:

from sklearn.svm import SVC
svc = SVC(kernel='linear')

Таким образом, классификатор попытается найти линейную функцию, разделяющую наши данные. После создания модели давайте обучим ее, или соответствовать это, с данными поезда, используя fit() метод и предоставление X_train функций и y_train цели в качестве аргументов.

Мы можем выполнить следующий код для обучения модели:

svc.fit(X_train, y_train)

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

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

Делать прогнозы

Способ ответить, удалось ли модели описать данные, — рассчитать и посмотреть на какую-то классификацию. метрика.

Учитывая, что обучение контролируется, мы можем делать прогнозы с X_test и сравните эти результаты предсказания, которые мы могли бы назвать y_pred - с фактическим y_testили основа истины.

Чтобы предсказать некоторые данные, модель predict() можно использовать метод. Этот метод получает тестовые функции, X_test, в качестве аргумента и возвращает прогноз, 0 или 1, для каждого из X_testряды.

После предсказания X_test данные, результаты сохраняются в y_pred переменная. Таким образом, каждый из классов, предсказанных с помощью простой линейной модели SVM, теперь находится в y_pred Переменная.

Это код предсказания:

y_pred = svc.predict(X_test)

Учитывая, что у нас есть прогнозы, теперь мы можем сравнить их с фактическими результатами.

Оценка модели

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

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

  2. Точность: когда наша цель состоит в том, чтобы понять, какие правильные значения прогноза были сочтены правильными нашим классификатором. Точность разделит эти истинные положительные значения на выборки, которые были предсказаны как положительные;

$$
точность = дробь{текст{истинные срабатывания}}{текст{истинные срабатывания} + текст{ложные срабатывания}}
$$

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

$$
отзыв = frac{текст{истинно положительные}}{текст{истинно положительные} + текст{ложноотрицательные}}
$$

  1. Счет F1: является сбалансированным или среднее гармоническое точности и отзыва. Наименьшее значение равно 0, а максимальное — 1. Когда f1-score равно 1, это означает, что все классы были предсказаны правильно — это очень сложно получить с реальными данными (почти всегда существуют исключения).

$$
текст{f1-оценка} = 2* дробь{текст{точность} * текст{отзыв}}{текст{точность} + текст{отзыв}}
$$

Мы уже познакомились с матрицей путаницы, точностью, отзывом и оценкой F1. Чтобы их вычислить, мы можем импортировать Scikit-Learn's metrics библиотека. Эта библиотека содержит classification_report и confusion_matrix методов, метод отчета о классификации возвращает точность, полноту и оценку f1. Оба classification_report и confusion_matrix можно легко использовать, чтобы узнать значения всех этих важных показателей.

Для расчета метрик мы импортируем методы, вызываем их и передаем в качестве аргументов предсказанные классификации, y_test, и метки классификации, или y_true.

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

from sklearn.metrics import classification_report, confusion_matrix cm = confusion_matrix(y_test,y_pred)
sns.heatmap(cm, annot=True, fmt='d').set_title('Confusion matrix of linear SVM') print(classification_report(y_test,y_pred))

Это отображает:

 precision recall f1-score support 0 0.99 0.99 0.99 148 1 0.98 0.98 0.98 127 accuracy 0.99 275 macro avg 0.99 0.99 0.99 275
weighted avg 0.99 0.99 0.99 275

Реализация SVM и SVM ядра с помощью Python Scikit-Learn PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

В отчете о классификации мы знаем, что точность составляет 0.99, отзыв 0.99 и оценка f1 0.99 для поддельных банкнот или класса 0. Эти измерения были получены с использованием 148 образцов, как показано в столбце поддержки. Между тем, для класса 1, или реальных заметок, результат был на одну единицу ниже, 0.98 точности, 0.98 отзыва и тот же показатель f1. На этот раз для получения этих результатов было использовано 127 измерений изображения.

Если мы посмотрим на матрицу путаницы, мы также увидим, что из 148 образцов класса 0 146 были правильно классифицированы и было 2 ложных срабатывания, а для 127 образцов класса 1 было 2 ложноотрицательных и 125 истинно положительных результатов.

Мы можем прочитать отчет о классификации и матрицу путаницы, но что они означают?

Интерпретация результатов

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

Почти все образцы для класса 1 были правильно классифицированы, для нашей модели было допущено 2 ошибки при идентификации реальных банкнот. Это то же самое, что и 0.98, или 98%, если вспомнить. Нечто подобное можно сказать и о классе 0, только 2 образца были классифицированы неправильно, в то время как 148 являются истинно отрицательными, что в сумме дает точность 99%.

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

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

Быстрый тест, чтобы выяснить, происходит ли переоснащение, также проводится с данными поезда. Если модель несколько запомнила данные поезда, метрика будет очень близка к 1 или 100%. Помните, что данные поезда больше, чем данные теста — по этой причине — старайтесь смотреть на них пропорционально, больше выборок, больше шансов сделать ошибки, если только не было переобучения.

Чтобы предсказать данные поезда, мы можем повторить то, что мы сделали для тестовых данных, но теперь с X_train:

y_pred_train = svc.predict(X_train) cm_train = confusion_matrix(y_train,y_pred_train)
sns.heatmap(cm_train, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with train data') print(classification_report(y_train,y_pred_train))

Это выводит:

 precision recall f1-score support 0 0.99 0.99 0.99 614 1 0.98 0.99 0.99 483 accuracy 0.99 1097 macro avg 0.99 0.99 0.99 1097
weighted avg 0.99 0.99 0.99 1097

Реализация SVM и SVM ядра с помощью Python Scikit-Learn PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

Легко видеть, что, кажется, есть переобучение, когда показатели поезда составляют 99% при наличии в 4 раза больше данных. Что можно сделать в этом сценарии?

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

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

Заключение

В этой статье мы изучили SVM с простым линейным ядром. Мы получили интуитивное представление об алгоритме SVM, использовали реальный набор данных, исследовали данные и увидели, как эти данные можно использовать вместе с SVM, реализовав его с библиотекой Python Scikit-Learn.

Чтобы продолжать практиковаться, вы можете попробовать другие наборы данных реального мира, доступные в таких местах, как Kaggle, UCI, Общедоступные наборы данных Big Query, университеты и правительственные веб-сайты.

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

Отметка времени:

Больше от Стекабьюс