当前位置:   article > 正文

logistics回归分析+代码详解_logistics模型代码

logistics模型代码

目录

1.2 Logistic 回归的引入

1.3 分类预测函数问题的转化成求θ

1.4 梯度下降法求解θ

2.3 利用随机梯度上升法训练样本


1.2 Logistic 回归的引入

Logistic 回归是概率非线性模型,用于处理二元分类结果,名为回归实为分类。下面给出一个二元分类的例子,如下图所示:

图中数据分成两类,打叉的一类用 y = 1 表示,另一类为圆圈用 y= 0 表示。现在我们要对数据进行分类,要找到一个分类函数(边界线),我们很容易得出一个线性函数对其分类:z = θ0 + θ1x1 + θ2x2 。但我们想要的函数应该是,能接受所有的输入然后预测类别。例如:在两个分类的情况下,函数输出 0 或 1。因此,我们就需要引入Sigmoid 函数,这个函数的性质可以满足要求。Sigmoid 函数:

Sigmoid 函数的值域为(0,1),且具有良好的从0 到 1 的跳跃性,如在两个不同的坐标尺度下的函数图形:

所以,我们把线性方程和Sigmoid 函数结合起来就能解决问题。即 :分类预测函数 hθ (x) = g( θ0 + θ1x1 + θ2x2) .我们就可以对样本数据进行分类,如下图所示:



其中,θT 是向量 θ (θ0, θ1,... ,θn) 的转置,向量 x是 ( x0 , x1 ,... , xn),x0 =1,这是便于计算。

1.3 分类预测函数问题的转化成求θ

 通过上面的分析,我们得出了分类预测函数 hθ(x) , 但其中向量 x 是已知的,向量 θ 未知,即我们把求分类函数问题转化成求向量 θ 。
因为Sigmoid 函数的取值区间(0,1),那我们可以看做概率 P(y = 1 | xi ; θ)= hθ(x) , 表示在 xi 确定的情况下,类别 y = 1 的概率。
由此我们也可以得出在 xi 确定的情况下,类别 y = 0 的概率  P(y = 0 | xi ; θ)= 1 -  P(y = 1 | xi ; θ)= 1 - hθ(x) . 即 :

我们可以将这两个式子合并得:(其中的 y = 0 或 1 ):类别为0或1 的概率函数

这时候我们可以利用最大似然函数对向量 θ 求值,可以理解为选取的样本数据的概率是最大的

①那么样本数为 m 的似然函数为:(概率分布函数的联合分布密度)

②通过对数的形式对似然函数进行变化,对数似然函数

此时我们不求解似然方程,而是利用梯度下降法。
这里的最大似然函数的值就是我们所要求的向量 θ , 而求解的方法利用梯度下降法。

1.4 梯度下降法求解θ

 在用梯度下降法时,我们将会利用Sigmoid 函数的一个性质: g, (z) = g(z)[ 1- g(z) ] 。

构造一个Cost函数(损失函数),该函数表示预测的输出(h)与训练数据类别(y)之间的偏差。综合考虑所有训练数据的“损失”,将Cost求和或者求平均,记为J(θ)函数(代价函数),表示所有训练数据预测值与实际类别的偏差。

损失函数:


J(θ)代价函数:

其中,x(i) 每个样本数据点在某一个特征上的值,即特征向量x的某个值,y(i) 是类别号,m 是样本对象个数。

梯度下降法含义:

梯度下降法,就是利用负梯度方向来决定每次迭代的新的搜索方向,使得每次迭代能使待优化的目标函数逐步减小。梯度其实就是函数的偏导数

这里对用梯度下降法对 J (θ) 求最小值,与求似然函数的最大值是一样的。则 J(θ) 最小值的求解过程:

其中 α 是步长。
具体步骤为:

