实战——预测病马的死亡率

前面,我简单介绍了「Logistic分类器」。

Logistic回归算法

今天,我们将进行实战操练:使用Logistic分类器来预测患有疝病的马的存活率。

疝病是描述马胃肠痛的术语。引发该病的因素(这里就是样本特征值)有很多。

一、数据集

原始数据集来源2010年1月11日的UCI机器学习数据库。该数据集包含368个样本和28个特征。

由于该数据集中有30%的值是缺失的,所以我们需要处理数据集中的缺失值。

几种可选的做法如下:

1.使用可用特征的均值来填补缺失值。
2.使用特殊值来填补缺失值。
3.忽略有缺失值的样本。
4.使用相似样本的均值填补缺失值。
5.使用另外的机器学习算法预测缺失值。

我们对原始数据做如下预处理:

1.所有特征缺失值必须用实数0来替换.

因为我们采用Logistic分类器,sigmod函数在x=0处的取值不影响最后的概率估计和更新回归系数。所以,我们恰好能采用实数0来进行填补缺失值。

2.若某条样本的类别标签缺失,则直接将该条数据丢弃。

因为,我们实在很难通过某种做法来判断该标签是什么。

预处理完成后的数据集有两个:horseColicTest.txt和horseColicTraining.txt。

处理后的数据集包含21个特征值和1个类别标签向量。

细心的朋友可能会问,前面不是28个特征值吗?为什么处理后变成21个了呢?这里我也没想通,可能数据缺失,书上确实是这样,但是这并不妨碍我们使用Logistic分类器。

二、 随机梯度下降算法

数据集已经准备好了,那么我们该说说「随机梯度下降算法」了。

咦?我记得前面好像是梯度下降算法吧,这里怎么成随机的了?

至于为什么,咱们接着往下讲。

【一点小问题】

没错,前面我们确实讲的是梯度下降算法。但是,你们有没有发现,这个算法的计算量是非常大的。

梯度下降算法在每次更新回归系数时都需要遍历整个数据集。

回归系数更新公式:weights = weights - alpha * dataMatrix.transpose()* error

这里的dataMatrix是整个数据集,其计算量大致为数据集的行数x列数。

如果样本和特征值足够大,那么计算量是非常大的。

那有没有什么改进方法?有!终于轮到「随机梯度下降算法」出场了。

【随机梯度下降算法】

随机梯度下降算法:一次只用一个样本点来更新回归系数。

其代码如下:

'''
Created on Oct 27, 2010
Logistic Regression Working Module
@author: Peter
@modified by Albert on July 18,2020
'''def stocGradDecline0(dataArray, classLabels):"""随机梯度下降算法"""m,n = np.shape(dataArray)# 设置步长alpha = 0.01# 初始化回归系数weights = np.ones(n)   #initialize to all onesfor i in range(m):# 每次一个样本,注意这里是数组运算,需要手动sumh = sigmoid(sum(dataArray[i]*weights))# 预测值-真实值error = h - classLabels[i]# 更新回归系数,注意这里都是数值计算,不同于梯度下降算法的矩阵运算weights = weights - alpha * error * dataArray[i]return weights

那么,该随机梯度下降算法的分类效果究竟怎么样呢?

我们运行程序:

# 返回的数据集是矩阵类型
dataMat,labelMat = loadDataSet()
weights = stocGradDecline0(np.array(dataMat),labelMat)
# 注意,使用随机梯度下降算法时,weights是数组类型,不需要调用getA()
plotBestFit(weights)

效果如下:

诶呀,一看这结果,傻眼了,这效果明显没有前面的梯度下降算法好啊!

各位别急,请听我说。

你们是不是把迭代次数给忘了?

# 迭代次数 maxCycles = 500

上次的结果是在整个数据集上迭代500次后的结果,而这次仅仅是只是迭代了一次,或者压根没迭代。

判断一个优化算法是否优劣的可靠性方法,是看它最终的参数是否收敛。

