当前位置:   article > 正文

机器学习-逻辑回归_负二项回归

负二项回归

机器学习-逻辑回归

本节简单介绍逻辑回归(Logistic Regression)的原理以及Python实现,包含以下内容,

  1. 概念
  2. Sigmoid函数
  3. 梯度上升算法
  4. Python实现
  5. 随机梯度上升算法

部分内容引用自《Machine Learning in Action》


概念

逻辑回归(Logistic Regression)是一种用于解决二分类问题的机器学习算法,用于估计某种事物的可能性。比如某病人患有某种疾病的可能性,某个员工是否离职的可能性,今天是否下雨的可能性等等。 注意,这里用的是“可能性”不是数学上的“概率”,逻辑回归的结果并非数学定义中的概率值,不可以直接当做概率值来用。

逻辑回归与多重线性回归实际上有很多相同之处,最大的区别就在于它们的因变量不同,其他的基本都差不多。正是因为如此,这两种回归可以归于同一个家族,即广义线性模型(generalizedlinear model)。

这一家族中的模型形式基本上都差不多,不同的就是因变量不同。

  • 如果是连续的,就是多重线性回归
  • 如果是二项分布,就是Logistic回归
  • 如果是Poisson分布,就是Poisson回归
  • 如果是负二项分布,就是负二项回归

逻辑回归的主要用途:

  • 寻找危险因素:寻找某一疾病的危险因素等
  • 预测:根据模型,预测在不同的自变量情况下,发生某病或某种情况的概率有多大
  • 判别:实际上跟预测有些类似,也是根据模型,判断某人属于某病或属于某种情况的概率有多大,也就是看一下这个人有多大的可能性是属于某病

逻辑回归主要在流行病学中应用较多,比较常用的情形是探索某疾病的危险因素,根据危险因素预测某疾病发生的概率,等等。例如,想探讨胃癌发生的危险因素,可以选择两组人群,一组是胃癌组,一组是非胃癌组,两组人群肯定有不同的体征和生活方式等。这里的因变量就是是否胃癌,即“是”或“否”,自变量就可以包括很多了,例如年龄、性别、饮食习惯、幽门螺杆菌感染等。自变量既可以是连续的,也可以是分类的。

Sigmoid函数

Sigmoid函数又叫激活函数,其函数表达式如下:

函数图像:

可知其定义域为全体实数,值域为(0, 1),Sigmoid函数的作用是将任何实数映射到(0, 1)。

逻辑回归的假设函数如下:

所以,

其中,\large x是输入,即特征值,\large \theta是待求的回归系数。

一个机器学习的模型,实际上是把决策函数限定在某一组条件下,这组限定条件就决定了模型的假设空间。当然,我们还希望这组限定条件简单而合理。而逻辑回归模型所做的假设是,

其含义是给定\large x\large \theta的情况下,求\large y=1的概率。如果得到的概率值大于0.5,则我们可以认为某元素属于\large y=1的类型,否则属于另一个类型。注意,阈值的选择不一定是0.5,可以根据实际情况调整。例如,判断某人是否患上肿瘤,我们可以将阈值设置为0.3,即只要大于0.3我们就认为其有一定的可能性患病,需要做一个全面检查。

逻辑回归要求我们根据一系列的学习样本(即上面公式中的\large x,多维矩阵)得到一个\large \theta向量,然后来预测新的元素分类。我们可以通过梯度上升算法来求解\large \theta向量。

梯度上升算法

梯度上升算法用于求解函数的最大值,梯度下降算法用于求解函数的最小值,其原理都一样。因为逻辑回归中求解的是某个元素属于某个分类的最大可能性,求解的是最大值,因此需要使用梯度上升算法。公式:

其中,\large \alpha是步长,\large \frac{\partial f(X_{i})) }{X_{i}}是梯度,也就是偏导数组成的向量,表示\large X应该沿此方向运动方能取到最大值。下面举一个实例,

求以下函数的最大值:

\large f(x) = -x^{2} + 2x + 2

函数图像:

可知,当\large x=1时取最大值为\large y=3

下面通过Python实现梯度上升算法,

  1. import math
  2. def f(x):
  3. return -x * x + 2 * x + 2
  4. def ff(x):
  5. return -2 * x + 2
  6. def gradient_ascent(x_0=1, steps=0.1):
  7. while True:
  8. x_1 = x_0 + ff(x_0) * steps
  9. if math.fabs(x_0 - x_1) <= 0.000001:
  10. return x_1
  11. x_0 = x_1
  12. x = gradient_ascent(-1)
  13. print("Max value x: %r" % x)
  14. print("Max value y: %r" % f(x))

运行结果:

  1. D:\work\python_workspace\machine_learning\venv\Scripts\python.exe D:/work/python_workspace/machine_learning/logistic_regression/gradient_ascent.py
  2. Max value x: 0.9999961687611478
  3. Max value y: 2.9999999999853215
  4. Process finished with exit code 0

上面例子中只有一个自变量\large x,代表一个特征,在逻辑回归的实际应用中往往有很多特征,因此我们需要多个自变量。多自变量的梯度上升公式需要一些数学推导,这里就不拷贝粘贴了,可以参考其它文章,这里仅给出公式:

Python实现

数据集文件:test_set.txt,

  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

