python逻辑回归分类MNIST数据集

一、逻辑回归的介绍

  logistic回归又称logistic回归分析,是一种广义的线性回归分析模型,常用于数据挖掘,疾病自动诊断,经济预测等领域。例如,探讨引发疾病的危险因素,并根据危险因素预测疾病发生的概率等。以胃癌病情分析为例,选择两组人群,一组是胃癌组,一组是非胃癌组,两组人群必定具有不同的体征与生活方式等。因此因变量就为是否胃癌,值为“是”或“否”,自变量就可以包括很多了,如年龄、性别、饮食习惯、幽门螺杆菌感染等。自变量既可以是连续的,也可以是分类的。然后通过logistic回归分析,可以得到自变量的权重,从而可以大致了解到底哪些因素是胃癌的危险因素。同时根据该权值可以根据危险因素预测一个人患癌症的可能性。

二、逻辑回归的原理和实现

  逻辑回归的算法原理和线性回归的算法步骤大致相同,只是预测函数H和权值更新规则不同。逻辑回归算法在这里应用于多分类,由于MNIST的数据集是共有十类的手写数字图片,所以应该使用十个分类器模型,分别求出每类最好的权值向量,并将其应用到预测函数中,预测函数值相当于概率,使得预测函数值最大对应的类就是所预测的类。

三、数据集介绍

  MNIST数据集,MNIST 数据集来自美国国家标准与技术研究所,National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据。训练数据集共有60000张图片和相应的标签,测试数据集共有10000张图片和相应的标签,并且每个图片都有28*28个像素。图1大致展示了数据集中的手写图片。

四、逻辑回归的代码和结果

代码:

from numpy import *import operatorimport osimport numpy as npimport timefrom scipy.special import expitimport matplotlib.pyplot as pltfrom matplotlib import cmfrom os import listdirfrom mpl_toolkits.mplot3d import Axes3Dimport structimport math#读取图片def read_image(file_name):    #先用二进制方式把文件都读进来    file_handle=open(file_name,"rb")  #以二进制打开文档    file_content=file_handle.read()   #读取到缓冲区中    offset=0    head = struct.unpack_from(‘>IIII‘, file_content, offset)  # 取前4个整数,返回一个元组    offset += struct.calcsize(‘>IIII‘)    imgNum = head[1]  #图片数    rows = head[2]   #宽度    cols = head[3]  #高度

images=np.empty((imgNum , 784))#empty,是它所常见的数组内的所有元素均为空,没有实际意义,它是创建数组最快的方法    image_size=rows*cols#单个图片的大小    fmt=‘>‘ + str(image_size) + ‘B‘#单个图片的format

for i in range(imgNum):        images[i] = np.array(struct.unpack_from(fmt, file_content, offset))        # images[i] = np.array(struct.unpack_from(fmt, file_content, offset)).reshape((rows, cols))        offset += struct.calcsize(fmt)    return images

#读取标签def read_label(file_name):    file_handle = open(file_name, "rb")  # 以二进制打开文档    file_content = file_handle.read()  # 读取到缓冲区中

head = struct.unpack_from(‘>II‘, file_content, 0)  # 取前2个整数,返回一个元组    offset = struct.calcsize(‘>II‘)

labelNum = head[1]  # label数    # print(labelNum)    bitsString = ‘>‘ + str(labelNum) + ‘B‘  # fmt格式:‘>47040000B‘    label = struct.unpack_from(bitsString, file_content, offset)  # 取data数据,返回一个元组    return np.array(label)

def loadDataSet():    train_x_filename="train-images-idx3-ubyte"    train_y_filename="train-labels-idx1-ubyte"    test_x_filename="t10k-images-idx3-ubyte"    test_y_filename="t10k-labels-idx1-ubyte"    train_x=read_image(train_x_filename)    train_y=read_label(train_y_filename)    test_x=read_image(test_x_filename)    test_y=read_label(test_y_filename)

# # # #调试的时候让速度快点,就先减少数据集大小    # train_x=train_x[0:1000,:]    # train_y=train_y[0:1000]    # test_x=test_x[0:500,:]    # test_y=test_y[0:500]

return train_x, test_x, train_y, test_y

def sigmoid(inX):    return 1.0/(1+exp(-inX))

def classifyVector(inX,weights):#这里的inX相当于test_data,以回归系数和特征向量作为输入来计算对应的sigmoid    prob=sigmoid(sum(inX*weights))    if prob>0.5:return 1.0    else: return 0.0# train_model(train_x, train_y, theta, learning_rate, iteration,numClass)def train_model(train_x,train_y,theta,learning_rate,iterationNum,numClass):#theta是n+1行的列向量    m=train_x.shape[0]    n=train_x.shape[1]    train_x=np.insert(train_x,0,values=1,axis=1)    J_theta = np.zeros((iterationNum,numClass))

