Алгоритм логистической регрессии
В этой статье представлен алгоритм логистической регрессии в машинном обучении, который мы используем для классификации данных. Алгоритм логистической регрессии также является алгоритмом обучения с учителем, который должен обучаться через пространство выборки и подходит для числовых и номинальных данных.Например, нам нужно судить о данных в соответствии с размером собственного значения (числового) ввода данные Не какая-то классификация.
1. Пример данных
В нашем случае у нас есть некоторые примеры данных, подобные этому:
- Демонстрационные данные имеют 3 собственных значения: X0X0, X1X1, X2X2.
- Мы оцениваем, соответствуют ли данные требованиям, через X1X1 и X2X2 в этих трех собственных значениях, то есть 1, если данные соответствуют требованиям, и 0, если они не соответствуют требованиям.
- Данные выборки классифицируются и сохраняются в массиве
Мы пишем следующие функции в файле logRegres.py для подготовки данных и распечатываем данные для наблюдения:
#coding=utf-8
from numpy import *
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
if __name__=='__main__':
dataMat,labelMat=loadDataSet()
print 'dataMat:\n',dataMat
Давайте посмотрим на этот образец данных:
dataMat:
[[1.0, -0.017612, 14.053064], [1.0, -1.395634, 4.662541], [1.0, -0.752157, 6.53862], [1.0, -1.322371, 7.152853], [1.0, 0.423363, 11.054677], [1.0, 0.406704, 7.067335], [1.0, 0.667394, 12.741452], [1.0, -2.46015, 6.866805], [1.0, 0.569411, 9.548755], [1.0, -0.026632, 10.427743], [1.0, 0.850433, 6.920334], [1.0, 1.347183, 13.1755], [1.0, 1.176813, 3.16702], [1.0, -1.781871, 9.097953], [1.0, -0.566606, 5.749003], [1.0, 0.931635, 1.589505], [1.0, -0.024205, 6.151823], [1.0, -0.036453, 2.690988], [1.0, -0.196949, 0.444165], [1.0, 1.014459, 5.754399], [1.0, 1.985298, 3.230619], [1.0, -1.693453, -0.55754], [1.0, -0.576525, 11.778922], [1.0, -0.346811, -1.67873], [1.0, -2.124484, 2.672471], [1.0, 1.217916, 9.597015], [1.0, -0.733928, 9.098687], [1.0, -3.642001, -1.618087], [1.0, 0.315985, 3.523953], [1.0, 1.416614, 9.619232], [1.0, -0.386323, 3.989286], [1.0, 0.556921, 8.294984], [1.0, 1.224863, 11.58736], [1.0, -1.347803, -2.406051], [1.0, 1.196604, 4.951851], [1.0, 0.275221, 9.543647], [1.0, 0.470575, 9.332488], [1.0, -1.889567, 9.542662], [1.0, -1.527893, 12.150579], [1.0, -1.185247, 11.309318], [1.0, -0.445678, 3.297303], [1.0, 1.042222, 6.105155], [1.0, -0.618787, 10.320986], [1.0, 1.152083, 0.548467], [1.0, 0.828534, 2.676045], [1.0, -1.237728, 10.549033], [1.0, -0.683565, -2.166125], [1.0, 0.229456, 5.921938], [1.0, -0.959885, 11.555336], [1.0, 0.492911, 10.993324], [1.0, 0.184992, 8.721488], [1.0, -0.355715, 10.325976], [1.0, -0.397822, 8.058397], [1.0, 0.824839, 13.730343], [1.0, 1.507278, 5.027866], [1.0, 0.099671, 6.835839], [1.0, -0.344008, 10.717485], [1.0, 1.785928, 7.718645], [1.0, -0.918801, 11.560217], [1.0, -0.364009, 4.7473], [1.0, -0.841722, 4.119083], [1.0, 0.490426, 1.960539], [1.0, -0.007194, 9.075792], [1.0, 0.356107, 12.447863], [1.0, 0.342578, 12.281162], [1.0, -0.810823, -1.466018], [1.0, 2.530777, 6.476801], [1.0, 1.296683, 11.607559], [1.0, 0.475487, 12.040035], [1.0, -0.783277, 11.009725], [1.0, 0.074798, 11.02365], [1.0, -1.337472, 0.468339], [1.0, -0.102781, 13.763651], [1.0, -0.147324, 2.874846], [1.0, 0.518389, 9.887035], [1.0, 1.015399, 7.571882], [1.0, -1.658086, -0.027255], [1.0, 1.319944, 2.171228], [1.0, 2.056216, 5.019981], [1.0, -0.851633, 4.375691], [1.0, -1.510047, 6.061992], [1.0, -1.076637, -3.181888], [1.0, 1.821096, 10.28399], [1.0, 3.01015, 8.401766], [1.0, -1.099458, 1.688274], [1.0, -0.834872, -1.733869], [1.0, -0.846637, 3.849075], [1.0, 1.400102, 12.628781], [1.0, 1.752842, 5.468166], [1.0, 0.078557, 0.059736], [1.0, 0.089392, -0.7153], [1.0, 1.825662, 12.693808], [1.0, 0.197445, 9.744638], [1.0, 0.126117, 0.922311], [1.0, -0.679797, 1.22053], [1.0, 0.677983, 2.556666], [1.0, 0.761349, 10.693862], [1.0, -2.168791, 0.143632], [1.0, 1.38861, 9.341997], [1.0, 0.317029, 14.739025]]
labelMat:
[0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0]
образецdataMat
Первый столбец , то есть наши собственные значения X0X0 все равны 1. Нам нужно обратить внимание, чтобы понять эту проблему при расчете параметров регрессии. Всего имеется 100 единиц выборочных данных, и соответствующие результаты классификации также составляют 100 единиц.
Итак, наш вопрос сейчас:
Мы хотим найти связь между собственными значениями в выборочном пространстве и результатами классификации. Разработайте функцию или функцию, чтобы понять, что после ввода набора собственных значений она может автоматически классифицировать входные данные в соответствии с соотношением между собственными значениями выборочного пространства и результатами классификации, то есть результатом будет либо 1, либо 0. .
2. Сигмовидная функция
Чтобы решить проблемы, о которых мы упоминали в предыдущем разделе, давайте сначала представим сигмовидную функцию:
Эта функция имеет следующие характеристики:
- Когда z=0z=0, значение равно 0,50,5.
- Поскольку zz продолжает увеличиваться, значение будет приближаться к 1
- Поскольку zz продолжает уменьшаться, значение будет приближаться к 0
Посмотрим на график функции:
Если мы подставим в функцию значения трех собственных значений X0X0, X1X1 и X2X2 выборочного пространства, мы сможем вычислить результат. Тогда этот результат будет близок к нашему результату классификации (число от 0 до 1). Если результат близок к 0, то мы рассматриваем классификацию как 0, если результат близок к 1, мы рассматриваем классификацию как 1.
Каким образом он подставляется в функцию? На самом деле можно сделать простое сложение, потому что, когда zz продолжает увеличиваться или уменьшаться, значение функции приближается к 1 или 0 соответственно. Делаем z=x0+x1+x2z=x0+x1+x2
Но реальная ситуация такова, что наши результаты расчета и фактические значения классификации будут иметь ошибки, а то и вовсе неверны. Чтобы исправить эту проблему, мы определяем коэффициент регрессии w0w0, w1w1 и w2w2 для трех собственных значений X0X0, X1X1 и X2X2 выборочного пространства, чтобы уменьшить эту ошибку. даже если z=w0x0+w1x1+w2x2
На самом деле нетрудно представить, что значение этого набора коэффициентов регрессии ww определяет точность и даже правильность результатов наших расчетов. То есть этот набор значений ww отражает правила классификации пространства выборки.
Затем, когда мы вводим данные, отличные от набора выборок, с правильным коэффициентом регрессии ww, мы можем получить результаты классификации, которые ближе к правилам классификации пространства выборки.
Вопрос снова в том, как мы можем получить такой набор коэффициентов регрессии ww?
3. Метод градиентного восхождения
Метод градиентного восхождения заключается в непрерывном итеративном вычислении значений параметров в направлении градиента функции для нахождения максимального значения параметра. Формула итерации выглядит следующим образом:
Среди них αα — размер шага, а Δσ(w)Δσ(w) — градиент функции σ(w)σ(w). Для получения градиента см.здесь. Математические способности автора ограничены и не будут объяснены.
Наконец, мы можем получить формулу для расчета градиента:
Тогда формула итерации выглядит следующим образом:
Описание формулы:
- wk+1wk+1 — результат коэффициента регрессии элемента функции XX в этой итерации.
- wkwk — результат коэффициента регрессии элемента функции XX предыдущей итерации.
- αα - размер шага каждой итерации, движущейся в направлении градиента
- xixi — i-й элемент в элементе функции XX.
- yiyi — результат выборки классификации i-й записи в выборке.
- σ(xi,wk)σ(xi,wk) — i-я запись в выборке, результат классификации вычисляется с помощью сигмовидной функции и wkwk как коэффициента регрессии
- [yi−σ(xi,wk)][yi−σ(xi,wk)] — значение результата классификации, соответствующее i-й записи выборки, и значение ошибки значения результата классификации, вычисленное сигмовидной функцией с использованием wkwk как коэффициент регрессии.
Теперь, когда у нас есть формула для расчета коэффициентов регрессии, давайте реализуем функцию в файле logRegres.py для расчета коэффициентов регрессии в пространстве выборки и печати наших результатов:
def gradAscent(dataMatIn, classLabels):
dataMatrix = mat(dataMatIn) #100行3列
#print dataMatrix
labelMat = mat(classLabels).transpose() #100行1列
#print 'labelMat:\n',labelMat
print 'labelMat 的形状:rowNum=',shape(labelMat)[0],'colNum=',shape(labelMat)[1]
rowNum,colNum = shape(dataMatrix)
alpha = 0.001
maxCycles = 500
weights = ones((colNum,1)) #3行1列
#print shape(dataMatrix)
#print shape(weights)
#print shape(labelMat)
for k in range(maxCycles): #heavy on matrix operations
h = sigmoid(dataMatrix*weights) #100行1列
#print h
error = (labelMat - h) #vector subtraction
weights = weights + alpha * dataMatrix.transpose()* error #3行1列
return weights
if __name__=='__main__':
dataMat,labelMat=loadDataSet()
#weights=gradAscent(dataMat,labelMat)
#print 'dataMat:\n',dataMat
#print 'labelMat:\n',labelMat
print weights
распечатать результат:
回归系数:
[[ 4.12414349]
[ 0.48007329]
[-0.6168482 ]]
Чтобы проверить точность наших рассчитанных ретроспективных коэффициентов, мы наблюдаем диаграмму рассеяния выборочного пространства и подобранную кривую коэффициентов регрессии. Мы используем z(x1,x2)=w0+w1x1+w2x2 в качестве нашей подгоночной функции и рисуем ее подгоночную кривую в системе координат. Используя значения X1X1 и X2X2 в пространстве выборки в качестве абсцисс и ординат, нарисуйте разброс в пространстве выборки. код показывает, как показано ниже:
def plotBestFit(weights):
import matplotlib.pyplot as plt
dataMat,labelMat=loadDataSet()
dataArr = array(dataMat)
n = shape(dataArr)[0]
xcord1 = []; ycord1 = []
xcord2 = []; ycord2 = []
for i in range(n):
if int(labelMat[i])== 1:
xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
else:
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
ax.scatter(xcord2, ycord2, s=30, c='green')
x = arange(-3.0, 3.0, 0.1)
y = (-weights[0]-weights[1]*x)/weights[2]
y = y.transpose()
ax.plot(x, y)
plt.xlabel('X1'); plt.ylabel('X2');
plt.show()
if __name__=='__main__':
dataMat,labelMat=loadDataSet()
weights=gradAscent(dataMat,labelMat)
print '回归系数:\n',weights
plotBestFit(weights)
После запуска получаем следующую картину:
По нашим наблюдениям, наш алгоритм для коэффициента регрессии является относительно точным.Подгоночная кривая делит данные выборки на две части и соответствует правилам классификации выборки.
Далее давайте реализуем классификатор и протестируем этот классификатор:
def classify0(targetData,weights):
v = sigmoid(targetData*weights)
if v>0.5:
return 1.0
else :
return 0
def testClassify0():
dataMat,labelMat=loadDataSet()
examPercent=0.7
row,col=shape(dataMat)
exam=[]
exam_label=[]
test=[]
test_label=[]
for i in range(row):
if i < row*examPercent:
exam.append(dataMat[i])
exam_label.append(labelMat[i])
else:
test.append(dataMat[i])
test_label.append(labelMat[i])
weights=gradAscent(exam,exam_label)
errCnt=0
trow,tcol=shape(test)
for i in range(trow):
v=int(classify0(test[i],weights))
if v != int(test_label[i]):
errCnt += 1
print '计算值:',v,' 原值',test_label[i]
print '错误率:',errCnt/trow
if __name__=='__main__':
#dataMat,labelMat=loadDataSet()
#weights=gradAscent(dataMat,labelMat)
##print 'dataMat:\n',dataMat
##print 'labelMat:\n',labelMat
#print '回归系数:\n',weights
#plotBestFit(weights)
testClassify0()
Реализация классификатора проста. Мы используем 70 фрагментов данных из предыдущей выборки данных в качестве выборки данных для нашего теста и вычисляем коэффициент регрессии. Затем используйте классификатор для классификации оставшихся 30 записей, а затем сравните результаты с выборочными данными. Наконец, распечатайте частоту ошибок. Как мы видим, процент ошибок равен 0, что почти идеально! Мы можем изменить пропорцию тестовой выборки в исходном пространстве выборки и протестировать ее несколько раз. Итак, вывод - точность нашего алгоритма неплохая!
Итак, здесь проблема решена? Кажется, чего-то не хватает. Давайте подробнее рассмотрим наш метод расчета коэффициентов регрессии, Нетрудно обнаружить, что в этом процессе мы выполняем матричное умножение с матрицей, составленной из выборочных данных. То есть для расчета коэффициентов регрессии мы проходим по всей выборке данных.
Наша проблема возникает снова.Выборочных данных в нашем примере всего 100. Если мы обработаем тысячи выборочных данных, вычислительная сложность нашей функции для расчета коэффициентов регрессии резко возрастет. Давайте посмотрим, как оптимизировать этот алгоритм.
В-четвертых, оптимизируйте алгоритм градиентного подъема - метод стохастического градиентного подъема.
Разбираемся с формулой итеративного расчета коэффициентов регрессии
и после программы, которую мы реализовали. Усовершенствуем метод расчета коэффициентов регрессии следующим образом:
def stocGradAscent0(dataMatrix, classLabels):
m,n = shape(dataMatrix)
alpha = 0.01
weights = ones((n,1)) #initialize to all ones
for i in range(m):
h = sigmoid(sum(dataMatrix[i]*weights))
error = classLabels[i] - h
weights = weights + alpha * error * mat(dataMatrix[i]).transpose()
return weights
Каждая итерация вычисляет коэффициенты регрессии, используя только одну точку выборки в пространстве выборки. Давайте посмотрим, насколько точен этот алгоритм, сгенерировав график выборочного разброса и подобранной кривой с помощью программы:
Нетрудно заметить, что отличие от предыдущего алгоритма все еще относительно велико. Причина в том, что предыдущий алгоритм рассчитывался за 500 итераций, последний только за 100 итераций. Тогда проблема, которую следует здесь объяснить, заключается в том, что коэффициент регрессии имеет тенденцию сходиться с увеличением числа итераций, а процесс сходимости флуктуирует. Грубо говоря, чем больше итераций, тем ближе значение, которое мы хотим, но поскольку выборочные данные нелинейны, в этом процессе будут определенные ошибки. Чтобы узнать о взаимосвязи между конкретным коэффициентом регрессии и количеством итераций, вы можете обратиться к некоторым учебникам, например к описанию в «Практике машинного обучения», которое здесь подробно не будет представлено.
Здесь мы только представляем, как улучшить наш алгоритм, чтобы наш алгоритм мог быстро сходиться и уменьшать колебания. Методы, как показано ниже:
- Каждая итерация случайным образом выбирает точку выборки для расчета вектора регрессии.
- Размер шага итерации уменьшается с количеством итераций, но никогда не равен 0.
Улучшите код и распечатайте подобранную кривую и образец диаграммы рассеяния:
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
m,n = shape(dataMatrix)
weights = ones((n,1)) #initialize to all ones
for j in range(numIter):
dataIndex = range(m)
for i in range(m):
alpha = 4/(1.0+j+i)+0.0001 #apha decreases with iteration, does not
randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant
h = sigmoid(sum(dataMatrix[randIndex]*weights))
error = classLabels[randIndex] - h
weights = weights + alpha * error * mat(dataMatrix[randIndex]).transpose()
del(dataIndex[randIndex])
return weights
if __name__=='__main__':
dataMat,labelMat=loadDataSet()
#weights=stocGradAscent0(dataMat,labelMat)
weights=stocGradAscent1(dataMat,labelMat)
#weights=gradAscent(dataMat,labelMat)
#print 'dataMat:\n',dataMat
#print 'labelMat:\n',labelMat
#print '回归系数:\n',weights
plotBestFit(weights)
#testClassify0()
По умолчанию используется 150 итераций выборочных диаграмм рассеяния и построенных кривых:
Нетрудно заметить, что точность очень близка к первому алгоритму!
V. Резюме
Алгоритм логистической регрессии в основном использует функцию Sgimoid для классификации данных Ключ к точности классификации зависит от коэффициентов регрессии, рассчитанных из выборочного пространства. Мы используем градиентное восхождение для расчета коэффициентов регрессии и стохастическое градиентное восхождение для повышения производительности алгоритма.
1 лайксобиратьКомментарий