创建模块 log_regres.py,并输入以下代码:

  1. import numpy as np
  2. def load_data():
  3. data_mat = []
  4. label_mat = []
  5. with open('test_set.txt') as f:
  6. for line in f.readlines():
  7. line_array = line.strip().split()
  8. data_mat.append([1.0, float(line_array[0]), float(line_array[1])])
  9. label_mat.append(int(line_array[2]))
  10. return data_mat, label_mat
  11. def sigmoid(in_X):
  12. return 1.0 / (1 + np.exp(-in_X))
  13. def grad_ascent(data_mat_in, class_labels):
  14. data_matrix = np.mat(data_mat_in)
  15. label_mat = np.mat(class_labels).transpose()
  16. m, n = np.shape(data_matrix)
  17. alpha = 0.001
  18. max_cycles = 500
  19. weights = np.ones((n, 1))
  20. for k in range(max_cycles):
  21. h = sigmoid(data_matrix * weights)
  22. error = label_mat - h
  23. weights = weights + alpha * data_matrix.transpose() * error
  24. return weights
  25. if __name__ == '__main__':
  26. data, label = load_data()
  27. weight = grad_ascent(data, label)
  28. print(weight)

输出结果:

  1. D:\work\python_workspace\machine_learning\venv\Scripts\python.exe D:/work/python_workspace/machine_learning/logistic_regression/log_regres.py
  2. [[ 4.12414349]
  3. [ 0.48007329]
  4. [-0.6168482 ]]
  5. Process finished with exit code 0

因此,该逻辑回归的决策函数为:

\large z = 4.12414349 + 0.48007329 * x_{1} -0.6168482 * x_{2}

下面我们根据该决策函数画出决策边界,创建模块 plot_best_fit.py,并输入以下代码:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import logistic_regression.log_regres as lr
  4. def plot_best_fit(weights):
  5. data, label = lr.load_data()
  6. data_array = np.array(data)
  7. n = np.shape(data_array)[0]
  8. xcord1 = []
  9. ycord1 = []
  10. xcord2 = []
  11. ycord2 = []
  12. for i in range(n):
  13. if int(label[i]) == 1:
  14. xcord1.append(data_array[i, 1])
  15. ycord1.append(data_array[i, 2])
  16. else:
  17. xcord2.append(data_array[i, 1])
  18. ycord2.append(data_array[i, 2])
  19. fig = plt.figure()
  20. ax = fig.add_subplot(111)
  21. ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
  22. ax.scatter(xcord2, ycord2, s=30, c='green')
  23. x = np.arange(-3.0, 3.0, 0.1)
  24. y = (-weights[0] - weights[1] * x) / weights[2]
  25. ax.plot(x, np.array(y)[0])
  26. plt.xlabel('X1')
  27. plt.ylabel('X2')
  28. plt.show()
  29. if __name__ == '__main__':
  30. data, label = lr.load_data()
  31. weights = lr.grad_ascent(data, label)
  32. plot_best_fit(weights)

运行结果:

注意,令上面的决策函数等于0,也就是设定0.5为决策阈值,即可得到\large x_{1}\large x_{2}的关系式,

\large x_{2} = \frac{4.12414349 + 0.48007329 * x_{1}}{0.6168482}

随机梯度上升算法

上面的梯度算法需要进行大量的计算,在样本点和特征值很多的情况下会有一定的性能问题,我们可以通过随机梯度算法进行优化。随机梯度算法和一般梯度算法类似,只是每次计算时是随机的从样本中选取一个样本点,而不是像一般梯度算法中每次迭代时把所有样本点都计算一次。且随机梯度算法每次迭代时都要逐渐减小步长。

创建模块 stoc_grad_ascent1.py,并输入以下代码:

  1. import numpy as np
  2. import random
  3. import matplotlib.pyplot as plt
  4. import logistic_regression.log_regres as lr
  5. import logistic_regression.plot_best_fit as pf
  6. def stoc_grad_ascent1(data_matrix, class_label, num_iter=150):
  7. m, n = np.shape(data_matrix)
  8. weights = np.ones(n)
  9. for j in range(num_iter):
  10. data_index = list(range(m))
  11. for i in range(m):
  12. alpha = 4 / (1.0 + j + i) + 0.01
  13. rand_index = int(random.uniform(0, len(data_index)))
  14. h = lr.sigmoid(np.sum(data_matrix[rand_index] * weights))
  15. error = class_label[rand_index] - h
  16. weights = weights + alpha * error * data_matrix[rand_index]
  17. del (data_index[rand_index])
  18. return weights
  19. def plot_best_fit(weights):
  20. data, label = lr.load_data()
  21. data_array = np.array(data)
  22. n = np.shape(data_array)[0]
  23. xcord1 = []
  24. ycord1 = []
  25. xcord2 = []
  26. ycord2 = []
  27. for i in range(n):
  28. if int(label[i]) == 1:
  29. xcord1.append(data_array[i, 1])
  30. ycord1.append(data_array[i, 2])
  31. else:
  32. xcord2.append(data_array[i, 1])
  33. ycord2.append(data_array[i, 2])
  34. fig = plt.figure()
  35. ax = fig.add_subplot(111)
  36. ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
  37. ax.scatter(xcord2, ycord2, s=30, c='green')
  38. x = np.arange(-3.0, 3.0, 0.1)
  39. y = (-weights[0] - weights[1] * x) / weights[2]
  40. ax.plot(x, y)
  41. plt.xlabel('X1')
  42. plt.ylabel('X2')
  43. plt.show()
  44. if __name__ == '__main__':
  45. data_arr, label_mat = lr.load_data()
  46. weights = stoc_grad_ascent1(np.array(data_arr), label_mat)
  47. print(weights)
  48. plot_best_fit(weights)

运行结果:

  1. D:\work\python_workspace\machine_learning\venv\Scripts\python.exe D:/work/python_workspace/machine_learning/logistic_regression/stoc_grad_ascent1.py
  2. [13.66512034 0.9332941 -2.05701081]
  3. Process finished with exit code 0

图像:

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

闽ICP备14008679号