当前位置:   article > 正文

Python实现Logistic Regression(逻辑回归模型)算法_python logistic regression

python logistic regression

       声明:代码的运行环境为Python3。Python3与Python2在一些细节上会有所不同,希望广大读者注意。本博客以代码为主,代码中会有详细的注释。相关文章将会发布在我的个人博客专栏《Python从入门到深度学习》,欢迎大家关注~


       Logistic Regression算法是一个分类算法,分类算法是一种监督学习算法,它是指根据样本的特征,将样本划分到指定的类别中。Logistic Regression是一个二分类的线性分类算法,说到线性分类算法就不得不说一下线性可分与线性不可分的概念了,如果一个分类问题可以使用线性判别函数正确分类,则称该问题为线性可分,否则称为线性不可分问题。

一、模型介绍

1、Sigmoid函数

       Logistic Regression模型属于线性分类模型,对于线性可分问题,我们需要一条直线将不同的类进行区分,这条直线被表示为:

       其中,W为权重值,b为偏置项,这条直线也被称为超平面。在Logistic Regression模型中,学习得到该直线之后,将数据分为两类,可以通过阈值函数将数据映射到不同的类别中,常用的阈值函数有Sigmoid函数,它表示为:

       代码实现Sigmoid函数:

  1. def sigmoid(x):
  2. '''
  3. 定义sigmoid函数
  4. :param x: 参数x
  5. :return: 返回计算后的值
  6. '''
  7. return 1.0 / (1 + np.exp(-x))

 

2、损失函数

       对于Logistic Regression模型来说,权重W和偏置b是唯一的未知参数,故求其值就显得尤为重要!为了求权重和偏置的值,我们需要定义损失函数。

       对于Logistic Regression算法,其属于类别a的概率为:

       其中,是Sigmoid函数。假设有n个样本,我们使用极大似然估计对其进行估计,这里我们使用Log函数,将负的Log似然函数作为其损失函数,于是问题转换为对负的Log函数求极小值,表示为:

       代码实现求解损失函数:

  1. def errorRate(pre, label):
  2. '''
  3. 损失函数
  4. :param pre: 预测值
  5. :param label: 实际值
  6. :return: 错误率
  7. '''
  8. m = np.shape(pre)[0]
  9. errSum = 0.0
  10. for i in range(m):
  11. if pre[i, 0] > 0 and (1 - pre[i, 0]) > 0:
  12. errSum -= (label[i, 0] * np.log(pre[i, 0]) + (1 - label[i, 0]) * np.log(1 - pre[i, 0]))
  13. else:
  14. errSum -= 0.0
  15. return errSum / m

二、梯度下降法

       在很多监督学习模型中,都需要对原始模型构建损失函数,接下来通过优化算法对损失函数进行优化,找到最优的解,优化算法中常用的例如最小二乘法、梯度下降法等等。此处,为了求得损失函数的最优解,我们使用梯度下降法进行求解。

       梯度下降法的基本流程如下:

       (1)随机选择开一个初始点;

       (2)选择梯度下降的方向;

       (3)选择步长;

       (4)更新点;

       (5)重复(2)、(3)、(4)步知道满足终止条件。

       代码实现梯度下降法:

  1. def LRGradientDescent(feature, label, maxIteration, alpha):
  2. '''
  3. 使用梯度下降法训练逻辑回归模型
  4. :param feature: 特征
  5. :param label: 标签
  6. :param maxIteration: 最大迭代次数
  7. :param alpha: 学习率α
  8. :return: 返回权重矩阵
  9. '''
  10. n = np.shape(feature)[1] # 特征的个数
  11. w = np.mat(np.ones((n, 1))) # 初始化权重矩阵
  12. i = 0 # 定义指标, 用于与最大迭代次数进行比较
  13. while i <= maxIteration: # 当指标小于最大迭代次数时
  14. i += 1
  15. sig = sigmoid(feature * w) # 调用sigmoid函数计算sigmoid的值
  16. error = label - sig
  17. w = w + alpha * feature.T * error # 权重修正
  18. if i % 100 == 0:
  19. print("迭代", str(i), "时的错误率为:", str(errorRate(sig, label)))
  20. return w

三、算法测试

1、数据集:分为训练集和测试集

(1)训练集

(2)测试集

