【机器学习算法实现】系列文章将记录个人阅读机器学习论文、书籍过程中所碰到的算法,每篇文章描述一个具体的算法、算法的编程实现、算法的具体应用实例。争取每个算法都用多种语言编程实现。所有代码共享至github:https://github.com/wepe/MachineLearning-Demo     欢迎交流指正!

(2)logistic回归__基于Python和Numpy函数库

1、算法简介

本文的重点放在算法的工程实现上,关于算法的原理不具体展开,logistic回归算法很简单,可以看看Andrew Ng的视频:https://class.coursera.org/ml-007,也可以看看一些写得比较好的博文:洞庭之子的博文。下面我只列出一些个人认为重要的点。

回归的概念:假设有一些数据点,我们用一条直线对这些点进行拟合,这个拟合过程就称作回归。

logistic回归算法之所以称作“logistic”,是因为它运用了logistic函数,即sigmoid函数。

logistic回归算法一般用于二分类问题(当然也可以多类别,后面会讲)。

logistic回归的算法思想:


用上面的图来分析,每个O或X代表一个特征向量,这里是二维的,可以写成x=(x1,x2)。

用logistic回归进行分类的主要思想就是根据现有数据集,对分类边界建立回归公式,拿上面这个图来说,就是根据

这些OOXX,找出那条直线的公式:Θ0*x0+Θ1*x1+Θ2*x2=Θ0+Θ1*x1+Θ2*x2=0  (x0=1)。

因为上图是二维的,所以参数Θ=(Θ0,Θ1, Θ2),分类边界就由这个(Θ0,Θ1, Θ2)确定,对于更高维的情况也

是一样的,所以无论二维三维更高维,分类边界可以统一表示成f(x)=ΘT*x  (ΘT表示Θ的转置)。

对于分类边界上的点,代入分类边界函数就得到f(x)=0,同样地,对于分类边界之上的点,代入得到f(x)>0,对于分

类边界之下的点,代入得到f(x)<0。这样就可以依据f(x)大于0或者小于0来分类了。

logistic回归的最后一步就是将f(x)作为输入,代入Sigmoid函数,当f(x)>0时,sigmoid函数的输出就大0.5,且随

着f(x)趋于正无穷,sigmoid函数的输出趋于1。当f(x)<0时,sigmoid函数的输出就小于0.5,且随着f(x)趋于负无

穷,sigmoid函数的输出趋于0。

所以我们要寻找出最佳参数Θ,使得对于1类别的点x,f(x)趋于正无穷,对于0类别的点x,f(x)趋于负无穷(实际编

程中不可能正/负无穷,只要足够大/小即可)。

总结一下思绪,logistic回归的任务就是要找到最佳的拟合参数。下图的g(z)即sigmoid函数,跟我上面讲的一样,

将f(x)=ΘT*x作为g(z)的输入。

以上就是logistic回归的思想,重点在于怎么根据训练数据求得最佳拟合参数Θ?这可以用最优化算法来求解,比如

常用的梯度上升算法,关于梯度上升算法这里也不展开,同样可以参考上面推荐的博文。

所谓的梯度,就是函数变化最快的方向,我们一开始先将参数Θ设为全1,然后在算法迭代的每一步里计算梯度,沿

着梯度的方向移动,以此来改变参数Θ,直到Θ的拟合效果达到要求值或者迭代步数达到设定值。Θ的更新公式:

alpha是步长,一系列推导后:

这个公式也是下面写代码所用到的。

后话:理解logistic回归之后可以发现,其实它的本质是线性回归,得到ΘT*x的过程跟线性回归是一样的,只不过

后面又将ΘT*x作为logistic函数的输入,然后再判断类别。

2、工程实例

logistic回归一般用于二分类问题,比如判断一封邮件是否为垃圾邮件,判断照片中的人是男是女,预测一场比赛输还

是赢......当然也可以用于多分类问题,比如k类别,就进行k次logistic回归。

我的前一篇文章:kNN算法__手写识别 讲到用kNN算法识别数字0~9,这是个十类别问题,如果要用logistic回归,

得做10次logistic回归,第一次将0作为一个类别,1~9作为另外一个类别,这样就可以识别出0或非0。同样地可以将

1作为一个类别,0、2~9作为一个类别,这样就可以识别出1或非1........

本文的实例同样是识别数字,但为了简化,我只选出0和1的样本,这是个二分类问题。下面开始介绍实现过程:

(1)工程文件说明

在我的工程文件目录下,有训练样本集train和测试样本集test,源代码文件命名为logistic regression.py

训练样本集train和测试样本集test里面只有0和1样本:

logistic regression.py实现的功能:从train里面读取训练数据,然后用梯度上升算法训练出参数Θ,接着用参数Θ来预

