Народное машинное обучение (4) Логистическая регрессия

машинное обучение
Народное машинное обучение (4) Логистическая регрессия

Народное машинное обучение — логистическая регрессия — теория + практика


[toc]

Обзор

Линейная регрессия описана ранее, модель линейной регрессииy=wT+by = w^T + b. Прогнозируемое значение модели аппроксимирует истинную метку y. Так может ли предсказанное значение модели быть аппроксимировано производной истинной метки y? Например, предсказанное значение модели аппроксимирует логарифмическую функцию истинной метки. Следующее вводит знания о логистической регрессии.

функция преобразования

Нам нужна монотонно дифференцируемая функция, чтобы связать истинную метку y задачи классификации с прогнозируемым значением модели линейной регрессии, поэтому нам нужна передаточная функция, чтобы связать значение линейной модели с фактическим прогнозируемым значением. Рассмотрим задачу бинарной классификации, где выходным токеном является то, что y принадлежит {0, 1}, а прогнозируемое значение, полученное линейной моделью, равноz=wT+bz = w^T + b является реальным значением, то нам нужно преобразовать это реальное значение в значение 0/1, и наиболее идеальной функцией является функция единичного шага.

единичная ступенчатая функция

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

\begin{equation} y = \begin{cases} 0 & \mbox{if z < 0}\\ 0.5 & \mbox{if z = 0} \\ 1 & \mbox{if z > 0} \end{cases} \end{equation}

sigmoid function

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

y=11+ezy = \dfrac{1}{1 + e^{-z}}

Преобразует значение z в значение y, близкое к 0 или 1, и его выходное значение круто изменяется в районе z=0. Затем наша текущая модель изменится на

y=11+e(wT+b)y = \dfrac{1}{1 + e^{-(w^T + b)}}

enter image description here

Шансы против логарифмических шансов

Шансы: если y — вероятность положительного примера, а 1-y — вероятность отрицательного примера, то отношение двухy1y \dfrac{y}{1 - y}называется вероятностью и отражает относительную вероятность того, что x является положительным примером. Тогда его можно получить по сигмовидной функции.

lny1y=wT+b ln\dfrac{y}{1 - y} = w^T + b

lny1y ln\dfrac{y}{1 - y}называемые логарифмические шансы;

** Отсюда видно, чтоy=11+e(wT+b)y = \dfrac{1}{1 + e^{-(w^T + b)}}Фактически результат прогнозирования линейной модели используется для аппроксимации логарифмической вероятности реальной оценки, поэтому соответствующая модель называется «логарифмическая регрессия вероятности»**

Функция потерь и метод расчета описаны ниже.

функция потерь

так как:lny1y=wT+b ln\dfrac{y}{1 - y} = w^T + b. так

p(y=1x)=e(wT+b)1+e(wT+b)p(y=1|x) = \dfrac{e^{(w^T + b)}}{1 + e^{(w^T + b)}}

p(y=0x)=11+e(wT+b)p(y=0|x) = \dfrac{1}{1 + e^{(w^T + b)}}

Мы используем метод оценки максимального правдоподобия для ее решения.Поскольку это проблема бинарной классификации, она соответствует распределению 0-1 в вероятности, поэтому функция правдоподобия сделатьp(y=1x)=e(wT+b)1+e(wT+b)=f(x)p(y=1|x) = \dfrac{e^{(w^T + b)}}{1 + e^{(w^T + b)}} = f(x),p(y=0x)=11+e(wT+b)=1f(x)p(y=0|x) = \dfrac{1}{1 + e^{(w^T + b)}}=1-f(x)

L(w)=i=1n[f(xi)]yi[1f(xi)]1yiL(w)=\prod_{i=1}^{n}[f(x_i)]^{y_i}[1 - f(x_i)]^{1- y_i}

Логарифмическая функция правдоподобия:

l(w)=lnL(w)=i=1n[yilnf(xi)+(1yi)ln(1f(xi))]l(w)=lnL(w)=\sum_{i = 1}^n [y_ilnf(x_i) + (1 -y_i)ln(1 - f(x_i))] l(w)=lnL(w)=i=1n[yilnf(xi)1f(xi)+ln(1f(xi))]l(w)=lnL(w)=\sum_{i = 1}^n [y_iln\dfrac{f(x_i)}{1 - f(x_i)} + ln(1-f(x_i))] l(w)=lnL(w)=i=1n[yi(wxi)ln(1+ewxi)]l(w)=lnL(w)=\sum_{i = 1}^n [y_i(wx_i) - ln(1 + e^{wx_i})]

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

