Нахождение оптимальных весовых коэффициентов

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

Частное решение для байесовского классификатора

Задача в следующем. Пусть у нас есть данные двух классов, и в обоих из них данные имеют гауссово распределение. У них одинаковая ковариация, но разное среднее значение, как видно на рисунке. Для данного примера необходимо знакомство с многомерным гауссовым распределением.

Итак, давайте рассмотрим правило Байеса.

Оно гласит, что постериор p(Y\X) равен правдоподобию, которое является p(X\Y), умноженному на приор, то есть p(Y), делённому на p(X):

P(Y|X) = \frac {p (X|Y) p(Y)} {P(X)}.

Член правдоподобия – это и есть гауссиан, о котором мы говорили. Мы можем вычислить его, взяв данные из каждого класса и вычислив их среднее значение и коацервацию. Приор можно считать просто максимумом функции правдоподобия. Так, например, p(Y=1|X) – это просто количество случаев, когда появился объект класса 1, делённое на общее количество случаев:

P(Y \; = \; 1|X) = \frac {p (X|Y =1) p(Y = 1)} {P(X)},

P(Y \; = \; 0|X) = \frac {p (X|Y =0) p(Y = 0)} {P(X)}.

Следующее, что мы можем сделать, – использовать правило Байеса для положительного класса и раскрыть знаменатель, чтобы привести его к той же форме, что и числитель:

p(y\; = \; 1|x) = \frac {p (x|y =1) p(y = 1)} {p(x)} = \frac {p (x|y =1) p(y = 1)} {p(x|y = 1) p (y=1) + p (x|y = 0) p (y = 0)}.

Далее поделим числитель и знаменатель на числитель:

p(y\; = \; 1|x) = \frac {1}{ 1 + p (x|y =0) p(y = 0) / p(x|y = 1) p (y = 1)}.

 

 

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

p(y\; = \; 1|x) = \frac {1}{ 1 + p (x|y =0) p(y = 0) / p(x|y = 1) p (y = 1)}= \frac {1} {1 +exp (-w^T x)}.

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

-w^T x = 1n (\frac {p (x|y =0) p(y = 0)} {p(x|y = 1) p (y = 1)}).

Обозначим теперь p (y = 1) = 1 - \alpha, \;p (y = 0) = \alpha. 

Это позволит упростить наше выражение. Кроме того, раскроем выражения под знаком логарифма, поскольку в нём идут только операции умножения и деления:

1n (\frac {p (x|y =0) p(y = 0)} {p(x|y = 1) p (y = 1)}) = 1n (p (x|y = 0) + 1n\;\alpha - 1n\;p (x|y = 1) - 1n (1-\alpha).

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

1n (p (x|y = 0) + 1n\;\alpha - 1n\;p (x|y = 1) - 1n (1-\alpha) =

= 1n \frac {1} {\sqrt {(2\pi)^D} |\sum|} e - \frac {1}{2} (x -\mu_0)^T \sum^{-1} (x - \mu_0) \;- \;1n \frac {1} {\sqrt {(2\pi)^D} |\sum|} e - \frac {1}{2} (x -\mu_1)^T \sum^{-1} (x - \mu_1) + 1n \frac {\alpha} {1 - \alpha} =

= - \frac {1}{2} (x^T \sum^{-1} x - x^T \sum^{-1} \mu_0 - \mu_0^T \sum^{-1}x + \mu_0^T \sum^{-1} \mu_0) + \;\frac {1}{2} (x^T \sum^{-1} x - x^T \sum^{-1} \mu_1 - \mu_1^T \sum^{-1}x + \mu_1^T \sum^{-1} \mu_1) + 1n\frac{\alpha}{1 - \alpha}.

Заметьте, что и все квадратичные члены сокращаются, и именно поэтому xT у нас встречается дважды.

Тут у вас может возникнуть вопрос: а разве xTΣ-1μ равно μTΣ-1x?

И разве не стоит быть осторожным с такими преобразованиями? Я настоятельно рекомендую вам провести все расчёты на бумаге, чтобы для себя удостовериться – да, равно. Не забывайте, что коацервация и обратная ей величина симметричны.

Убрав множитель 1/2 и сгруппировав члены, зависящие от x, и не зависящие от x, мы придём к следующей форме уравнения, взглянув на которую более внимательно, мы обнаружим, что она выглядит точно так же, как и наша линейная форма классификатора, равная – (wTx + b):

 - \frac {1}{2} (x^T \sum^{-1} x - x^T \sum^{-1} \mu_0 - \mu_0^T \sum^{-1}x + \mu_0^T \sum^{-1} \mu_0) + \;\frac {1}{2} (x^T \sum^{-1} x - x^T \sum^{-1} \mu_1 - \mu_1^T \sum^{-1}x + \mu_1^T \sum^{-1} \mu_1) + 1n\frac{\alpha}{1 - \alpha} =

= \mu_0^T \sum^{-1} x - \mu_1^T \sum^{-1} x - \frac {1}{2} \mu_0^T \sum^{-1} \mu_0 + \frac {1}{2} \mu_1^T \sum^{-1}\mu_1 + 1n\frac{\alpha}{1 - \alpha} =

= (\mu_0^T - \mu_1^T) \sum^{-1} x - \frac {1}{2} \mu_0^T \sum^{-1} \mu_0 + \frac {1}{2} \mu_1^T \sum^{-1}\mu_1 + 1n\frac{\alpha}{1 - \alpha} =

= - (w^Tx + b).

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

Итак, у нас есть один член, зависящий от x, – это наше wT, и один член, от x не зависящий, – это наше b. Если подставить выражения для wT и b , то получатся следующие уравнения:

w^T = (\mu^T_1 - \mu^T_0) \sum^{-1},

b = \frac{1}{2} \mu^T_0 \sum^{-1} \mu_0 - \frac{1}{2} \mu^T_1 \sum^{-1} \mu_1 - 1n \frac{\alpha}{1 - \alpha}.

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

В наших примерах с кодом мы будем использовать два гауссиана – один с центром с координатами (-2, -2), а второй – с центром с координатами (+2, +2); дисперсия по каждой размерности будет равна единице, причём каждая размерность будет независимой, так что любые диагноли в ковариации будут равны нулю. В качестве упражнения предлагаю вам самостоятельно убедиться, что решением является w = (4, 4), b = 0. При этом предполагется, что мы имеем равное количество примеров обоих классов, что означает, что α = 0,5. Кроме того, убедитесь, что вы можете самостоятельно вывести решение, не пересматривая видео лекции.

И пара коротких замечаний. Описанный метод часто называется линейным дискриминантным анализом (LDA). Если ковариация является диагональной матрицей, как мы видели в числовом примере, приведённом выше, это также пример так называемого наивного байесовского классификатора. Удостоверьтесь, что вы понимаете, почему это так.

Если же у нас различные ковариации, то – внимание! – квадратичные члены не будут сокращаться. В качестве упражнения можете попробовать решить получившееся квадратное уравнение. Это ещё называется квадратичным дискриминантным анализом (QDA). Попробуйте также написать код для квадратичного дискриминантного анализа и сравните результат с линейным.

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

Что означают все эти символы – X, Y, N, D, L, J и т. д?

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

Первое, что мы  хотим объяснить, – это обозначения входных переменных. Обычно мы используем N в качестве количества опытов (наблюдений), а D – размерность, то есть количество признаков (параметров) в каждом из этих наблюдений. Например, если я хочу измерить рост 10 своих одноклассников, чтобы вычислить их средний рост, это значит, что N = 10. Если же я вычисляю их рост, вес и обхват, чтобы вычислить процент жира в теле каждого из них, то D = 3, поскольку у меня три признака – рост, вес и обхват.

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

Как вы знаете, когда мы обучаем модель, как в случае логистической регрессии, каждая входная переменная x имеет зависимую от неё целевую переменную y, поэтому в случае N наблюдений мы имеем N-е количество y. Это значит, что если мы соберем все наши y, то получим матрицу размерностью Nx1. В частности, при двоичной классификации это будет матрица размерности Nx1, состоящая из нулей и единиц.

В наших статьях мы иногда будем обозначать целевую переменную через t. Это и понятно, потому что слово «target» (цель) начинается с буквы t. Причина же того, что мы будем писать t вместо y, состоит в том, что y мы будем использовать для несколько другой цели, а именно: y будет использоваться в качестве исходящей переменной всей модели логистической регрессии.

Не забывайте, что истинная цель логистической регрессии – это нахождение вероятности P(Y=1|X). Постоянно записывать это выражение долго, поэтому сокращённо мы будем обозначать его через y. Как видите, это может озадачить, поскольку y используется для двух совершенно разных вещей.

Следующее, что может внести путаницу, – это функция затрат, поскольку она имеет много синонимов. Как вы знаете, в машинном обучении мы пытаемся сформулировать функцию затрат, а затем минимизировать её для нахождения оптимальных параметров модели. Иногда функцию затрат мы будем называть функцией ошибок или целевой функцией. Мы точно так же хотим свести к минимуму функцию ошибок, как и функцию затрат, что понятно даже чисто семантически. В случае же целевой функции мы будем пытаться иногда найти максимум, а иногда – найти минимум. Это обычное для науки переформулирование задачи – например, нахождение минимума x2 равносильно нахождение максимума xравносильно нахождение максимума x2

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

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

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

Проект интернет-магазина. Обучение логистической модели

Напомним вам что в этой статье мы уже запустили проект интернет-магазина   

И сейчас мы продолжим наш проект и займемся обучением логистической модели.

Импортируем необходимые библиотеки и, конечно, загрузим наши данные.

import numpy as np

import matplotllib.pyplot as plt

from sklearn.utils import shuffle

from process import get_binary_data

X, Y = get_binary_data()

X, Y = shuffle(X, Y)

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

Xtrain = X[:-100]

Ytrain = Y[:-100]

Xtest = X[:-100]

Ytest = Y[:-100]

После этого вновь установим случайное значение весовых коэффициентов.

D = X.shape[1]

W = np.random.randn(D)

b = 0

Далее создадим функции sigmoid, forward и classification_rate. Всё это мы уже делали.

def sigmoid(a):

return 1 / (1 + np.exp(-a))

def forward(X, W, b):

return sigmoid(X.dot(W) + b)

def classification_rate(Y, P):

return np.mean(Y == P)

Кроме того, создадим функцию cross_entropy.

def cross_entropy(T, pY):

return –np.mean(T*np.log(pY) + (1 – T)*np.log(1 – pY))

Теперь перейдём к введению основного учебного набора. При каждом проходе цикла будем вычислять ошибку учебного и проверочного наборов. Коэффициент обучения установим равным 0,001, количество итераций – равным 10000.

train_costs[]

test_costs[]

learning_rate = 0.001

для i в xrange(10000):

pYtrain = forward(Xtrain, W, b)

pYtest = forward(Xtest, W, b)

ctrain – cross_entropy(Ytrain, pYtrain)

ctest = cross_entropy(Ytest, pYtest)

train_costs.append(ctrain)

test_costs.append(ctest)

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

W -= learning_rate*Xtrain.T.dot(pYtrain – Ytrain)

b -= learning_rate*(pYtrain – Ytrain).sum()

если i % 1000 == 0:

print i, ctrain, ctest

И, наконец, после всего этого выведем коэффициенты классификации для учебного и проверочного наборов.

print ‘’Fainal train classification_rate:’’, classification_rate(Ytrain, np.round(pYtrain))

print ‘’Fainal test classification_rate:’’, classification_rate(Ytest, np.round(pYtest))

Ещё одна интересная вещь, которую мы можем сделать, – это вывести на экран графики ошибок для учебного и проверочного наборов.

legend1, = plt.plot(train_costs, label=’ train_costs’)

legend2, = plt.plot(test_costs, label=’ test_costs’)

plt.legend([legend1, legend2])

plt.show()

Запустим программу.

Мы видим, что графики функций ошибок для учебного и проверочного наборов практически одинаковы. Наш окончательный коэффициент классификации составляет 96% для учебного набора и 92% для проверочного.

Андрей Никитенко
Андрей Никитенко
Задать вопрос эксперту
Понравилась статья? Поделить с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Share via
Copy link