线性模型与回归
目的: 学习一个线性模型以尽可能准确地预测实值输出标记。
其中,yi为实际观察值,f(xi)是回归值。
一般形式:
其中x=(x1, x2, …, xd)是由d维属性描述的样本,其中 xi是 x 在 第 i 个属性上的取值。
向量形式:
其中w=(w1, w2, …, wd)为待求解系数。
举个简单的例子来说明,之前写过的博客有写过歌坛常青树的判定因素,x1,x2,x3…就可以分别用来指代,歌手的年龄、唱功音区(高,中,低)、性别(男,女),而w1、w2、w3…分别为
其所对应的系数,系数越大说明该属性越重要。
最小二乘与参数求解
1.一维数据:
考虑xi是一维数据,设其回归值f(xi)与实际观察yi之间存在的 误差 ei,则学习的目标为:
误差 ei=| f(xi)-yi |,代入数据可得
最小化均方误差:
分别对w和b求导,可得:
得到解析/闭合(closed-form)解:
2.多维数据
多元线性回归目标:
给定数据集:
把 w 和 b 整合成向量形式 (w;b)数据集可表示为:
得到解析解如下:
则线性回归模型:
最大似然估计
最大似然估计:
找到 β0,β1 值让似然概率最大化
目标函数 损失函数(代价函数 cost functon):
参数估计优化的目标->损失最小化
对数似然损失函数 (log-likehood loss function)
对β 优化求解的算法:梯度下降
寻找让损失函数 J(β)J(β) 取得最小值时的 β
正则化:
损失函数中增加惩罚项:参数值越大惩罚越大–>让算法去尽量减少参数值
损失函数 J(β):
● 当模型参数 β 过多时,损失函数会很大,算法要努力减少 β 参数值来让损失函数最小。
● λ 正则项重要参数,λ 越大惩罚越厉害,模型越欠拟合,反之则倾向过拟合。
Logistic回归
基本介绍
1、回归:用一条直线(该线称之为最佳拟合直线)对存在的一些数据点进行拟合,这个拟合过程就叫回归。回归就是要找到最佳拟合参数集。回归就是预测一系列连续的值,分类就是预测一系列离散的值
线性“回归”,模型的目的是预测,方式是“回归”,有“倒推”之意在里面。(倒推就是先建立线性模型(包含系数)然后用训练数据来倒推出误差最小的参数。
2、主要思想:根据现有数据对分类边界线建立回归公式,以此来分类。
3、训练分类器:找到最佳拟合参数集,使用最优化算法。
接下来,介绍二值型输出分类器的相关原理。
基于Logistic回归和Sigmoid函数的分类
我们要做的是二值型输出分类器,即有0和1。将因变量可能属于的两个类分别称为负向类和正向类,其中 0 表示负向类,1 表示正向类。
Sigmoid函数公式:
为了实现Logistic回归分类器,我们可以将每个属性乘上一个回归系数,再把所有结果之相加,将这个综合代入Sigmoid函数中,得到值域为[0,1]。
基于最优化方法的最佳回归系数确定
Sigmoid函数输入记为z:
写成向量形式:
其中,向量w是我们要找的最佳参数,向量x是分类器的输入数据。
最优化算法之梯度上升法
基本思想:沿着某函数的梯度方向探寻找到该函数的最大值。
梯度意味着要沿x的方向移动∂ f ( x , y ) ∂ x /∂x,沿y的方向移动∂ f ( x , y ) /∂ y,其中,函数f ( x , y ) f(x,y)f(x,y)必须要在待计算的点上有定义并且可微。如下图:
上图展示的,梯度上升算法到达每个点后都会重新估计移动的方向。从 P0 开始,计算完该点的梯度,函数就根据梯度移动到下一点 P1。在 P1 点,梯度再次被重新计算,并沿着新的梯度方向移动到 P2 。如此循环迭代,直到满足停止条件。迭代过程中,梯度算子总是保证我们能选取到最佳的移动方向。
上图中的梯度上升算法沿梯度方向移动了一步。可以看到,梯度算子总是指向函数值增长最快的方向。这里所说的是移动方向,而未提到移动量的大小。该量值称为步长,记作 α 。用向量来表示的话,梯度上升算法的迭代公式如下:
该公式将一直被迭代执行,直至达到某个停止条件为止,比如迭代次数达到某个指定值或算法达到某个可以允许的误差范围。
所以,接下来我们要做的就是对l(β)求偏导:
则最终迭代公式写成:
训练算法:使用梯度上升找到最佳参数
如下图所示:图中有100个样本点,每个点有两个属性即X1和X2。我们将通过梯度上升法找到最佳回归系数,也就是拟合出Logistic回归模型的最佳参数。
将数据存在testSet.txt记事本中,如下图所示:
我们可以将这些数据当做训练模型参数的训练样本。见到训练样本就可以比较直观的理解算法的输入,以及我们如何利用这些数据来训练逻辑回归分类器,进而用训练好的模型来预测新的样本(检测样本)。
可以看出数据具有二维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据为X1轴上的值,第二列数据为X2轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
相关代码:
#打开文本读取每行的数据X1和X2
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]