这就是一开始,我对代码中公式困惑的地方。在这里我在补充一点,以上的梯度下降法可以认为是批量梯度下降法(Batch Gradient Descent),由于我们有m个样本,这里求梯度的时候就用了所有m个样本的梯度数据。下面介绍随机梯度下降法(Stochastic Gradient Descent):

 随机梯度下降法,其实和批量梯度下降法原理类似,区别在与求梯度时没有用所有的m个样本的数据,而是仅仅选取一个样本j来求梯度。随机梯度下降法,和批量梯度下降法是两个极端,一个采用所有数据来梯度下降,一个用一个样本来梯度下降。自然各自的优缺点都非常突出。
对于训练速度来说,随机梯度下降法由于每次仅仅采用一个样本来迭代,训练速度很快,而批量梯度下降法在样本量很大的时候,训练速度不能让人满意。
对于准确度来说,随机梯度下降法用于仅仅用一个样本决定梯度方向,导致解很有可能不是最优。
对于收敛速度来说,由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快的收敛到局部最优解。公式为:

到这里已经把Logistics 回归的原理推导完成。这里对以上推导做一次总结:

 二分类边界线 要利用—> Sigmoid 函数 ——>要求向量 θ在 xi 确定的情况下求类别 y = 0、1 的概率—> P(y | x ; θ)  —— > 似然函数  得到—> 损失函数——>代价函数 J (θ) ——> 梯度下降法求解向量 θ ——> 最终公式 θj

步骤简略公式为:




