1,逻辑回归的定义
简单来说, 逻辑回归(Logistic Regression)是一种用于解决二分类(0 or 1)问题的机器学习方法,用于估计某种事物的可能性。比如某用户购买某商品的可能性,某病人患有某种疾病的可能性,以及某广告被用户点击的可能性等。 注意,这里用的是“可能性”,而非数学上的“概率”,logisitc回归的结果并非数学定义中的概率值,不可以直接当做概率值来用。该结果往往用于和其他特征值加权求和,而非直接相乘。
那么逻辑回归与线性回归是什么关系呢?
逻辑回归(Logistic Regression)与线性回归(Linear Regression)都是一种广义线性模型(generalized linear model)。逻辑回归假设因变量 y 服从伯努利分布,而线性回归假设因变量 y 服从高斯分布。 因此与线性回归有很多相同之处,去除Sigmoid映射函数的话,逻辑回归算法就是一个线性回归。可以说,逻辑回归是以线性回归为理论支持的,但是逻辑回归通过Sigmoid函数引入了非线性因素,因此可以轻松处理0/1分类问题。
2,Logistic 回归的一般过程
收集数据:采用任意方式收集数据
准备数据:由于需要进行距离计算,因此要求数据类型为数值型,另外,结构化数据格式更佳
分析数据:采用合适的方式对数据进行分析(比如可视化、数据的简单处理等)
训练算法:大部分时间用于训练,训练的目的是为了找到最佳的分类回归系数
测试算法:一旦训练完成,分类将会很快
3,Logistic算法优缺点
优点:计算代价不高,易于理解和实现。
缺点:容易欠似合,分类的精度不高。
范围:数值型和标量型数据。
4,基于Logistic回归和Sigmoid函数
Sigmoid函数是单位阶越函数。
在数学上比较容易处理。
在数据量比较大的时候,跨度大;数据量小的时候,跨度平稳。
5,基于最优化方法的回归系数确定
Sigmoid 函数的输入记为 z ,由下面公式得到:
如果采用向量的写法,上述公式可以写成z=wTx, ,它表示将这两个数值向量对应元素相乘然后全部加起来即得到 z 值。其中的向量 x 是分类器的输入数据,向量 w 也就是我们要找到的最佳参数(系数),从而使得分类器尽可能地精确。为了寻找该最佳参数,需要用到最优化理论的一些知识。我们这里使用的是——梯度上升法。
5.1 梯度的介绍
向量 = 值 + 方向
梯度 = 向量
梯度 = 梯度值 + 梯度方
5.2 梯度上升法的思想
要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。如果梯度记为 ▽ ,则函数 f(x, y) 的梯度由下式表示:
5.3 梯度下降法
梯度下降法用来计算函数的最小值,在梯度下降算法中,梯度算子总是向函数值增长最慢的方向。
。
代码实现
1,testSet.txt数据
-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
2,实现代码
from numpy import *
import matplotlib.pyplot as plt
def loadDataSet():
dataMat = [];
labelMat = []
fr = open('testSet.txt') ##打开文本
for line in fr.readlines(): ##逐行读取,每行前两个值为X1和X2,第三个值是数据对应的标签,将X0的值设置为1
lineArr = line.strip().split()
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) ##
labelMat.append(int(lineArr[2]))
return dataMat, labelMat
##定义sigmoid函数
def sigmoid(inX):
return 1.0 / (1 + exp(-inX))
##梯度下降法
def gradAscent(dataMatIn, classLabels):
dataMatrix = mat(dataMatIn) # 原始数据转化为矩阵
labelMat = mat(classLabels).transpose() # 标签数据转化为矩阵
m, n = shape(dataMatrix)
alpha = 0.001
maxCycles = 500 ##迭代次数500
weights = ones((n, 1)) ##初始化参数为1
temp = []
for k in range(maxCycles):
h = sigmoid(dataMatrix * weights) # 预测值
error = (labelMat - h) # 向量
weights = weights + alpha * dataMatrix.transpose() * error # matrix mult
return weights
##画出数据集和logistic回归最佳拟合直线
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标签值为1
xcord1.append(dataArr[i, 1]);
ycord1.append(dataArr[i, 2])
else:
xcord2.append(dataArr[i, 1]);
ycord2.append(dataArr[i, 2]) ##xcord2标签值为0
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] ##0为两类的分界处,故假定0=w0x0+w1x1+w2x2,x0=1
y = y.transpose()
ax.plot(x, y)
plt.xlabel('X1');
plt.ylabel('X2')
plt.show()
##随机
def stocGradAscent0(dataMatrix, classLabels):
m, n = shape(dataMatrix)
alpha = 0.01
weights = ones(n) # initialize to all ones
for i in range(m):
h = sigmoid(sum(dataMatrix[i] * weights))
error = classLabels[i] - h ##数值
weights = weights + alpha * error * dataMatrix[i]
return weights
##改进的随机梯度上升算法
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
m, n = shape(dataMatrix)
weights = ones(n) # 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 # 改变步长
randIndex = int(random.uniform(0, len(dataIndex))) # 随机选取样本,减少周期性的波动
h = sigmoid(sum(dataMatrix[randIndex] * weights))
error = classLabels[randIndex] - h ##数值型,float64
weights = weights + alpha * error * array(dataMatrix[randIndex]) ##参数更新
del (list(dataIndex)[randIndex]) ##删除该值进行下一次迭代
return weights
if __name__ == '__main__':
dataMat, labelMat = loadDataSet()
# weights = gradAscent(dataMat,labelMat) ##梯度下降算法回归系数
weights1 = stocGradAscent1(dataMat, labelMat) ##改进随机梯度下降算法回归系数
# plotBestFit(weights) ##画出梯度下降算法在数据集上的拟合直线
plotBestFit(weights1) ##画出改进随机梯度下降算法在数据集上的拟合直线