对此,我们假定迭代次数为500,然后研究随机梯度下降算法在数据集上遍历500次时,回归系数与迭代次数的关系

核心代码如下:

'''
Created on Oct 27, 2010
Logistic Regression Working Module
@author: Peter
@modified by Albert on July 18,2020
'''
import numpy as np
import matplotlib.pyplot as plt
import logRegresdef stocGradDecline0(dataArr, classLabels):m,n = np.shape(dataArr)alpha = 0.5weights = np.ones(n)   #initialize to all ones# 设置500次迭代(遍历整个数据集500次),并记录(500x样本个数)次回归系数weightsHistory=np.zeros((500*m,n))for j in range(500):for i in range(m):h = logRegres.sigmoid(sum(dataArr[i]*weights))error = h - classLabels[i] weights = weights - alpha * error * dataArr[i]# 记录回归系数,共(500x样本个数)weightsHistory[j*m + i,:] = weightsreturn weightsHistory# 运行主程序
dataMat,labelMat=logRegres.loadDataSet()
myHist = stocGradDecline0(np.array(dataMat),labelMat)# 绘图
n = np.shape(np.array(dataMat))[0] #number of points to create
xcord1 = []; ycord1 = []
xcord2 = []; ycord2 = []markers =[]
colors =[]fig = plt.figure()
ax = fig.add_subplot(311)
type1 = ax.plot(myHist[:,0])
plt.ylabel('X0')
ax = fig.add_subplot(312)
type1 = ax.plot(myHist[:,1])
plt.ylabel('X1')
ax = fig.add_subplot(313)
type1 = ax.plot(myHist[:,2])
plt.xlabel('iteration')
plt.ylabel('X2')
plt.show()

运行结果如下:

可见,在500次迭代中,回归系数都有着不同程度的周期性波动(数据集不是线性可分的,每次迭代都会引发系数剧烈改变),且三个回归系数的收敛速度也不一样。

对此,我们希望算法能够避免周期性波动,并且尽快收敛到某一个值。

升级版核心代码如下,其余部分除调用处外,都相同:


def stocGradDecline1(dataArr, classLabels,numIter=100):"""改进的随机梯度下降算法"""m,n = np.shape(dataArr)weights = np.ones(n)   #initialize to all ones# weightsHistory 这里是为了画图需要,实际算法时,相关代码可以去掉weightsHistory=np.zeros((numIter*m,n))for j in range(numIter):dataIndex = list(range(m))for i in range(m):alpha = 4/(1.0+j+i)+0.01# 随机选择一个样本randIndex = int(np.random.uniform(0,len(dataIndex)))h = logRegres.sigmoid(sum(dataArr[randIndex]*weights))error = h -classLabels[randIndex]weights = weights - alpha * error * dataArr[randIndex]weightsHistory[j*m + i,:] = weights# 删掉已经使用过的样本索引值del(dataIndex[randIndex])print (weights)return weightsHistory

上述代码改进的地方有三处:

  1. 由于alpha的值会影响回归系数,所以我们让alpha在每次迭代时都进行调整。
  2. 随机选择某个样本来更新回归系数,这种做法可以减少回归系数的周期性波动。
  3. 添加了一个迭代参数,默认100。

运行效果如下:

可见,回归系数没有出现明显的周期性波动。另外,各参数的收敛速度也明显加快了。

我们设置迭代次数为3次。

# 返回的数据集是矩阵类型
dataMat,labelMat = loadDataSet()
weights = stocGradDecline1(np.array(dataMat),labelMat,3)
# 注意,使用随机梯度下降算法时,weights是数组类型,不需要调用getA()
plotBestFit(weights)

最后,我们来看看分类效果。

怎么样,效果不错吧,这可只是迭代了三次的结果啊,和迭代500次的梯度下降算法,随机梯度下降算法的计算量大大减少了。