2、加载数据集

       我们此处使用如下方法加载数据集,也可使用其他的方式进行加载,此处可以参考我的另外一篇文章《Python两种方式加载文件内容》。加载文件内容代码如下:

  1. def loadData(fileName):
  2. '''
  3. 加载测试数据
  4. :param fileName: 文件名
  5. :return: 返回特征和标签
  6. '''
  7. f = open(fileName) # 打开训练数据集所在的文档
  8. feature = [] # 存放特征的列表
  9. label = [] # 存放标签的列表
  10. for row in f.readlines():
  11. f_tmp = [] # 存放特征的中间列表
  12. l_tmp = [] # 存放标签的中间列表
  13. number = row.strip().split("\t") # 得到每行特征和标签
  14. f_tmp.append(1) # 设置偏置项
  15. for i in range(len(number) - 1):
  16. f_tmp.append(float(number[i]))
  17. l_tmp.append(float(number[-1]))
  18. feature.append(f_tmp)
  19. label.append(l_tmp)
  20. f.close() # 关闭文件,这个操作很重要
  21. return np.mat(feature), np.mat(label)

3、保存权重值

       训练数据集,得到权重值,使用如下方法保存权重值:

  1. def saveWeight(fileName, weight):
  2. '''
  3. 保存权重矩阵
  4. :param fileName: 保存后的文件名
  5. :param weight: 权重矩阵
  6. :return:
  7. '''
  8. m = np.shape(weight)[0]
  9. f = open(fileName, "w")
  10. weight_list = []
  11. for i in range(m):
  12. weight_list.append(str(weight[i ,0]))
  13. f.write("\t".join(weight_list))
  14. f.close()

4、使用训练得到的权重对测试集进行分类

  1. '''
  2. 分类算法(线性二分类):logistic Regression
  3. '''
  4. from LogisticRegression.LogisticRegression_train import sigmoid
  5. import numpy as np
  6. def loadFile(fileName, num):
  7. '''
  8. 加载测试集
  9. :param fileName:
  10. :param num:
  11. :return: 返回特征
  12. '''
  13. f = open(fileName)
  14. feature = []
  15. for row in f.readlines():
  16. f_tmp = []
  17. number = row.strip().split("\t")
  18. if len(number) != num - 1: # 排除测试集中不符合要求的数据
  19. continue
  20. f_tmp.append(1) # 设置偏置项
  21. for i in number:
  22. f_tmp.append(float(i))
  23. feature.append(f_tmp)
  24. f.close()
  25. return np.mat(feature)
  26. def loadWeights(weights):
  27. '''
  28. 加载权重值
  29. :param weights: 权重所在的文件位置
  30. :return: 权重矩阵
  31. '''
  32. f = open(weights)
  33. w = []
  34. for row in f.readlines():
  35. number = row.strip().split("\t")
  36. w_tmp = []
  37. for i in number:
  38. w_tmp.append(float(i))
  39. w.append(w_tmp)
  40. f.close()
  41. return np.mat(w)
  42. def predict(feature, w):
  43. '''
  44. 对测试数据进行预测
  45. :param feature: 测试数据的特征
  46. :param w: 权重
  47. :return: 预测结果
  48. '''
  49. sig = sigmoid(feature * w.T)
  50. n = np.shape(sig)[0]
  51. for i in range(n):
  52. if sig[i, 0] < 0.5:
  53. sig[i, 0] = 0.0
  54. else:
  55. sig[i, 0] = 1.0
  56. return sig
  57. def saveResult(fileName, result):
  58. '''
  59. 保存预测结果
  60. :param file_name: 结果文件名
  61. :param result: 结果值
  62. :return:
  63. '''
  64. m = np.shape(result)[0]
  65. res = []
  66. for i in range(m):
  67. res.append(str(result[i, 0]))
  68. f = open(fileName, "w")
  69. f.write("\t".join(res))
  70. f.close()
  71. if __name__ == "__main__":
  72. path = "./data/" # 数据集的存放路径
  73. w = loadWeights("weights")
  74. n = np.shape(w)[1]
  75. lr_test_data = loadFile(path + "test.txt", n)
  76. sig = predict(lr_test_data, w)
  77. saveResult("resultData", sig)

5、测试集分类如下图所示

        你们在此过程中遇到了什么问题,欢迎留言,让我看看你们都遇到了哪些问题。

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

闽ICP备14008679号