for k in range(numClass):        # print(k)        real_y=np.zeros((m,1))        index=train_y==k#index中存放的是train_y中等于0的索引        real_y[index]=1#在real_y中修改相应的index对应的值为1,先分类0和非0

for j in range(iterationNum):            # print(j)            temp_theta = theta[:,k].reshape((785,1))            #h_theta=expit(np.dot(train_x,theta[:,k]))#是m*1的矩阵(列向量),这是概率            h_theta = expit(np.dot(train_x, temp_theta)).reshape((60000,1))            #这里的一个问题,将train_y变成0或者1            J_theta[j,k] = (np.dot(np.log(h_theta).T,real_y)+np.dot((1-real_y).T,np.log(1-h_theta))) / (-m)            temp_theta = temp_theta + learning_rate*np.dot(train_x.T,(real_y-h_theta))

#theta[:,k] =learning_rate*np.dot(train_x.T,(real_y-h_theta))            theta[:, k] = temp_theta.reshape((785,))

return theta#返回的theta是n*numClass矩阵

def predict(test_x,test_y,theta,numClass):#这里的theta是学习得来的最好的theta,是n*numClass的矩阵    errorCount=0    test_x = np.insert(test_x, 0, values=1, axis=1)    m = test_x.shape[0]

h_theta=expit(np.dot(test_x,theta))#h_theta是m*numClass的矩阵,因为test_x是m*n,theta是n*numClass    h_theta_max = h_theta.max(axis=1)  # 获得每行的最大值,h_theta_max是m*1的矩阵,列向量    h_theta_max_postion=h_theta.argmax(axis=1)#获得每行的最大值的label    for i in range(m):        if test_y[i]!=h_theta_max_postion[i]:            errorCount+=1

error_rate = float(errorCount) / m    print("error_rate", error_rate)    return error_rate

def mulitPredict(test_x,test_y,theta,iteration):    numPredict=10    errorSum=0    for k in range(numPredict):        errorSum+=predict(test_x,test_y,theta,iteration)    print("after %d iterations the average error rate is:%f" % (numPredict, errorSum / float(numPredict)))

if __name__==‘__main__‘:    print("Start reading data...")    time1=time.time()    train_x, test_x, train_y, test_y = loadDataSet()    time2=time.time()    print("read data cost",time2-time1,"second")

numClass=10    iteration = 1    learning_rate = 0.001    n=test_x.shape[1]+1

theta=np.zeros((n,numClass))# theta=np.random.rand(n,1)#随机构造n*numClass的矩阵,因为有numClass个分类器,所以应该返回的是numClass个列向量(n*1)

print("Start training data...")    theta_new = train_model(train_x, train_y, theta, learning_rate, iteration,numClass)    time3 = time.time()    print("train data cost", time3 - time2, "second")

print("Start predicting data...")    predict(test_x, test_y, theta_new,iteration)    time4=time.time()    print("predict data cost",time4-time3,"second")

结果截图:

逻辑回归分类MNIST数据集的实验

该实验中用到的参数学习率是0.001,观察分类错误率随着迭代次数的变化情况,如表2所示。

表2 分类错误率随着迭代次数的变化情况


迭代次数


1


10


100


1000


分类错误率


0.90


0.35


0.15


0.18

由表2可知,分类错误率随着迭代次数的增加先大幅度的减少后略增加。

原文地址:https://www.cnblogs.com/BlueBlue-Sky/p/9383050.html

时间: 2024-10-12 16:28:26

python逻辑回归分类MNIST数据集的相关文章

Lineage逻辑回归分类算法

Lineage逻辑回归分类算法 1.概述 Lineage逻辑回归是一种简单而又效果不错的分类算法 什么是回归:比如说我们有两类数据,各有50十个点组成,当我门把这些点画出来,会有一条线区分这两组数据,我们拟合出这个曲线(因为很有可能是非线性),就是回归.我们通过大量的数据找出这条线,并拟合出这条线的表达式,再有新数据,我们就以这条线为区分来实现分类. 下图是一个数据集的两组数据,中间有一条区分两组数据的线. 显然,只有这种线性可分的数据分布才适合用线性逻辑回归  2.算法思想 Lineage回归

朴素贝叶斯和逻辑回归分类

