内容来源于书《机器学习实战》
# *-* coding: utf-8 *-*
'''
<<机器学习实战>>---读书笔记: 第5章 Logistic回归
回归:用直线对点进行拟合的过程
利用回归分类主要思想:根据现有数据对分类边界线建立回归公式,进行分类
回归:最佳拟合,需要找到最佳拟合参数集
训练分类器:寻找最佳拟合参数,使用最优化算法
Logistic回归过程:
准备数据:需要距离运算,要求数据类型为数值型
优点:计算代价不高
缺点:容易欠拟合
适用:数值型和标称型数据
Sigmod函数
f(x)=1/(1 + e^(-x))
f(x)范围:0到1
把大于0.5的数据分入到1类,把小于0.5的数据归入0类
基于最优化方法的最佳回归系数确定
z=W0*X0 + W1*X1 + ... + Wn*Xn
采用向量写法: z=W^T * X
将这两个数值向量对应元素相乘后全部加起来得到z值。
向量X:输入数据
向量W:最佳参数
梯度上升法:
思想:找到函数最大值,最好方法是沿着该函数的梯度方向探寻,记梯度为V
f(x,y)的梯度如下表示
Vf(x,y)=[af(x,y) / ax]
[af(x,y) / ay]
该梯度意味着:要沿着x的方向移动 af(x,y) / ax,沿着y的方向移动af(x,y) / ay
函数f(x,y)必须在待计算的点上有定义且可微
梯度算子总指向函数值增长最快的方向
移动量=步长=e
梯度上升算法迭代公式:
w:= w + e * Vwf(W)
公式一直迭代运行,直到达到某停止条件或达到某指定值或允许误差范围内
梯度下降: w:= w - e * Vwf(W)
梯度上升过程:
每个回归系数初始化为1
重复R次:
计算整个数据集的梯度
使用alpha * gradient更新回归系数的向量
返回回归系数
'''
from math import *
from numpy import *
def loadDataSet():
dataSet = []
labels = []
fr = open("testSet.txt")
for line in fr.readlines():
words = line.strip().split()
dataSet.append([1.0 , float(words[0]) , float(words[1])])
labels.append(int(words[2]))
return dataSet , labels
# f(x)=1/(1 + e^(-x))
def sigmoid(inX):
return 1.0/(1 + exp(-inX))
#梯度上升
def gradAscent(dataSet , labels):
dataMatrix = mat(dataSet)
labelMatrix = mat(labels).transpose()
rows , cols = shape(dataMatrix)
alpha = 0.001
times = 500
weights = ones((cols , 1))
for k in range(times):
h = sigmoid( dataMatrix * weights)
error = (labelMatrix - h)
weights = weights + alpha * dataMatrix.transpose() * error
return weights
def gradAscent_test():
dataSet , labels = loadDataSet()
weights = gradAscent(dataSet , labels)
print(weights)
plotBestFit(weights)
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]
# pl.plot(x, y)改成pl.plot(x, y, 'o')
ax.plot(x, y)
plt.xlabel('X1'); plt.ylabel('X2');
plt.show()
if __name__ == "__main__":
gradAscent_test()