Введение алгоритма
Алгоритм персептрона является классическим алгоритмом бинарной классификации.
Народное описание: На столе много апельсинов и яблок, и стоит очередь, так что яблоки и апельсины по обе стороны от очереди. Цель алгоритма персептрона состоит в том, чтобы найти эту линию.
Формальное описание (отрывок из "Алгоритмы машинного обучения" - Ли Ханг): Алгоритм персептрона представляет собой модель линейной классификации для двухклассовой классификации. Его входом является вектор признаков экземпляра, а выходом является класс экземпляра, принимая +1 и -1 двоичное значение. Персептрон соответствует гиперплоскости, которая делит экземпляры на положительные и отрицательные классы во входном пространстве (векторе признаков) и принадлежит дискриминационной модели. Целью алгоритма набора персептрона является поиск гиперплоскости классификации, которая в настоящее время разделяет обучающие данные.С этой целью импортируется функция потерь, основанная на неправильной классификации, и используется алгоритм градиентного спуска для минимизации функции потерь для получения модели персептрона. . Эта модель была предложена Розенблаттом в 1957 году и является основой нейронных сетей и машин опорных векторов.
Описание модели
Чтобы упростить описание проблемы, нарисуйте график с помощью matplotlib.
Краткое описание модели: Подставьте координаты всех точек в функцию, и результат может быть +1 или -1. На основании этого результата мишени делятся на две категории. Эта соответствующая функция становится персептроном.
Формальное описание модели:
Предположим, что входное пространство (пространство признаков) равно ,
Выходное пространство.
входитьвекторное пространство, представляющее экземпляры, соответствующие точкам входного пространства (пространство признаков);
выводПредставляет класс экземпляра. Следующая функция из входного пространства в выходное пространство:
называется перцептроном.
в:
ипараметры модели персептрона
называются весами (или векторами)
предвзятость
выражатьивнутренний продукт
Примечание:, который является векторомтоже вектор. Обратите внимание, что это векторизованное представление.
является символической функцией:
Как показано на рисунке:
стратегия обучения персептрона
Алгоритм персептрона пытается использовать гиперплоскость (представленную в виде линии в двумерном пространстве) для точного и правильного разделения положительных и отрицательных экземпляров. Чтобы найти такую линию, мы можем посчитать все ошибочно классифицированные точки, сумму их расстояний от плоскости. Сначала рассмотрим формулу расстояния.
Средняя школа и старшая школа должны выучить формулу расстояния от точки до линии точкак прямой линииРасстояние:
Точно так же для модели персептрона, которую мы определили на предыдущем шаге, она представлена в векторизованной форме,к гиперплоскостиРасстояние:
Во-вторых, для неправильно классифицированных данныхСказать,
Упрощается до:
Среди них, когдачас,;когдачас,;
Таким образом, мы находим расстояние от неправильно классифицированной точки до гиперплоскости. Предположим, что множество всех ошибочно классифицированных точек равно. Тогда сумма расстояний от всех ошибочно классифицированных точек до гиперплоскости:
пс:иЕго можно увеличивать и уменьшать пропорционально. Но представляемая ими гиперплоскость инвариантна. Здесь мы не рассматриваемможно получить функцию потерь обучения персептрона: данный тренировочный набор
в:
i=1,2,...,N
Функция потерь алгоритма персептрона
M — множество ошибочно классифицированных точек.
Таким образом, проблема решения модели персептрона теперь меняется на решение, так чтоминимум. который:
Шаги алгоритма обучения персептрона
Алгоритм градиентного спуска необходимо использовать в процессе решения, поэтому давайте сначала решим функцию потерьполоса градиента
Конкретные шаги алгоритма:
(1) Выберите начальное значение;
(2) Выберите данные в обучающем наборе;
(3) Если,
(4) Переходите к (2) до тех пор, пока в тренировочном наборе не останется ошибочно классифицированных точек.
До сих пор мы описали шаги алгоритма персептрона. Далее делаем две вещи: 1, вызовите алгоритм персептрона в sklearn, 2 рукописный алгоритм персептрона и вызовите его.
Вызовите модель персептрона в sklearn
Сначала импортируйте необходимые библиотеки
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import load_iris
импортировать набор данных
iris = load_iris()
# 数据集中共有3类,每类50各,我们取0,1两类。
# 共有4个特征值,我们取第二个和第三个特征,方便分析。
data = iris.data[:,2:4][iris.target < 2]
target = iris.target[iris.target < 2]
Разделите данные на обучающие и тестовые наборы:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.33, random_state=42)
Давайте посмотрим на распределение набора данных:
plt.scatter(X_train[y_train==0][:, 0], X_train[y_train==0][:, 1], c='r',)
plt.scatter(X_train[y_train==1][:, 0], X_train[y_train==1][:, 1], c='g')
plt.xlim(-2, 6)
plt.ylim(-2, 6)
Результат выглядит следующим образом:
Далее импортируем модель персептрона и начинаем обучение
from sklearn.linear_model import Perceptron
clf = Perceptron()
clf.fit(X_train, y_train)
X_predict = clf.predict(X_test)
X_predict
Результат выглядит следующим образом:
array([1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1,
0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1])
Сравните с y_test:
y_test
Результат выглядит следующим образом:
array([1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1,
0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1])
Все прогнозы оказались точными. Давайте используем функцию оценки, чтобы увидеть точность:
clf.score(X_test, y_test)
Результат выглядит следующим образом:
1.0
Доказательство является точным на 100%, что связано с тем, что набор данных слишком мал. А набор данных полностью линейно разделим, поэтому точность достигает 100%.
Теперь найдутся друзья, которым не терпится увидеть полученную гиперплоскость (соответствующую разделительной линии в двумерной плоскости).
Посмотрим на параметры вектора после решенияБар:
clf.coef_
Результат выглядит следующим образом:
array([[0.8, 0.8]])
Посмотрите на б:
clf.intercept_
Результат выглядит следующим образом:
array([-2.])
Теперь, когда все параметры получены, соответствующий
Теперь давайте нарисуем эту линию и предыдущие точки данных на том же графике, чтобы увидеть эффект:
plt.scatter(X_train[y_train==0][:, 0], X_train[y_train==0][:, 1], c='r',)
plt.scatter(X_train[y_train==1][:, 0], X_train[y_train==1][:, 1], c='g')
plt.xlim(-2, 6)
plt.ylim(-2, 6)
x_1 = np.arange(-2, 6, 0.01)
x_2 = - x_1 + 2.5
plt.plot(x_1, x_2)
Результат выглядит следующим образом:
Это всегда странно, линия слишком близко к красной области. Но ведь набор данных делится на два. Эффект уже полный.
Реализуйте алгоритм персептрона самостоятельно
На предыдущем шаге мы вызвали алгоритм персептрона в sklearn и реализовали бинарную классификацию выборок. Далее давайте сами реализуем алгоритм персептрона. и назовите это.
Код персептрона, реализованный мной, выглядит следующим образом:
#coding: utf-8
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.metrics import accuracy_score
class Perceptron:
def __init__(self, eta=0.01, n_iter=50, random_state=1):
self.eta = eta
self.n_iter = n_iter
self.random_state = random_state
def fit(self, X, y):
"""
Fit training data.
Parameters
----------
X : {array-like}, shape = [n_samples, n_features]
Training vectors, where n_samples is the number of samples and
n_features is the number of features.
y : array-like, shape = [n_samples]
Target values.
Returns
-------
self : object
"""
assert X.ndim == 2, "X must be 2 dimensional"
assert y.ndim == 1, "y must be 1 dimensional"
assert X.shape[0] == y.shape[0], \
"the size of X_train must be equal to the size of y_train"
rgen = np.random.RandomState(self.random_state)
self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
for _ in range(self.n_iter):
assert X[self.predict(X)!=y].shape[0] == y[self.predict(X)!=y].shape[0], \
"the size of X_train must be equal to the size of y_train"
# M 表示错误分类的点
M = X[self.predict(X)!=y]
M_target = y[self.predict(X)!=y]
if (len(M) > 0):
# 每次迭代抽取一个错误点进行梯度下降 直到错误分类点的集合大小为0
M_predict = np.array(self.predict(M))
x_i = M[0]
M_target_i = np.array([M_target[0]])
M_predict_i = np.array([M_predict[0]])
update = self.eta * (M_target_i - M_predict_i)
self.w_[1:] += update * x_i
self.w_[0] += update
return self
def _compute_value(self, X):
assert X.ndim == 2, "the single input must be one dimenssional"
return np.dot(X, self.w_[1:]) + self.w_[0]
def predict(self, X):
assert X.ndim == 2, "function predict: X must be 2 dimensional"
return np.where(self._compute_value(X) >= 0.0, 1, -1)
def score(self, X_test, y_test):
"""根据测试数据集 X_test 和 y_test 确定当前模型的准确度"""
y_predict = self.predict(X_test)
return accuracy_score(y_test, y_predict)
Затем мы вызываем его, чтобы увидеть эффект. (Импортируйте набор данных, разделите набор данных, используйте код на предыдущем шаге, теперь мы напрямую вызываем наш собственный алгоритм персептрона)
from Perceptron import Perceptron
clf = Perceptron(n_iter=10000, eta=0.1)
clf.fit(X_train, y_train)
clf.predict(X_test)
clf.score(X_test, y_test), clf.w_
Результат выглядит следующим образом:
(1.0, array([-0.38375655, 0.13388244, 0.19471828]))
Мы видим, что точность составляет 100%. clf.w_[0] соответствует нашей модели
За исключением части, отличной от clf.w_[0], это означает, то есть clf.w_[1:]
Наносим точки и расчетную линию:
plt.scatter(X_train[y_train==1][:, 0], X_train[y_train==1][:, 1], c='r',)
plt.scatter(X_train[y_train==-1][:, 0], X_train[y_train==-1][:, 1], c='g')
plt.xlim(-2, 6)
plt.ylim(-2, 6)
y_1 = np.arange(-2, 6, 0.01)
y_2 = - clf.w_[1] / clf.w_[2] * y_1 - clf.w_[0] / clf.w_ [2]
plt.plot(y_1, y_2)
Результат выглядит следующим образом:
Видно, что сегментация набора данных была достигнута.
Суммировать
В самореализованном алгоритме есть параметр эта, который представляет скорость обучения, Чем больше эта, тем быстрее сходимость. Однако, если эта слишком велика, флуктуация процесса сходимости будет слишком большой. Вам нужно настроить параметры самостоятельно.
Также есть соответствующие параметры в соответствующем файле sklearn. Заинтересованные ребята могут сами выставлять разные значения и наблюдать за процессом сходимости.