朴素贝叶斯 用p1(x, y)表示(x, y)属于类别1的概率,P2(x, y)表示(x, y)属于类别2的概率: 如果p(c1|x, y) > P(c2|x, y), 那么类别为1 如果p(c1|x, y) < P2(c2|x, y), 那么类别为2 根据贝叶斯公式: p(c|x, y) = (p(x, y|c) * p(c)) / p(x, y) (x, y)表示要分类的特征向量, c表示类别 因为p(x, y),对不同类别的数值是一样的,只需计算p(x, y|c) 和 p(c) p(c)

统计学习方法五 逻辑回归分类

逻辑回归分类 1,概念 2,算法流程 3,多分类逻辑回归 4,逻辑回归总结 优点: 1)预测结果是界于0和1之间的概率: 2)可以适用于连续性和类别性自变量: 3)容易使用和解释: 缺点: 1)对模型中自变量多重共线性较为敏感,例如两个高度相关自变量同时放入模型,可能导致较弱的一个自变量回归符号不符合预期,符号被扭转.?需要利用因子分析或者变量聚类分析等手段来选择代表性的自变量,以减少候选变量之间的相关性: 2)预测结果呈"S"型,因此从log(odds)向概率转化的过程是非线性的,在

用Python开始机器学习(7:逻辑回归分类) --好!!

from : http://blog.csdn.net/lsldd/article/details/41551797 在本系列文章中提到过用Python开始机器学习(3:数据拟合与广义线性回归)中提到过回归算法来进行数值预测.逻辑回归算法本质还是回归,只是其引入了逻辑函数来帮助其分类.实践发现,逻辑回归在文本分类领域表现的也很优秀.现在让我们来一探究竟. 1.逻辑函数 假设数据集有n个独立的特征,x1到xn为样本的n个特征.常规的回归算法的目标是拟合出一个多项式函数,使得预测值与真实值的误差最小

使用逻辑回归分类手写数字MNIST

英文原文请参考http://www.deeplearning.net/tutorial/logreg.html 这里,我们将使用Theano实现最基本的分类器:逻辑回归,以及学习数学表达式如何映射成Theano图. 逻辑回归是一个基于概率的线性分类器,W和b为参数.通过投射输入向量到一组超平面,每个对应一个类,输入到一个平面的距离反应它属于对应类的概率. 那么输入向量x为i类的概率,数值表示如下: 预测类别为概率最大的类,及: 用Theano实现的代码如下: # initialize with

使用逻辑回归进行mnist手写字识别

1.引言 逻辑回归(LR)在分类问题中的应用十分广泛,它是一个基于概率的线性分类器,通过建立一个简单的输入层和输出层,即可实现对输入数据的有效分类.而该网络结构的主要参数只有两个,分别是权重和偏置,本文定义损耗函数为负对数,然后通过随机梯度下降算法(SGD)来对参数进行更新,并定义误差函数来衡量训练的阶段. 2.具体训练过程 在第3部分将会给出本文的完整python代码,其中用到的文件mnist.pkl.gz可以去网上下载,放到与python文件同一目录下面即可. 首先,定义一个基于object

Python逻辑回归原理及实际案例应用

前言 上面我们介绍了线性回归, 岭回归, Lasso回归, 今天我们来看看另外一种模型-"逻辑回归". 虽然它有"回归"一词, 但解决的却是分类问题 目录 1. 逻辑回归 2. 优缺点及优化问题 3. 实际案例应用 4. 总结 正文 在前面所介绍的线性回归, 岭回归和Lasso回归这三种回归模型中, 其输出变量均为连续型, 比如常见的线性回归模型为: 其写成矩阵形式为: 现在这里的输出为连续型变量, 但是实际中会有"输出为离散型变量"这样的需求,

逻辑回归分类算法

逻辑回归由于其简单.高效.可解释性强的特点,在实际用途中十分的广泛:从购物预测到用户营销响应,从流失分析到信用评价,都能看到其活跃的身影.可以说逻辑回归占据了分类算法中非常重要的地位. 逻辑回归:logistic regression,LR.模型公式是Logistic函数,也叫Sigmoid函数.图像形如S型曲线.它可以将实数映射到[0,1]区间用来做二分类.一般选择0.5作为阀值,大于阀值的归为类1,小于阀值的归为类0.公式(Y为决策值,x为特征值,e为自然对数): 如果希望对正例样本有更高的

mnist的格式说明,以及在python3.x和python 2.x读取mnist数据集的不同

#!/usr/bin/env python # -*- coding: UTF-8 -*- import struct # from bp import * from datetime import datetime # 数据加载器基类 class Loader(object): def __init__(self, path, count): ''' 初始化加载器 path: 数据文件路径 count: 文件中的样本个数 ''' self.path = path self.count = co