python机器学习理论与实战(四)逻辑回归


Posted in Python onJanuary 19, 2018

         从这节算是开始进入“正规”的机器学习了吧,之所以“正规”因为它开始要建立价值函数(cost function),接着优化价值函数求出权重,然后测试验证。这整套的流程是机器学习必经环节。今天要学习的话题是逻辑回归,逻辑回归也是一种有监督学习方法(supervised machine learning)。逻辑回归一般用来做预测,也可以用来做分类,预测是某个类别^.^!线性回归想比大家都不陌生了,y=kx+b,给定一堆数据点,拟合出k和b的值就行了,下次给定X时,就可以计算出y,这就是回归。而逻辑回归跟这个有点区别,它是一种非线性函数,拟合功能颇为强大,而且它是连续函数,可以对其求导,这点很重要,如果一个函数不可求导,那它在机器学习用起来很麻烦,早期的海维赛德(Heaviside)阶梯函数就因此被sigmoid函数取代,因为可导意味着我们可以很快找到其极值点,这就是优化方法的重要思想之一:利用求导,得到梯度,然后用梯度下降法更新参数。

        下面来看看逻辑回归的sigmoid函数,如(图一)所示:

python机器学习理论与实战(四)逻辑回归

(图一)

            (图一)中上图是sigmoid函数在定义域[-5,5] 上的形状,而下图是在定义域[-60,60]上的形状,由这两个图可以看出,它比较适合做二类的回归,因为严重两级分化。Sigmoid函数的如(公式一)所示:

python机器学习理论与实战(四)逻辑回归

(公式一)

         现在有了二类回归函数模型,就可以把特征映射到这个模型上了,而且sigmoid函数的自变量只有一个Z,假设我们的特征为X=[x0,x1,x2…xn]。令python机器学习理论与实战(四)逻辑回归,当给定大批的训练样本特征X时,我们只要找到合适的W=[w0,w1,w2…wn]来正确的把每个样本特征X映射到sigmoid函数的两级上,也就是说正确的完成了类别回归就行了,那么以后来个测试样本,只要和权重相乘后,带入sigmoid函数计算出的值就是预测值啦,很简单是吧。那怎么求权重W呢?

          要计算W,就要进入优化求解阶段咯,用的方法是梯度下降法或者随机梯度下降法。说到梯度下降,梯度下降一般对什么求梯度呢?梯度是一个函数上升最快的方向,沿着梯度方向我们可以很快找到极值点。我们找什么极值?仔细想想,当然是找训练模型的误差极值,当模型预测值和训练样本给出的正确值之间的误差和最小时,模型参数就是我们要求的。当然误差最小有可能导致过拟合,这个以后再说。我们先建立模型训练误差价值函数(cost function),如(公式二)所示:

python机器学习理论与实战(四)逻辑回归

(公式二)

        (公式二)中Y表示训练样本真实值,当J(theta)最小时的所得的theta就是我们要求的模型权重,可以看出J(theta)是个凸函数,得到的最小值也是全局最小。对其求导后得出梯度,如(公式三)所示:

python机器学习理论与实战(四)逻辑回归

(公式三)

        由于我们是找极小值,而梯度方向是极大值方向,因此我们取负号,沿着负梯度方向更新参数,如(公式四)所示:

python机器学习理论与实战(四)逻辑回归

(公式四)

        按照(公式四)的参数更新方法,当权重不再变化时,我们就宣称找到了极值点,此时的权重也是我们要求的,整个参数更新示意图如(图二)所示:

python机器学习理论与实战(四)逻辑回归

(图二)

原理到此为止逻辑回归基本就说完了,下面进入代码实战阶段:

from numpy import * 
 
def loadDataSet(): 
  dataMat = []; labelMat = [] 
  fr = open('testSet.txt') 
  for line in fr.readlines(): 
    lineArr = line.strip().split() 
    dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) 
    labelMat.append(int(lineArr[2])) 
  return dataMat,labelMat 
 
def sigmoid(inX): 
  return 1.0/(1+exp(-inX))

上面两个函数分别是加载训练集和定义sigmoid函数,都比较简单。下面发出梯度下降的代码:

def gradAscent(dataMatIn, classLabels): 
  dataMatrix = mat(dataMatIn)       #convert to NumPy matrix 
  labelMat = mat(classLabels).transpose() #convert to NumPy matrix 
  m,n = shape(dataMatrix) 
  alpha = 0.001 
  maxCycles = 500 
  weights = ones((n,1)) 
  for k in range(maxCycles):       #heavy on matrix operations 
    h = sigmoid(dataMatrix*weights)   #matrix mult 
    error = (labelMat - h)       #vector subtraction 
    weights = weights + alpha * dataMatrix.transpose()* error #matrix mult 
  return weights

         梯度下降输入训练集和对应标签,接着就是迭代跟新参数,计算梯度,然后更新参数,注意倒数第二句就是按照(公式三)和(公式四)来更新参数。

为了直观的看到我们得到的权重是否正确的,我们把权重和样本打印出来,下面是相关打印代码:

def plotBestFit(weights): 
  import matplotlib.pyplot as plt 
  dataMat,labelMat=loadDataSet() 
  dataArr = array(dataMat) 
  n = shape(dataArr)[0]  
  xcord1 = []; ycord1 = [] 
  xcord2 = []; ycord2 = [] 
  for i in range(n): 
    if int(labelMat[i])== 1: 
      xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) 
    else: 
      xcord2.append(dataArr[i,1]); ycord2.append(dataArr[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 = (-weights[0]-weights[1]*x)/weights[2] 
  ax.plot(x, y) 
  plt.xlabel('X1'); plt.ylabel('X2'); 
  plt.show()

打印的效果图如(图三)所示:

python机器学习理论与实战(四)逻辑回归

(图三)

       可以看出效果蛮不错的,小错误是难免的,如果训练集没有错误反而危险,说到这基本就说完了,但是考虑到这个方法对少量样本(几百的)还行,在实际中当遇到10亿数量级时,而且特征维数上千时,这种方法很恐怖,光计算梯度就要消耗大量时间,因此要使用随机梯度下降方法。随机梯度下降算法和梯度下降算法原理一样,只是计算梯度不再使用所有样本,而是使用一个或者一小批来计算梯度,这样可以减少计算代价,虽然权重更新的路径很曲折,但最终也会收敛的,如(图四)所示

python机器学习理论与实战(四)逻辑回归

(图四)

下面也发出随机梯度下降的代码:

def stocGradAscent1(dataMatrix, classLabels, numIter=150): 
  m,n = shape(dataMatrix) 
  weights = ones(n)  #initialize to all ones 
  for j in range(numIter): 
    dataIndex = range(m) 
    for i in range(m): 
      alpha = 4/(1.0+j+i)+0.0001  #apha decreases with iteration, does not  
      randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant 
      h = sigmoid(sum(dataMatrix[randIndex]*weights)) 
      error = classLabels[randIndex] - h 
      weights = weights + alpha * error * dataMatrix[randIndex] 
      del(dataIndex[randIndex]) 
  return weights

最后也给出一个分类的代码,只要把阈值设为0.5,大于0.5划为一类,小于0.5划为另一类就行了,代码如下:

def classifyVector(inX, weights): 
  prob = sigmoid(sum(inX*weights)) 
  if prob > 0.5: return 1.0 
  else: return 0.0

总结:

        优点:计算量不高,容易实现,对现实数据也很容易描述

        缺点:很容易欠拟合,精度可能也会不高

参考文献:

    [1] machine learning in action. Peter Harrington

    [2] machine learning.Andrew Ng

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python编写的com组件发生R6034错误的原因与解决办法
Apr 01 Python
Python读取ini文件、操作mysql、发送邮件实例
Jan 01 Python
python中的__slots__使用示例
Feb 26 Python
详解Python中用于计算指数的exp()方法
May 14 Python
python查看微信好友是否删除自己
Dec 19 Python
Windows下Anaconda的安装和简单使用方法
Jan 04 Python
我就是这样学习Python中的列表
Jun 02 Python
解决Django一个表单对应多个按钮的问题
Jul 18 Python
Python input函数使用实例解析
Nov 22 Python
UI自动化定位常用实现方法代码示例
Oct 27 Python
详解Python利用configparser对配置文件进行读写操作
Nov 03 Python
python音频处理的示例详解
Dec 23 Python
python机器学习理论与实战(二)决策树
Jan 19 #Python
Python三种遍历文件目录的方法实例代码
Jan 19 #Python
python机器学习理论与实战(一)K近邻法
Jan 28 #Python
python机器学习理论与实战(六)支持向量机
Jan 19 #Python
Python logging管理不同级别log打印和存储实例
Jan 19 #Python
python机器学习理论与实战(五)支持向量机
Jan 19 #Python
Python读取图片为16进制表示简单代码
Jan 19 #Python
You might like
德生PL450的电路分析和低放电路的改进办法
2021/03/02 无线电
一个简单实现多条件查询的例子
2006/10/09 PHP
基于Linux调试工具strace与gdb的常用命令总结
2013/06/03 PHP
一个PHP二维数组排序的函数分享
2014/01/17 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
使用Codeigniter重写insert的方法(推荐)
2017/03/23 PHP
PHP使用curl_multi_select解决curl_multi网页假死问题的方法
2018/08/15 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
javascript setTimeout和setInterval 的区别
2009/12/08 Javascript
javascript中的107个基础知识收集整理 推荐
2010/03/29 Javascript
JavaScript 面向对象之命名空间
2010/05/04 Javascript
使用jquery解析XML示例代码
2014/09/05 Javascript
为什么JS中eval处理JSON数据要加括号
2015/04/13 Javascript
javascript实现rgb颜色转换成16进制格式
2015/07/10 Javascript
三种AngularJS中获取数据源的方式
2016/02/02 Javascript
JS获取复选框的值,并传递到后台的实现方法
2016/05/30 Javascript
超实用的javascript时间处理总结
2016/08/16 Javascript
BootStrap+Angularjs+NgDialog实现模式对话框
2016/08/24 Javascript
JavaScript之WebSocket技术详解
2016/11/18 Javascript
JS使用正则实现去掉字符串左右空格的方法
2016/12/27 Javascript
JS立即执行函数功能与用法分析
2019/01/15 Javascript
Vue开发之watch监听数组、对象、变量操作分析
2019/04/25 Javascript
webpack实践之DLLPlugin 和 DLLReferencePlugin的使用教程
2019/06/10 Javascript
Vue数据绑定实例写法
2019/08/06 Javascript
Vue 数据绑定的原理分析
2020/11/16 Javascript
Python中实现三目运算的方法
2015/06/21 Python
Django中URL视图函数的一些高级概念介绍
2015/07/20 Python
Python正则表达式经典入门教程
2017/05/22 Python
基于Python爬取素材网站音频文件
2020/10/21 Python
使用python-cv2实现视频的分解与合成的示例代码
2020/10/26 Python
质检部部长职责
2013/12/16 职场文书
解除合同协议书
2014/04/17 职场文书
假面舞会策划方案
2014/05/29 职场文书
主持稿开场白
2015/06/01 职场文书
2016年6月份红领巾广播稿
2015/12/21 职场文书
八年级语文教学反思
2016/03/03 职场文书