2 使用python 实现Logistic 回归

  1. from numpy import *
  2. import matplotlib.pyplot as plt
  3. ######################################################读取数据############################################################
  4. def loadDataSet():
  5. '''数据集的前两个值分别为X1和X2,第三个值是数据对应的类别标签,为了方便计算,把X0的值设置成了1.0'''
  6. dataMat = []
  7. labelMat = []
  8. fr = open('testSet.txt')
  9. for line in fr.readlines():
  10. lineArr = line.strip().split() #按行读取并按空格拆分,每一行为一个列表, ['-0.017612', '14.053064', '0']
  11. # 为了方便计算,我们将 X0 的值设为 1.0 ,也就是在每一行的开头添加一个 1.0 作为 X0
  12. # 因为线性回归化式为 H(x) = W0 + W1*X1 + W2*X2,即为 (W0, W1, W2)*(1.0, X1, X2),其中 (W0, W1, W2) 即为所求回归系数 W,所以模拟了一个数据列全为1.0
  13. dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
  14. #[[1.0, -0.017612, 14.053064], [1.0, -1.395634, 4.662541],........]含有100个元素的列表,每一个元素都为一个列表,包含3个元素
  15. labelMat.append(int(lineArr[2])) #100个元素(类别标签)的列表
  16. return dataMat, labelMat
  17. ################################################分类器的分类(转换)函数#####################################################
  18. def sigmoid(inX):
  19. return 1.0 / (1 + exp(-inX))
  20. ################################### 梯度上升算法,用来计算出最佳回归系数w(weights)#############################################
  21. #输入数据特征与数据的类别标签,dataMatIn存放的是100*3的矩阵
  22. """
  23. 第一个参数(dataMatIn)是3维数组,每列代表每个不同特征,每行代表每个训练样本
  24. 第二个参数(labelMat)是类别标签,1*100的行向量,为便于计算,将其转换为列向量,即进行转置,并赋值给labelMat
  25. 转化矩阵[[0,1,0,1,0,1.....]]为[[0],[1],[0].....]
  26. """
  27. def gradAscent(dataMatIn, classLabels):
  28. dataMatrix = mat(dataMatIn) #转为100*3的矩阵 [ 1.0000000e+00 -1.7612000e-02 1.4053064e+01]
  29. labelMat = mat(classLabels).transpose() #转为100*1的矩阵,transpose() 行列转置函数,将行向量转化为列向量 => 矩阵的转置
  30. # m->数据量、样本数100 n->特征数3
  31. m, n = shape(dataMatrix)# shape()函数是numpy.core.fromnumeric中的函数,它的功能是查看矩阵或者数组的维数
  32. alpha = 0.001 # 步长,向函数增长最快的方向的移动量,即学习率
  33. maxCycles = 500# 迭代次数
  34. weights = ones((n, 1)) # 转为3*1的矩阵,元素为1的矩阵赋给weihts,即回归系数初始化为1
  35. # 循环 maxCycles次, 每次都沿梯度向真实值 labelMat 靠拢
  36. for k in range(maxCycles):
  37. # 求当前sigmoid函数的值
  38. h = sigmoid(dataMatrix * weights) # 矩阵相乘 包含了300次的乘积 [100*3] * [3*1] = [100*1]
  39. error = (labelMat - h) # 向量减法,计算真实类别与预测类别的差值,h是一个列向量,列向量的元素个数等于样本数,即为100
  40. weights = weights + alpha * dataMatrix.transpose() * error # 矩阵相乘,dataMatrix.transpose()* error 就是梯度f(w),按照该差值的方向调整回归系数
  41. return weights
  42. ###################################################分析数据:画出决策边界####################################################
  43. # 画出数据集和Logistic回归最佳拟合直线
  44. def plotBestFit(weights):
  45. dataMat, labelMat = loadDataSet()
  46. dataArr = array(dataMat)
  47. n = shape(dataArr)[0] # n->数据量、样本数
  48. # xcord1,ycord1代表正例特征1,正例特征2
  49. # xcord2,ycord2代表负例特征1,负例特征2
  50. xcord1 = []; ycord1 = []
  51. xcord2 = []; ycord2 = []
  52. # 循环筛选出正负集
  53. for i in range(n):
  54. if int(labelMat[i]) == 1:
  55. xcord1.append(dataArr[i, 1]); ycord1.append(dataArr[i, 2])
  56. else:
  57. xcord2.append(dataArr[i, 1]); ycord2.append(dataArr[i, 2])
  58. fig = plt.figure()
  59. # “111”表示“1×1网格,第一子图”,“234”表示“2×3网格,第四子图”。
  60. ax = fig.add_subplot(111)
  61. ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
  62. ax.scatter(xcord2, ycord2, s=30, c='green')
  63. # 画线
  64. # 设定边界直线x和y的值,并且以0.1为步长从-3.0到3.0切分。
  65. x = arange(-3.0, 3.0, 0.1)#[-3.000000000 -2.90000000 -2.80000000 -2.70000000
  66. """
  67. y的由来?
  68. 首先理论上是这个样子的:
  69. dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
  70. w0*x0+w1*x1+w2*x2=f(x)
  71. x0最开始就设置为1, x2就是我们画图的y值。0是两个类别的分界处
  72. 所以: w0+w1*x+w2*y=0 => y = (-w0-w1*x)/w2
  73. """
  74. y = (-weights[0] - weights[1] * x) / weights[2] #最佳拟合直线
  75. ax.plot(x, y)
  76. plt.xlabel('X1');
  77. plt.ylabel('X2');
  78. plt.show()
  79. # 输出运用梯度上升优化算法后得到的最理想的回归系数的值
  80. if __name__ =='__main__':
  81. dataArr,labelMat=loadDataSet()
  82. weights=gradAscent(dataArr,labelMat)
  83. plotBestFit(weights.getA())

