机器学习实战:Logistic回归

第一眼看到逻辑回归(Logistic Regression)这个词时,脑海中没有任何概念,读了几页后,发现这非常类似于神经网络中单个神经元的分类方法。

书中逻辑回归的思想是用一个超平面将数据集分为两部分,这两部分分别位于超平面的两边,且属于两个不同类别(和SVM的想法有些相似),如下图:

因此,一般的逻辑回归只能处理两分类问题,同时两个类别必须是线性可分的。对于线性不可分问题,在SVM中,可以使用核函数升维的方式解决,不过那都是后话了。还是先看看逻辑回归吧。

一、Sigmoid函数

了解神经网络的朋友想必不会对这个东西陌生,在神经网络中它就是所谓的激励函数,其最常用的一种表现形式如下:

函数曲线如下:

很显然它是对阶跃函数的一个很好的近似,当输入大于零时,输出趋近于1,输入小于零时,输出趋近于0,输入为0时,输出刚好为0.5。

在逻辑回归中,训练和分类所用数据的取值范围是任意的,因此我认为,Sigmoid在逻辑回归中除了有分类作用外,最主要作用是将数据映射到0和1之间,之后我会说明具体原因。

二、超平面与梯度上升(下降)

作为分界面的超平面定义如下:

其中可取x0 = 1,即将w0作为一个常量偏移。

通过该式可以计算得到一个z值,这个z值将作为Sigmoid函数的输入,其输出大于0.5和小于0.5分别表示两个不同的类别,也即实现了两分类。现在的问题是,给定一组训练数据,如何求出超平面中的系数,即w。

我们使用梯度上升算法进行优化求解。了解神经网络的朋友对梯度上升或梯度下降应该也很熟悉吧。一个函数的梯度定义为:

注意,这里并不是f(w)的导数,其中的w是一个向量,因此上式代表对w中每一个元素求偏导。

梯度是有方向的,总是指向函数值上升最快的方向,因此当我们沿着梯度方向或反方向行进时,就能达到一个函数的最大值或最小值处。因此,梯度上升算法就是根据下式不断更新w,直到梯度没有变化或变化很小,即函数达到了最大值:

其中alpha为沿着梯度行进的步长。

也许有人会问,如何用代码求函数的梯度,在Machine Learning In Action一书中,作者没有解释,直接写出了以下几行代码:

[python] view plaincopy

  1. h = sigmoid(dataMatrix*weights)
  2. error = (labelMat - h)
  3. weights = weights + alpha * dataMatrix.transpose()* error

从代码可以看出,作者用误差值error乘以输入数据矩阵的转置代表梯度,这里我就来尝试推导一下这个等式吧。

首先说明,我们的这个分类问题,可以等效为一个最小二乘问题,设:

其中A是包含训练数据的矩阵,也就是上面代码中的dataMatrix,w是我们要求的系数,而b是我们期望的每个训练样本乘以w后应该有的值,比如我们希望输入这个样本后,Sigmoid函数输出1,那么就应该期望这个样本乘以w后的值大于零,比如说20 。

要达到最好的分类,必然希望Aw中的每一项都接近b中的对应项,即要使下式达到最小:

这就是我们要优化的函数,于是对其求梯度,有:

由梯度的定义知:

由矩阵的微分方法可知(具体过程略):

最后合在一起可得:

其中(Aw - b)正好就是实际输出值与期望值的误差,前面的系数2和步长alpha合并,就得到了上面代码中所用的公式。

现在也可以解释用Sigmoid函数映射数据的作用了,如果不用Sigmoid函数,训练样本中的取值可能较大,因此误差值error也会较大,将这样的error值带入上式后,就会造成w的剧烈变化,最后甚至难以收敛,因此在代码中,作者将dataMatrix*weights的结果送入Sigmoid后才得到用于计算误差的输出结果,同时由于Sigmoid的使用,期望值b就和Label的值一样了(0和1),对代码的编写还起到简化作用。

以上是我的个人理解,如有错误或不严密的地方,还请指出!

三、代码实现

到具体实现代码时,以上算法就有一些问题了,首先,以上算法的步长值alpha是固定的,太小会使算法收敛很慢,太大又有不能收敛的可能。其次,以上算法的结果往往在一个最佳值附件来回震荡。为此我们使用随机梯度上升算法,在神经网络中也被称为LMS(最小均方)算法。

随机梯度上升算法与普通梯度上升算法不同在于,更新w时不使用全部训练样本,而只是从中随机选择一个样本来计算误差并更新w,这样通过多次迭代,每次都随机选择不同的样本,最终w趋于收敛,且结果与普通梯度上升算法没有差别,这种方式可以抑制结果的来回震荡。同时,使用可变的步长,使步长alpha随着迭代次数的增加而减小,这样可使算法在刚开始时,快速沿着梯度前进,当接近最佳值时,alpha减小,保证算法能正确收敛到最佳值上,从而在总体上加快算法的收敛速度。