测test里面的测试样本,同时计算错误率。

(2)源代码解释

  • loadData(direction)函数

实现的功能就是从文件夹里面读取所有训练样本,每个样本(比如0_175.txt)里有32*32的数据,程序将32*32的数据

整理成1*1024的向量,这样从每个txt文件可以得到一个1*1024的特征向量X,而其类别可以从文件名“0_175.txt”里截

取0出来。因此,从train文件夹我们可以获得一个训练矩阵m*1024和一个类别向量m*1,m是样本个数。

[python] view plaincopy
  1. def loadData(direction):
  2. trainfileList=listdir(direction)
  3. m=len(trainfileList)
  4. dataArray= zeros((m,1024))
  5. labelArray= zeros((m,1))
  6. for i in range(m):
  7. returnArray=zeros((1,1024))  #每个txt文件形成的特征向量
  8. filename=trainfileList[i]
  9. fr=open('%s/%s' %(direction,filename))
  10. for j in range(32):
  11. lineStr=fr.readline()
  12. for k in range(32):
  13. returnArray[0,32*j+k]=int(lineStr[k])
  14. dataArray[i,:]=returnArray   #存储特征向量
  15. filename0=filename.split('.')[0]
  16. label=filename0.split('_')[0]
  17. labelArray[i]=int(label)     #存储类别
  18. return dataArray,labelArray
代码里面用到python os模块里的listdir(),用于从文件夹里读取所有文件,返回的是列表。
python里的open()函数用于打开文件,之后用readline()一行行读取
  • sigmoid(inX)函数
[python] view plaincopy
  1. def sigmoid(inX):
  2. return 1.0/(1+exp(-inX))
  • gradAscent(dataArray,labelArray,alpha,maxCycles)函数

用梯度下降法计算得到回归系数,alpha是步长,maxCycles是迭代步数。

[python] view plaincopy
  1. def gradAscent(dataArray,labelArray,alpha,maxCycles):
  2. dataMat=mat(dataArray)    #size:m*n
  3. labelMat=mat(labelArray)      #size:m*1
  4. m,n=shape(dataMat)
  5. weigh=ones((n,1))
  6. for i in range(maxCycles):
  7. h=sigmoid(dataMat*weigh)
  8. error=labelMat-h    #size:m*1
  9. weigh=weigh+alpha*dataMat.transpose()*error
  10. return weigh

用到numpy里面的mat,矩阵类型。shape()用于获取矩阵的大小。

这个函数返回参数向量Θ,即权重weigh

  • classfy(testdir,weigh)函数

分类函数,根据参数weigh对测试样本进行预测,同时计算错误率

[python] view plaincopy
  1. def classfy(testdir,weigh):
  2. dataArray,labelArray=loadData(testdir)
  3. dataMat=mat(dataArray)
  4. labelMat=mat(labelArray)
  5. h=sigmoid(dataMat*weigh)  #size:m*1
  6. m=len(h)
  7. error=0.0
  8. for i in range(m):
  9. if int(h[i])>0.5:
  10. print int(labelMat[i]),'is classfied as: 1'
  11. if int(labelMat[i])!=1:
  12. error+=1
  13. print 'error'
  14. else:
  15. print int(labelMat[i]),'is classfied as: 0'
  16. if int(labelMat[i])!=0:
  17. error+=1
  18. print 'error'
  19. print 'error rate is:','%.4f' %(error/m)
  • digitRecognition(trainDir,testDir,alpha=0.07,maxCycles=10)函数

整合上面的所有函数,调用这个函数进行数字识别,alpha和maxCycles有默认形参,这个可以根据实际情况更改。

[python] view plaincopy
  1. def digitRecognition(trainDir,testDir,alpha=0.07,maxCycles=10):
  2. data,label=loadData(trainDir)
  3. weigh=gradAscent(data,label,alpha,maxCycles)
  4. classfy(testDir,weigh)
用loadData函数从train里面读取训练数据,接着根据这些数据,用gradAscent函数得出参数weigh,最后就可以用拟
合参数weigh来分类了。

3、试验结果

工程文件可以到这里下载:github地址

运行logistic regression.py,采用默认形参:alpha=0.07,maxCycles=10,看下效果,错误率0.0118

[python] view plaincopy
  1. >>> digitRecognition('train','test')

改变形参,alpah=0.01,maxCycles=50,看下效果,错误率0.0471

[python] view plaincopy
  1. >>> digitRecognition('train','test',0.01,50)

这两个参数可以根据实际情况调整