Кодовый бой

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

  1. переменная для ввода информации
  • Образцы: включая метки признаков и классификаций, положительные и отрицательные примеры
  • Инициализация коэффициентов регрессии;
  • расчет размера шага;
  • Определена функция потерь;
  • Расчет градиента функции потерь;
  • Градиент и размер шага через функцию потерь делают каждую итерацию;
  • условие остановки итерации;
  1. Введите данные (определить переменные выше)
  • Образец информации: включая функции, классификационные теги (извлекаются из машинного обучения реального боя и будут опубликованы позже;
  • Все коэффициенты функции регрессии инициализируются равными 1,0;
  • Для простоты установите размер шага альфа = 0,001;
  • Функция потерь, которая была введена выше:

l(w)=lnL(w)=i=1n[yi(wxi)ln(1+ewxi)]l(w)=lnL(w)=\sum_{i = 1}^n [y_i(wx_i) - ln(1 + e^{wx_i})]

  • Градиент функции потерь:

[f2xiyj]nxn[\frac {\partial f^2} {\partial x_i \partial y_j}]_{nxn} l(w)=lnL(w)=i=1n[yi(wxi)ln(1+ewxi)]l(w)=lnL(w)=\sum_{i = 1}^n [y_i(wx_i) - ln(1 + e^{wx_i})]

[(lnL(w))w]=i=1n[yixie(wxi)1+e(wxi)xi]=i=1n[xi(yie(wxi)1+e(wxi))][\frac {\partial (lnL(w))} {\partial w}] = \sum_{i = 1}^n[y_ix_i - \dfrac{e^{(wx_i)}}{1 + e^{(wx_i)}}x_i] = \sum_{i = 1}^n[x_i (y_i- \dfrac{e^{(wx_i)}}{1 + e^{(wx_i)}})]

[(lnL(w))w]=i=1n[xi(yi11+e(wxi))][\frac {\partial (lnL(w))} {\partial w}] = \sum_{i = 1}^n[x_i (y_i- \dfrac{1}{1 + e^{(-wx_i)}})]

  • Условие остановки для итерации: maxCycles = 500, 500 итераций.
  1. код
def loadDataSet():
    dataMat = []; labelMat = []
    fr = open('testSet.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()
        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
        labelMat.append(int(lineArr[2]))
    return dataMat,labelMat

def sigmoid(inX):
    return 1.0/(1+exp(-inX))

def gradAscent(dataMatIn, classLabels):
    dataMatrix = mat(dataMatIn)             #convert to NumPy matrix
    labelMat = mat(classLabels).transpose() #convert to NumPy matrix
    m,n = shape(dataMatrix)
    alpha = 0.001
    maxCycles = 500
    weights = ones((n,1))
    for k in range(maxCycles):              #heavy on matrix operations
        h = sigmoid(dataMatrix*weights)     #matrix mult
        error = (labelMat - h)              #vector subtraction
        weights = weights + alpha * dataMatrix.transpose()* error # 这里就是用梯度迭代修改参数的值
    return weights
  1. образец
-0.017612	14.053064	0
-1.395634	4.662541	1
-0.752157	6.538620	0
-1.322371	7.152853	0
0.423363	11.054677	0
0.406704	7.067335	1
0.667394	12.741452	0
-2.460150	6.866805	1
0.569411	9.548755	0
-0.026632	10.427743	0
0.850433	6.920334	1
1.347183	13.175500	0
1.176813	3.167020	1
-1.781871	9.097953	0
-0.566606	5.749003	1
0.931635	1.589505	1
-0.024205	6.151823	1
-0.036453	2.690988	1
-0.196949	0.444165	1
1.014459	5.754399	1
1.985298	3.230619	1
-1.693453	-0.557540	1
-0.576525	11.778922	0
-0.346811	-1.678730	1
-2.124484	2.672471	1
1.217916	9.597015	0
-0.733928	9.098687	0
-3.642001	-1.618087	1
0.315985	3.523953	1
1.416614	9.619232	0
-0.386323	3.989286	1
0.556921	8.294984	1
1.224863	11.587360	0
-1.347803	-2.406051	1
1.196604	4.951851	1
0.275221	9.543647	0
0.470575	9.332488	0
-1.889567	9.542662	0
-1.527893	12.150579	0
-1.185247	11.309318	0
-0.445678	3.297303	1
1.042222	6.105155	1
-0.618787	10.320986	0
1.152083	0.548467	1
0.828534	2.676045	1
-1.237728	10.549033	0
-0.683565	-2.166125	1
0.229456	5.921938	1
-0.959885	11.555336	0
0.492911	10.993324	0
0.184992	8.721488	0
-0.355715	10.325976	0
-0.397822	8.058397	0
0.824839	13.730343	0
1.507278	5.027866	1
0.099671	6.835839	1
-0.344008	10.717485	0
1.785928	7.718645	1
-0.918801	11.560217	0
-0.364009	4.747300	1
-0.841722	4.119083	1
0.490426	1.960539	1
-0.007194	9.075792	0
0.356107	12.447863	0
0.342578	12.281162	0
-0.810823	-1.466018	1
2.530777	6.476801	1
1.296683	11.607559	0
0.475487	12.040035	0
-0.783277	11.009725	0
0.074798	11.023650	0
-1.337472	0.468339	1
-0.102781	13.763651	0
-0.147324	2.874846	1
0.518389	9.887035	0
1.015399	7.571882	0
-1.658086	-0.027255	1
1.319944	2.171228	1
2.056216	5.019981	1
-0.851633	4.375691	1
-1.510047	6.061992	0
-1.076637	-3.181888	1
1.821096	10.283990	0
3.010150	8.401766	1
-1.099458	1.688274	1
-0.834872	-1.733869	1
-0.846637	3.849075	1
1.400102	12.628781	0
1.752842	5.468166	1
0.078557	0.059736	1
0.089392	-0.715300	1
1.825662	12.693808	0
0.197445	9.744638	0
0.126117	0.922311	1
-0.679797	1.220530	1
0.677983	2.556666	1
0.761349	10.693862	0
-2.168791	0.143632	1
1.388610	9.341997	0
0.317029	14.739025	0
  1. получить результаты
>>> import logRegres
>>> param_mat, label_mat = logRegres.loadDataSet()
>>> 
>>> logRegres.gradAscent(param_mat, label_mat)
matrix([[ 4.12414349],
        [ 0.48007329],
        [-0.6168482 ]])
>>> 

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

Ссылаться на

  • машинное обучение в действии