另外,如果,你运行同样的代码,发现分类效果有一些不一样,不用担心,因为这是随机梯度下降算法,它每次选择的样本都是具有随机性的,不过其分类结果大致是差不多的。

多次运行上面的代码,分类结果如下:

三、病马预测

数据集准备好了,算法也优化好了,那么现在就可以进行我们的最终目标——病马预测了。

直接上代码:

1.sigmod 分类函数

'''
Created on Oct 27, 2010
Logistic Regression Working Module
@author: Peter
@modified by Albert on July 18,2020
'''def classifyVector(inX, weights):"""Sigmod分类函数"""prob = sigmoid(sum(inX*weights))# 预测结果大于0.5, 归为1类;反之,归为0类if prob > 0.5:return 1.0else: return 0.0

前面已经对sigmod函数进行了充分的讲解,这里就不再重复了。

2.疝气病预测

'''
Created on Oct 27, 2010
Logistic Regression Working Module
@author: Peter
@modified by Albert on July 18,2020
'''
def colicTest(numIter=100):"""病马预测函数"""frTrain = open('horseColicTraining.txt')frTest = open('horseColicTest.txt')trainingSet = []; trainingLabels = []for line in frTrain.readlines():currLine = line.strip().split('\t')lineArr =[]# 21个特征值for i in range(21):lineArr.append(float(currLine[i]))trainingSet.append(lineArr)# 类别标签trainingLabels.append(float(currLine[21]))trainWeights = stocGradDecline1(np.array(trainingSet), trainingLabels, numIter)# 定义错误率errorCount = 0numTestVec = 0.0for line in frTest.readlines():numTestVec += 1.0currLine = line.strip().split('\t')lineArr =[]for i in range(21):lineArr.append(float(currLine[i]))# 比较预测类别和真实类别if int(classifyVector(np.array(lineArr), trainWeights))!= int(currLine[21]):errorCount += 1errorRate = (float(errorCount)/numTestVec)print ("the error rate of this test is: %f" % errorRate)return errorRate

上面这个函数,打开测试集和训练集,来训练和测试我们构建的分类器,并计算错误率。另外,改变alpha和迭代次数,错误率也是会跟着改变的。我们我们设置迭代次数为400次,alpha同上,计算10次预测的平均错误率。

运行代码:multiTest(400)

结果如下:

可见,平均错误率差不多35%左右,这个结果还行。另外,这还不是最优的结果,因为数据有30%的丢失,alpha和迭代次数也有待调试。最终,分类器的错误率还会下降很多。

四、总结

本文主要介绍了以下三部分内容:

1.有缺失值的数据集的相关处理方法。
2.一种优化的随机梯度下降算法。
3.Logsitic实战项目编程。

Logistic回归的目的是寻找一个非线性函数Sigmod的最佳拟合系数,求解过程可以由最优化算法来完成,其中最常用的算法就是随机梯度下降算法。

最后,Logistic回归算法系列就先介绍到这里。

参考资料:

《机器学习实战》, [美] ,Peter Harriington,人民邮电出版社.

Python 3 代码下载:
链接:https://pan.baidu.com/s/10yIYk_-j1pcfZOErVyB-TA
提取码:dwps