数据集为

  1. -0.017612 14.053064 0
  2. -1.395634 4.662541 1
  3. -0.752157 6.538620 0
  4. -1.322371 7.152853 0
  5. 0.423363 11.054677 0
  6. 0.406704 7.067335 1
  7. 0.667394 12.741452 0
  8. -2.460150 6.866805 1
  9. 0.569411 9.548755 0
  10. -0.026632 10.427743 0
  11. 0.850433 6.920334 1
  12. 1.347183 13.175500 0
  13. 1.176813 3.167020 1
  14. -1.781871 9.097953 0
  15. -0.566606 5.749003 1
  16. 0.931635 1.589505 1
  17. -0.024205 6.151823 1
  18. -0.036453 2.690988 1
  19. -0.196949 0.444165 1
  20. 1.014459 5.754399 1
  21. 1.985298 3.230619 1
  22. -1.693453 -0.557540 1
  23. -0.576525 11.778922 0
  24. -0.346811 -1.678730 1
  25. -2.124484 2.672471 1
  26. 1.217916 9.597015 0
  27. -0.733928 9.098687 0
  28. -3.642001 -1.618087 1
  29. 0.315985 3.523953 1
  30. 1.416614 9.619232 0
  31. -0.386323 3.989286 1
  32. 0.556921 8.294984 1
  33. 1.224863 11.587360 0
  34. -1.347803 -2.406051 1
  35. 1.196604 4.951851 1
  36. 0.275221 9.543647 0
  37. 0.470575 9.332488 0
  38. -1.889567 9.542662 0
  39. -1.527893 12.150579 0
  40. -1.185247 11.309318 0
  41. -0.445678 3.297303 1
  42. 1.042222 6.105155 1
  43. -0.618787 10.320986 0
  44. 1.152083 0.548467 1
  45. 0.828534 2.676045 1
  46. -1.237728 10.549033 0
  47. -0.683565 -2.166125 1
  48. 0.229456 5.921938 1
  49. -0.959885 11.555336 0
  50. 0.492911 10.993324 0
  51. 0.184992 8.721488 0
  52. -0.355715 10.325976 0
  53. -0.397822 8.058397 0
  54. 0.824839 13.730343 0
  55. 1.507278 5.027866 1
  56. 0.099671 6.835839 1
  57. -0.344008 10.717485 0
  58. 1.785928 7.718645 1
  59. -0.918801 11.560217 0
  60. -0.364009 4.747300 1
  61. -0.841722 4.119083 1
  62. 0.490426 1.960539 1
  63. -0.007194 9.075792 0
  64. 0.356107 12.447863 0
  65. 0.342578 12.281162 0
  66. -0.810823 -1.466018 1
  67. 2.530777 6.476801 1
  68. 1.296683 11.607559 0
  69. 0.475487 12.040035 0
  70. -0.783277 11.009725 0
  71. 0.074798 11.023650 0
  72. -1.337472 0.468339 1
  73. -0.102781 13.763651 0
  74. -0.147324 2.874846 1
  75. 0.518389 9.887035 0
  76. 1.015399 7.571882 0
  77. -1.658086 -0.027255 1
  78. 1.319944 2.171228 1
  79. 2.056216 5.019981 1
  80. -0.851633 4.375691 1
  81. -1.510047 6.061992 0
  82. -1.076637 -3.181888 1
  83. 1.821096 10.283990 0
  84. 3.010150 8.401766 1
  85. -1.099458 1.688274 1
  86. -0.834872 -1.733869 1
  87. -0.846637 3.849075 1
  88. 1.400102 12.628781 0
  89. 1.752842 5.468166 1
  90. 0.078557 0.059736 1
  91. 0.089392 -0.715300 1
  92. 1.825662 12.693808 0
  93. 0.197445 9.744638 0
  94. 0.126117 0.922311 1
  95. -0.679797 1.220530 1
  96. 0.677983 2.556666 1
  97. 0.761349 10.693862 0
  98. -2.168791 0.143632 1
  99. 1.388610 9.341997 0
  100. 0.317029 14.739025 0

