【4】Logistic回归
前言
logistic回归的主要思想:根据现有数据对分类边界建立回归公式,以此进行分类
sigmoid函数
由前言中知道,我们需要一个阶跃函数,不管接受什么输入,输出的都是0或1
它的图形如下:
最佳回归系数
其中W就是回归系数向量,向量的每个元素对应数据的一个维度也就是一种特征
现在的任务就是确定最佳回归系数,常用的方法有最小二乘法、梯度上升法等最优化方法。
本文主要是使用梯度上升法作为讨论的基础
梯度上升法
每个回归系数初始化为1
重复R次:
计算整个数据集的梯度
使用 alpha * gradient 更新回归系数向量
返回回归系数
# 载入测试数据,返回测试数据集和类别标签
def loadDataSet():
dataMat = []
labelMat = []
fr = open(r'E:\ml\machinelearninginaction\Ch05\testSet.txt')
dataFromFile = fr.readlines()
print len(dataFromFile)
for line in dataFromFile:
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))
# =====================================
# 梯度上升算法
# 输入:
# dataMatIn: 2维数组,每列代表一种特征
# classLabels: 类别标签
# 返回:逻辑回归参数
# =====================================
def gradAscent(dataMatIn, classLabels):
dataMat = mat(dataMatIn)# 装换成numpy矩阵
labelMat = mat(classLabels).transpose()# 转置
m, n = shape(dataMat)
weights = ones((n, 1))# 初始化权重都为1
alpha = 0.001
maxCycles = 500# 迭代次数
for i in range(maxCycles):
# 以下三行代码是梯度上升算法的具体实现
h = sigmoid(dataMat * weights)# 矩阵乘法
error = (labelMat - h)
weights = weights + alpha * dataMat.transpose() * error
return weights



画出决策函数
# 画出数据集合logistic回归最佳拟合直线的函数
# 输入wei是系数向量
def plotBestFit(wei):
import matplotlib.pyplot as plt
weight = wei.getA() # 矩阵转换成数组
dataMat, labelMat = loadDataSet()
dataArray = array(dataMat)
n = shape(dataArray)[0] # 获得数组的行数
xcord1 = []
ycord1 = []
xcord2 = []
ycord2 = []
for i in range(n):
if labelMat[i] == 1:
xcord1.append(dataArray[i, 1])
ycord1.append(dataArray[i, 2])
else:
xcord2.append(dataArray[i, 1])
ycord2.append(dataArray[i, 2])
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 = (-weight[0] - weight[1] * x) / weight[2]
ax.plot(x, y)
plt.show()

随机梯度上升
# =========================================
# 随机梯度上升算法
# =========================================
def stoGradAsent0(dataMatrix, classLabels):
m, n = shape(dataMatrix)
weights = ones(n)
alpha = 0.001
for i in range(m):
h = sigmoid(sum(dataMatrix[i] * weights))
err = h - classLabels[i]
weights = weights + alpha * err * dataMatrix[i]
return weights
data, label = loadDataSet()
wei = stocGradAscent0(array(data), label)
plotBestFit(wei)

改进的随机梯度上升
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
m,n = shape(dataMatrix)
weights = ones(n)
for j in range(numIter):
dataIndex = range(m)
for i in range(m):
# alpha随着迭代次数减小,但是有常数项保证永远不会小到0
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
weights = weights + alpha * error * dataMatrix[randIndex]
del(dataIndex[randIndex])
return weights
- 第八行代码表示alpha随着迭代次数减小,这是为了缓解回归系数的波动,尽快达到收敛状态(收敛是判断一个优化算法是否可靠的重要方法)。并且alpha有常数项保证永远不会小到0
- 第十行表示随机选取样本来更新回归系数,这样是为了减少周期波动

例子:从疝气病预测病马的死亡率
缺失值处理
- 使用可用特征的均值填补
- 使用特殊值来填补缺失值,比如0或-1
- 忽略有缺失值的样本
- 使用其他机器学习算法来预测缺失值
- 使用相似样本对应特征的均值俩填补
- 特征缺失:可以丢弃此样本;否则的话,由于numpy不支持包含缺失值,所以必须要填补上
- 标签缺失:基本上只能直接丢弃,因为和特征值不同,它很难使用某个合适值来替换
用logistic回归进行分类
# 用于为每个输入样本分类
# inX为待分类的样本的特征值
# weights 为训练好的权重
def classifyVector(inX, weights):
prob = sigmoid(sum(inX * weights))
if prob > 0.5:
return 1
else:
return 0
def colicTest():
frTrain = open(r'E:\ml\machinelearninginaction\Ch05\horseColicTraining.txt')
frTest = open(r'E:\ml\machinelearninginaction\Ch05\horseColicTest.txt')
trainData = []
trainLabels = []
for line in frTrain.readlines():
currLine = line.strip().split('\t')
lineArr = []
for i in range(21):#这个数据集有21个特征
lineArr.append(float(currLine[i]))
trainData.append(lineArr)
trainLabels.append(float(currLine[21]))
# 用训练集作500次迭代得到权重
trainWeights = stocGradAscent1(array(trainData), trainLabels, 500)
numTestVec = 0 # 记录测试样本的数量
errorCount = 0 # 预测错误的数量
for line in frTest.readlines():
numTestVec += 1
currLine = line.strip().split('\t')
lineArr = []
for i in range(21):
lineArr.append(float(currLine[i]))
# 把训练好的权重应用到测试集上
if int(classifyVector(array(lineArr), trainWeights)) != int(currLine[21]):
errorCount += 1
errorRate = float(errorCount)/numTestVec
print 'The error rate of this test is %f' %errorRate
return errorRate
def multiTest():
numTests = 10; errorSum=0.0
for k in range(numTests):
errorSum += colicTest()
print "after %d iterations the average error rate is: %f" % (numTests, errorSum/float(numTests))