Logistic回归算法实战相关推荐

  1. R语言glm拟合logistic回归模型实战:基于glm构建逻辑回归模型及模型系数统计显著性分析、每个预测因子对响应变量的贡献

    R语言glm拟合logistic回归模型实战:基于glm构建逻辑回归模型及模型系数统计显著性分析.每个预测因子对响应变量的贡献 目录

  2. R语言无序多分类Logistic回归模型实战

    R语言无序多分类Logistic回归模型实战 目录 R语言无序多分类Logistic回归模型实战 #导入包 #加载数据数据编码

  3. python实现logistic_用Python实现机器学习算法—Logistic 回归算法

    在 Logistic 回归中,我们试图对给定输入特征的线性组合进行建模,来得到其二元变量的输出结果.例如,我们可以尝试使用竞选候选人花费的金钱和时间信息来预测选举的结果(胜或负).Logistic 回 ...

  4. Python实现 logistic 回归算法

    Python实现 logistic 回归算法 1.算法介绍 模型描述: sigmoid函数: 原理: 优化目标:最小化 sigmoid(f(x)) 和真实标签的差别(有不同的 cost functio ...

  5. circle loss代码实现_Python全栈之路-23-使用Python实现Logistic回归算法

    视频讲解地址 使用Python实现Logistic回归算法_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com 本文代码 地址​github.com Logistic ...

  6. Logistic 回归算法原理

    Logistic 回归算法原理 Sigmoid 函数 概率决策 分布函数 函数求导 逻辑回归模型 概率预测函数 对数几率回归 条件概率分布 极大似然估计 似然函数 对数似然 对数损失 梯度上升 Log ...

  7. 机器学习中的Logistic回归算法(LR)

    Logistic回归算法(LR) 算法简介 LR名为回归,实际是一种分类算法.其针对输入样本集 x x,假设的输出结果 y=hθ(x)y=h_{\theta}(x) 的取值范围为 y=[0,1] y= ...

  8. python数据分析实战案例logistic_从零开始学Python【27】--Logistic回归(实战部分)...

    往期精彩回顾 前言 基于上一期的理论知识,我们本期跟大家分享一下如何通过Python和R语言完成Logistic回归分类器的构建.大家都知道,Logistic模型主要是用来解决二元分类问题,通过构建分 ...

  9. Logistic回归算法

    Logistic回归算法 类别 学习方法 数学知识 数据集 代码 详细内容 步骤 Logistic回归的数学表达式 Logistic回归的损失函数 优化 类别 类别:分类算法 学习方法 学习方法:有监 ...

最新文章

  1. codeforces水题100道 第五题 Codeforces Round #304 (Div. 2) A. Soldier and Bananas (math)
  2. Android Activity 生命周期和LaunchMode 规则
  3. 不努力提高效率,小姐姐都被人追走了:K8S一键部署了解一下?
  4. 深度学习100例-卷积神经网络(AlexNet)手把手教学 | 第11天
  5. 汇编语言 计算ffff:0006单元中的数乘以3,结果存在dx中
  6. Java提高篇 —— Java关键字之final的几种用法
  7. 修改终端服务端口的方法
  8. ios 贝塞尔曲线 颜色填充_iOS贝塞尔曲线(UIBezierPath)的基本使用方法
  9. 桌面版应用_【Nordic博文分享系列】开发你的第一个NCS(Zephyr)应用程序
  10. 《矩阵分析》Ⅳ——三对角矩阵的追赶法matlab实现
  11. 【Software】动软代码生成器
  12. tensorflow,pytorch中normalize方法
  13. nginx 解决 405 not allowed错误
  14. ISE UCF 写法:(转载)
  15. file对象转换为Muti文件对象工具类
  16. css选择最后一个元素
  17. 华为鸿蒙太空人壁纸,华为太空人动态壁纸下载-华为太空人动态壁纸图片高清版-丫丫安卓网...
  18. Windows凭据管理器
  19. Android--单元测试
  20. 做了3年半测试员,薪资不到20K,今天,我辞职了…

热门文章

  1. Ubuntu 20.04 搭建 DVWA 靶场
  2. python中的pro什么意思_荣耀20 PRO现货发售 华为官方解析何为Python爬虫
  3. 修改谷歌浏览器背景色
  4. 预测京张高铁一天会有多少趟列车?
  5. 今年还能学java么?
  6. [附源码]java毕业设计多功能电子词典
  7. 电力系统励磁涌流有关的问题分析。 可以通过MATLAB中m文件便编写产生励磁涌流
  8. WPS office Pro 安装教程
  9. 用HTML+CSS做一个简单的美食网页---web学生网页设计作业源码
  10. 449php,【19/11/09】基于官版Win10_Pro_1909_x64_18363.449 无APPS适度精简版极致精简版