2.3 利用随机梯度上升法训练样本

  1. from numpy import *
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. ######################################################读取数据############################################################
  5. def loadDataSet():
  6. '''数据集的前两个值分别为X1和X2,第三个值是数据对应的类别标签,为了方便计算,把X0的值设置成了1.0'''
  7. dataMat = []
  8. labelMat = []
  9. fr = open('testSet.txt')
  10. for line in fr.readlines():
  11. lineArr = line.strip().split() #按行读取并按空格拆分,每一行为一个列表, ['-0.017612', '14.053064', '0']
  12. # 为了方便计算,我们将 X0 的值设为 1.0 ,也就是在每一行的开头添加一个 1.0 作为 X0
  13. # 因为线性回归化式为 H(x) = W0 + W1*X1 + W2*X2,即为 (W0, W1, W2)*(1.0, X1, X2),其中 (W0, W1, W2) 即为所求回归系数 W,所以模拟了一个数据列全为1.0
  14. dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
  15. #[[1.0, -0.017612, 14.053064], [1.0, -1.395634, 4.662541],........]含有100个元素的列表,每一个元素都为一个列表,包含3个元素
  16. labelMat.append(int(lineArr[2])) #100个元素(类别标签)的列表
  17. return dataMat, labelMat
  18. ################################################分类器的分类(转换)函数#####################################################
  19. def sigmoid(inX):
  20. return 1.0 / (1 + exp(-inX))
  21. def stocGradAscent1(dataMatrix, classLabels, numIter=150):
  22. dataMatrix = np.array(dataMatrix)
  23. m, n = np.shape(dataMatrix) # 返回dataMatrix的大小。m为行数,n为列数。
  24. weights = np.ones(n) # 参数初始化
  25. for j in range(numIter):
  26. dataIndex = list(range(m))
  27. for i in range(m):
  28. alpha = 4 / (1.0 + j + i) + 0.01 # 降低alpha的大小,每次减小1/(j+i)。
  29. randIndex = int(random.uniform(0, len(dataIndex))) # 随机选取样本
  30. h = sigmoid(sum(dataMatrix[randIndex] * weights)) # 选择随机选取的一个样本,计算h
  31. error = classLabels[randIndex] - h # 计算误差
  32. weights = weights + alpha * error * dataMatrix[randIndex] # 更新回归系数
  33. del (dataIndex[randIndex]) # 删除已经使用的样本
  34. return weights # 返回
  35. ###################################################分析数据:画出决策边界####################################################
  36. # 画出数据集和Logistic回归最佳拟合直线
  37. def plotBestFit(weights):
  38. dataMat, labelMat = loadDataSet()
  39. dataArr = array(dataMat)
  40. n = shape(dataArr)[0] # n->数据量、样本数
  41. # xcord1,ycord1代表正例特征1,正例特征2
  42. # xcord2,ycord2代表负例特征1,负例特征2
  43. xcord1 = []; ycord1 = []
  44. xcord2 = []; ycord2 = []
  45. # 循环筛选出正负集
  46. for i in range(n):
  47. if int(labelMat[i]) == 1:
  48. xcord1.append(dataArr[i, 1]); ycord1.append(dataArr[i, 2])
  49. else:
  50. xcord2.append(dataArr[i, 1]); ycord2.append(dataArr[i, 2])
  51. fig = plt.figure()
  52. # “111”表示“1×1网格,第一子图”,“234”表示“2×3网格,第四子图”。
  53. ax = fig.add_subplot(111)
  54. ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
  55. ax.scatter(xcord2, ycord2, s=30, c='green')
  56. # 画线
  57. # 设定边界直线x和y的值,并且以0.1为步长从-3.0到3.0切分。
  58. x = arange(-3.0, 3.0, 0.1)#[-3.000000000 -2.90000000 -2.80000000 -2.70000000
  59. """
  60. y的由来?
  61. 首先理论上是这个样子的:
  62. dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
  63. w0*x0+w1*x1+w2*x2=f(x)
  64. x0最开始就设置为1, x2就是我们画图的y值。0是两个类别的分界处
  65. 所以: w0+w1*x+w2*y=0 => y = (-w0-w1*x)/w2
  66. """
  67. y = (-weights[0] - weights[1] * x) / weights[2] #最佳拟合直线
  68. ax.plot(x, y)
  69. plt.xlabel('X1');
  70. plt.ylabel('X2');
  71. plt.show()
  72. # 输出运用梯度上升优化算法后得到的最理想的回归系数的值
  73. if __name__ =='__main__':
  74. dataArr,labelMat=loadDataSet()
  75. weights=stocGradAscent1(dataArr,labelMat)
  76. plotBestFit(weights)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/629949
推荐阅读
相关标签
  

闽ICP备14008679号