由于随机梯度上升算法每次只取一个样本,和样本总体无关,所以它还是一种支持在线学习的算法。所谓在线就是指能实时处理新加入的训练数据,而不必从新将所有数据又处理一遍。

下面给出C#版本的实现:

[csharp] view plaincopy

  1. class LogisticRegressiond
  2. {
  3. private double[] m_weights;
  4. public double[] Weights
  5. {
  6. get { return m_weights; }
  7. }
  8. private double Sigmoid(double input)
  9. {
  10. return 1 / (1 + Math.Exp(-input));
  11. }
  12. /// <summary>
  13. /// Use stochastic gradient descent\ascent method to train a binary classifier.
  14. /// </summary>
  15. /// <param name="samples">Samples used to train the classifier.</param>
  16. /// <param name="labels">Binary labels corresponding to samples.</param>
  17. /// <param name="iteration_count">Iteration count</param>
  18. /// <param name="online">Specify whether use the online training method.</param>
  19. /// <param name="max_step">Max step size.</param>
  20. /// <param name="min_step">Min step size.</param>
  21. public void Train(List<double[]> samples, bool[] labels, int iteration_count = 150, bool online = false, double max_step = 4.0, double min_step = 0.01)
  22. {
  23. if (samples.Count != labels.Length)
  24. throw new ArgumentException("‘samples‘ has different count with ‘labels‘");
  25. double[] weights = new double[samples[0].Length];
  26. if (online && m_weights != null)
  27. {
  28. if (m_weights.Length != weights.Length)
  29. {
  30. throw new ArgumentException("Sample length is different with the previous samples‘");
  31. }
  32. m_weights.CopyTo(weights, 0);
  33. }
  34. else
  35. {
  36. weights.AllSetToOne();
  37. }
  38. Random rand = new Random();
  39. for (int i = 0; i < iteration_count; i++)
  40. {
  41. for (int j = 0; j < samples.Count; j++)
  42. {
  43. double alpha = max_step / (1 + i + j) + min_step;
  44. int rand_index = rand.Next(samples.Count);
  45. double[] sample = samples[rand_index];
  46. sample.Multiply(weights);
  47. double res = Sigmoid(sample.ElementsSum());
  48. double error = res - (labels[rand_index] ? 1.0 : 0.0);
  49. sample.Multiply(alpha * error);
  50. weights.Plus(sample);
  51. samples.RemoveAt(rand_index);
  52. }
  53. }
  54. m_weights = weights;
  55. }
  56. public bool Classify(double[] vector)
  57. {
  58. if (m_weights == null)
  59. throw new AccessViolationException("Classifier has not been trained yet.");
  60. vector.Multiply(m_weights);
  61. double res = Sigmoid(vector.ElementsSum());
  62. return res > 0.5;
  63. }
  64. }

最后总结一下逻辑回归的优缺点。

优点:

1、实现简单;

2、分类时计算量非常小,速度很快;

3、所需存储资源极低;

缺点:

1、容易过拟合;

2、准确度可能不高;

3、只能处理两分类问题,且必须线性可分;

时间: 2024-09-30 09:02:59

机器学习实战:Logistic回归的相关文章

机器学习实战——Logistic回归

回归概述(个人理解的总结) 回归是数学中的一种模拟离散数据点的数学模型的方法,拟合一个连续的函数从而可以对未知的离散数据点进行分类或预测.这种方法有一个统一的形式,给定n维特征的数据集合,对任意一个数据点Xi={x(1)i,x(2)i,...,x(n)i}的每个维度都有一个回归系数wi与之对应,整个模型就存在一个系数向量w={w1,w2...wn}.如果是系数向量w与特征Xi的线性组合,那么就是一个n空间下的超平面,如果对应分类问题,那么这个超平面就是分类器的决策平面(分类超平面).由于线性组合

[机器学习实战] Logistic回归

1. Logistic回归: 1)优点:计算代价不高,易于理解和实现: 2)缺点:容易欠拟合,分类精度可能不高: 3)适用数据类型:数值型和标称型数据: 2. 分类思想: 根据现有数据对分类边界线建立回归公式,以此进行分类. 这里借助sigmoid函数,其特点为当z为0时,sigmoid函数值为0.5:随着z的增大,对应的sigmoid值将逼近1: 而随着z的减小,sigmoid值将逼近0. σ(z) = 1/(1 + e-z) 上述 z = w0x0 + w1x1 + w2x2 + ....