小结
LR优点:计算代价不高,易于理解和实现
【4】Logistic回归的更多相关文章
- 神经网络、logistic回归等分类算法简单实现
最近在github上看到一个很有趣的项目,通过文本训练可以让计算机写出特定风格的文章,有人就专门写了一个小项目生成汪峰风格的歌词.看完后有一些自己的小想法,也想做一个玩儿一玩儿.用到的原理是深度学习里 ...
- 机器学习——Logistic回归
1.基于Logistic回归和Sigmoid函数的分类 2.基于最优化方法的最佳回归系数确定 2.1 梯度上升法 参考:机器学习--梯度下降算法 2.2 训练算法:使用梯度上升找到最佳参数 Logis ...
- logistic回归
logistic回归 回归就是对已知公式的未知参数进行估计.比如已知公式是$y = a*x + b$,未知参数是a和b,利用多真实的(x,y)训练数据对a和b的取值去自动估计.估计的方法是在给定训练样 ...
- Logistic回归 python实现
Logistic回归 算法优缺点: 1.计算代价不高,易于理解和实现2.容易欠拟合,分类精度可能不高3.适用数据类型:数值型和标称型 算法思想: 其实就我的理解来说,logistic回归实际上就是加了 ...
- Logistic回归的使用
Logistic回归的使用和缺失值的处理 从疝气病预测病马的死亡率 数据集: UCI上的数据,368个样本,28个特征 测试方法: 交叉测试 实现细节: 1.数据中因为存在缺失值所以要进行预处理,这点 ...
- 如何在R语言中使用Logistic回归模型
在日常学习或工作中经常会使用线性回归模型对某一事物进行预测,例如预测房价.身高.GDP.学生成绩等,发现这些被预测的变量都属于连续型变量.然而有些情况下,被预测变量可能是二元变量,即成功或失败.流失或 ...
- SPSS数据分析—配对Logistic回归模型
Lofistic回归模型也可以用于配对资料,但是其分析方法和操作方法均与之前介绍的不同,具体表现 在以下几个方面1.每个配对组共有同一个回归参数,也就是说协变量在不同配对组中的作用相同2.常数项随着配 ...
- SPSS数据分析—多分类Logistic回归模型
前面我们说过二分类Logistic回归模型,但分类变量并不只是二分类一种,还有多分类,本次我们介绍当因变量为多分类时的Logistic回归模型. 多分类Logistic回归模型又分为有序多分类Logi ...
- SPSS数据分析—二分类Logistic回归模型
对于分类变量,我们知道通常使用卡方检验,但卡方检验仅能分析因素的作用,无法继续分析其作用大小和方向,并且当因素水平过多时,单元格被划分的越来越细,频数有可能为0,导致结果不准确,最重要的是卡方检验不能 ...
- Logistic回归分类算法原理分析与代码实现
前言 本文将介绍机器学习分类算法中的Logistic回归分类算法并给出伪代码,Python代码实现. (说明:从本文开始,将接触到最优化算法相关的学习.旨在将这些最优化的算法用于训练出一个非线性的函数 ...
随机推荐
- 夯实Java基础(六)——包装类
1.包装类简介 我们都知道Java是面向对象编程语言,包含了8种基本数据类型,但是这8种基本数据类型并不支持面向对象的特征,它们既不是类,也不能调用方法.这在实际使用时存在很多的不便,比如int类型需 ...
- 使用Arthas 获取Spring ApplicationContext还原问题现场
## 背景 最近来了个实习僧小弟,安排他实现对目标网站 连通性检测的小功能,简单讲就是将下边的shell 脚本换成Java 代码来实现 ``` 1#!/bin/bash 2URL="http ...
- 如何让传统ASP.NET网站在Docker中运行
本文主要描述如何让传统ASP.NET网站在Docker中运行,侧重Docker image 搭建. 使用条件: Docker for windows 用户切换到Windows 容器模式 Windows ...
- spring boot 加载自定义log4j 文件路径
spring boot 使用log4j 打印时,需首先去除自带 Logger ,然后加入log4j 依赖 <dependencies> <!-- https://mvnreposit ...
- 如何阅读JDK源码
JDK源码阅读笔记: https://github.com/kangjianwei/LearningJDK 如何阅读源码,是每个程序员需要面临的一项挑战. 为什么需要阅读源码?从实用性的角度来看,主要 ...
- JAVA基础知识(二):List接口、ArrayList类和LinkedList类
List接口继承了Collection接口,位于java.util包中.它包含Collection接口的所有方法,外加其他一些方法(具体实现参考源码),比较重要的有: anyType get(int ...
- tk.mybatis扩展通用接口
一.tk.mybatis已经为我们封装好了许多拆箱即用的通用mapper,但在实际的项目开发中想必不少小伙伴在数据库设计中都会采用逻辑删除这种方案,再去使用通用的mapper接口就不行了.这时候就需要 ...
- flink 1.7.2 安装详解
##flink 1.7.2 安装需要java环境 下载地址 https://flink.apache.org/downloads.html#1.单机版 #创建用户flinkuseradd flink ...
- 逆向破解之160个CrackMe —— 013
CrackMe —— 013 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...
- Kafka 系列(四)—— Kafka 消费者详解
一.消费者和消费者群组 在 Kafka 中,消费者通常是消费者群组的一部分,多个消费者群组共同读取同一个主题时,彼此之间互不影响.Kafka 之所以要引入消费者群组这个概念是因为 Kafka 消费者经 ...