logistic回归__基于Python和Numpy函数库相关推荐

  1. [转载] python导入numpy函数库

    参考链接: Python中的NumPy 1(简介) 1.安装pip  去网站  https://raw.github.com/pypa/pip/master/contrib/get-pip.py  进 ...

  2. python做logistic回归_用Python做Logistic回归

    为什么写这篇文章 本人初学python,碰巧做的东西需要用一下Logistic回归,自觉这个很基础的东西应该已经有很多比较好的实现了,于是我就很自觉地问了下度娘.结果大囧==..出来的相关结果少得可怜 ...

  3. python中numpy数组的合并_基于Python中numpy数组的合并实例讲解

    基于Python中numpy数组的合并实例讲解 Python中numpy数组的合并有很多方法,如 - np.append() - np.concatenate() - np.stack() - np. ...

  4. logistic回归模型—基于R

    logistic回归模型-基于R 数据理解和准备 一. 对缺失值的处理 二.虚拟变量的赋值 三.箱线图 四.相关性分析 训练集与测试集的划分 模型构建与评价 一.logistic回归模型 二.检查模型 ...

  5. Python使用numpy函数vsplit垂直(行角度)拆分numpy数组(返回拆分后的numpy数组列表)实战:垂直拆分二维numpy数组、split函数垂直拆分二维numpy数组

    Python使用numpy函数vsplit垂直(行角度)拆分numpy数组(返回拆分后的numpy数组列表)实战:垂直拆分二维numpy数组.split函数垂直拆分二维numpy数组 目录

  6. Python使用numpy函数hsplit水平(按列)拆分numpy数组(返回拆分后的numpy数组列表)实战:水平(按列)拆分二维numpy数组、split函数水平(按列)拆分二维numpy数组

    Python使用numpy函数hsplit水平(按列)拆分numpy数组(返回拆分后的numpy数组列表)实战:水平(按列)拆分二维numpy数组.split函数水平(按列)拆分二维numpy数组 目 ...

  7. R语言构建logistic回归模型:WVPlots包PRTPlot函数可视化获取logistic回归模型的最优阈值、优化(precision、enrichment)和recall之间的折衷

    R语言构建logistic回归模型:WVPlots包PRTPlot函数可视化获取logistic回归模型的最佳阈值(改变阈值以优化精确度(precision.enrichment)和查全率(recal ...

  8. 匿名函数python_基于python内置函数与匿名函数详解

    内置函数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice() any() d ...

  9. Python中numpy.linalg库常用函数

    Python中numpy.linalg库常用函数 numpy.linalg Python中numpy.linalg库常用函数 简单记录所遇到的numpy库内置函数 矩阵与向量积 ①np.linalg. ...

  10. Logistic回归模型及损失函数和成本函数

    Logistic回归模型.损失函数和成本函数 logistic模型 损失函数 成本函数 梯度下降法 logistic模型 logistic模型: y^=σ(wTx+b)\hat{y} = σ(w^Tx ...

最新文章

  1. 全球智能驾驶产业全景图
  2. CF401D Roman and Numbers
  3. CNCF 云原生系列文章
  4. antd menu收缩时二级菜单不跟随的问题。
  5. Netbeans and Remote Host for C/C++ Developing
  6. CSS之定位布局(position,relative定位布局技巧)
  7. java 招聘需求_Java人员要具备哪些技能 招聘需求包括什么
  8. HashMap测试程序2
  9. 团队-游戏《石头,剪刀,布》-团队一阶段互评
  10. 【渝粤教育】国家开放大学2018年春季 0556-21T广告摄影 参考试题
  11. 先虚拟主机后云服务器,先虚拟主机后云服务器
  12. 使用JedisCluster出现异常:java.lang.NumberFormatException
  13. 捆网包裹行业调研报告 - 市场现状分析与发展前景预测
  14. stegsolve---图片隐写查看器
  15. spss主成分综合得分_权重赋值之“主成分分析法”
  16. 安装虚拟光驱Daemon Tool 安装失败
  17. linux 不小心删除ls,浅谈Linux系统误删除文件恢复方法
  18. BAT领衔,云计算厂商群雄逐鹿,谁才是云时代的安全之王
  19. 电脑突然找不到蓝牙开关了
  20. Before Anything, an Architect Is a Developer

热门文章

  1. Spring Cloud消息驱动整合
  2. 微软发布云端计算机实验室服务 可以让用户存取虚拟机
  3. 第十三 关于JavaScript
  4. bootstrapt使用
  5. 苹果和FBI出庭日期延后
  6. 中国数字电视视频信号基本参数
  7. 男人在拥有女人之后!
  8. 关于安装CNPM 与搭建VUE空白项目
  9. bzoj 2151 种树 —— 思路+链表
  10. 陈梓涵:关于编程的胡扯