机器学习实战 logistic回归 python代码

# -*- coding: utf-8 -*- """ Created on Sun Aug 06 15:57:18 2017 @author: mdz """ '''http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=9162199&id=4223505''' import numpy as np #读取数据 def loadDataSet(): dataList=[]

机器学习实战-逻辑回归

什么是回归? 假设现在有些数据点,我用直线对这些点进行拟合(该线叫做最佳拟合直线),这个拟合的过程就叫做回归. Logistic回归? 这里,Logistic回归进行分类的主要思想:根据现有数据对分类的边界线建立回归公式,以此边界线进行分类.这里的回归指的是最佳拟合,就是要找到边界线的回归公式的最佳拟合的参数集.训练时使用最优化算法寻找最佳拟合参数. 基于Logistic回归和Sigmoid函数的分类 对于边界线建立的回归函数,能够接受所有的输入然后预测出类别.例如,对于二分类的情况下,上述函数

机器学习之logistic回归与分类

logistic回归与分类是一种简单的分类算法.在分类的过程中只需要找到一个划分不同类的权重向量即可,对新的数据只需要乘上这个向量并比较就可以得到分类.比如下图的二分类问题: 每个样本点可以看成包含两个特征(x1,x2),现在需要把他们分开,如果这是训练集,他们本身属于哪一个类是已知的,比如说蓝色的属于0类,红色的属于1类,现在我们想通过这些数据建立一个分类标准可以将他们分开,这样再来了一个不知道类别的数据,我们看看这个标准就知道他是属于哪一类的. 像上面这个线性的,那么我们可以建立一个函数模型

机器学习笔记—Logistic回归

本文申明:本系列笔记全部为原创内容,如有转载请申明原地址出处.谢谢 序言:what is logistic regression? Logistics 一词表示adj.逻辑的;[军]后勤学的n.[逻]数理逻辑;符号逻辑;[军]后勤学, “回归”是由英国著名生物学家兼统计学家高尔顿在研究人类遗传问题时提出来的.为了研究父代与子代身高的关系,高尔顿搜集了1078对父亲及其儿子的身高数据.他发现这些数据的散点图大致呈直线状态,也就是说,总的趋势是父亲的身高增加时,儿子的身高也倾向于增加.但是,高尔顿对

机器学习算法-logistic回归算法

Logistic回归算法调试 一.算法原理 Logistic回归算法是一种优化算法,主要用用于只有两种标签的分类问题.其原理为对一些数据点用一条直线去拟合,对数据集进行划分.从广义上来讲这也是一种多元线性回归方法,所不同的是这种算法需要找出的是能够最大可能地将两个类别划分开来而不是根据直线关系预测因变量的值.Logistic回归算法的核心部分是sigmoid函数: 其中,xi为数据集的第i个特征.定义损失函数损失函数: 损失函数越小表明曲线拟合的效果就越好.利用梯度向上法更新x的系数W,求出W的

机器学习:logistic回归

逻辑回归是一个形式是Y=1/(1+E(-X))的函数,它的特点是: 1, 当X>0,随着X增大,Y很快的接近1: 2,当x<0,随着X的减小,Y很快的接近0: 3,当X=0时,Y=1/2. 由于逻辑回归的这种特性(在0-1之间连续),它被用来判断一个学习算法是否正确. 除了正确和不正确的结果之外,使用逻辑回归的好处在于,它还能告诉你,你离正确的结果还差多少,从而引导你向正确的方向前进.因此它常常和梯度上升的算法结合起来.下面的代码体现了这样的例子: 输入参数1是100行,2列的矩阵: 输入参数

机器学习实战-Logistics回归

Logistics回归:实战,有两个特征X0,X1.100个样本,进行Logistics回归 1.导入数据 1 def load_data_set(): 2 """ 3 加载数据集 4 :return:返回两个数组,普通数组 5 data_arr -- 原始数据的特征 6 label_arr -- 原始数据的标签,也就是每条样本对应的类别 7 """ 8 data_arr=[] 9 label_arr=[] 10 f=open('TestSet.

机器学习day14 机器学习实战树回归之CART与模型树

这几天完成了树回归的相关学习,这一部分内容挺多,收获也挺多,刚刚终于完成了全部内容,非常开心. 树回归这一章涉及了CART,CART树称作(classify and regression tree) 分类与回归树,既可以用于分类,也可以用于回归.这正是前面决策树没有说到的内容,在这里补充一下.正好也总结一下我们学的3种决策树. ID3:用信息增益来选择特性进行分类,只能处理分类问题.缺点是往往偏向于特性种类多的特性进行分解,比如特性A有2种选择,特性B有3种选择,混乱度差不多的情况下,ID3会偏