机器学习之回归模型
来源:互联网 发布:明解c语言第三版 pdf 编辑:程序博客网 时间:2024/05/16 00:38
基本形式
线性模型(linear model)就是试图通过属性的线性组合来进行预测的函数,基本形式如下:
许多非线性模型可在线性模型的基础上通过引入层结构或者高维映射(比如核方法)来解决。线性模型有很好的解释性。
线性回归
线性回归要求均方误差最小:
均方误差有很好的几何意义,它对应了常用的欧式距离(Euclidean distance)。基于均方误差最小化来进行模型求解称为最小二乘法(least square method),线性回归中,最小二乘发就是试图找到一条直线,使得所有样本到直线的欧式距离之和最小。
我们把上式写成矩阵的形式:
这里我们把b融合到w中,X中最后再加一列1。为了求最小值,我们对w求导并令其为0:
当
令
最小二乘法的代码如下:
def standRegres(xArr,yArr): xMat = mat(xArr); yMat = mat(yArr).T xTx = xMat.T*xMat if linalg.det(xTx) == 0.0: print "This matrix is singular, cannot do inverse" return ws = xTx.I * (xMat.T*yMat) return ws
然而,现实情况是很多时候,
局部加权线性回归
我们在介绍岭回归之前先看一下局部加权线性回归。这首针对线性回归容易出现“欠拟合”现象提出的,因为它求的是具有最小均方误差的无偏估计。如果模型欠拟合将不能取得最好的效果。所以有些方法在估计中引入一些偏差,从而降低均方误差。其中一个方法就是局部加权线性回归(Locally Wegihted Linear Regression,LWLR),我们给待预测点附近的每个点赋予一定的权重。回归系数
LWLWR使用核方法来赋权重,最常用的就是高斯核:
这样构建了一个只含对角元素的权重矩阵
函数代码如下:
def lwlr(testPoint,xArr,yArr,k=1.0): xMat = mat(xArr); yMat = mat(yArr).T m = shape(xMat)[0] weights = mat(eye((m))) for j in range(m): #next 2 lines create weights matrix diffMat = testPoint - xMat[j,:] weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) xTx = xMat.T * (weights * xMat) if linalg.det(xTx) == 0.0: print "This matrix is singular, cannot do inverse" return ws = xTx.I * (xMat.T * (weights * yMat)) return testPoint * ws
文末给出的下载链接中regreesion.py文件中,有个线性加权回归例子。
岭回归
就是在
岭回归最先用来处理特征数多于样本数的情况,现在也用于在估计中加入偏差,从而得到更好的估计。这里通过引入
相关代码如下:
def ridgeRegres(xMat,yMat,lam=0.2): xTx = xMat.T*xMat denom = xTx + eye(shape(xMat)[1])*lam if linalg.det(denom) == 0.0: print "This matrix is singular, cannot do inverse" return ws = denom.I * (xMat.T*yMat) return wsdef ridgeTest(xArr,yArr): xMat = mat(xArr); yMat=mat(yArr).T yMean = mean(yMat,0) yMat = yMat - yMean #to eliminate X0 take mean off of Y #regularize X's xMeans = mean(xMat,0) #calc mean then subtract it off xVar = var(xMat,0) #calc variance of Xi then divide by it xMat = (xMat - xMeans)/xVar numTestPts = 30 wMat = zeros((numTestPts,shape(xMat)[1])) for i in range(numTestPts): ws = ridgeRegres(xMat,yMat,exp(i-10)) wMat[i,:]=ws.T return wMat
ridgeRegres用于计算回归系数,ridgeTest用于在一组
同样在使用特征时,都要先进行归一化处理。
LASSO
LASSO是least absolute shrinkage and selection operator的简称。我们注意到增加如下约束,最小二乘法回归会得到与岭回归一样的公式:
上式限定了所有回归系数的平方和不大于
LASSO的约束为:
虽然用绝对值取代了平方和,但结果却差别很大。在
前向逐步回归
前向逐步回归可以得到与LASSO差不多的结果,但更加简单,是一种贪心算法,每一步都尽可能减少误差。一开始,所有权重设为1,然后每一步所做的决策是对某个权重增加或减少一个很小的值。
代码如下:
def stageWise(xArr,yArr,eps=0.01,numIt=100): xMat = mat(xArr); yMat=mat(yArr).T yMean = mean(yMat,0) yMat = yMat - yMean #can also regularize ys but will get smaller coef xMat = regularize(xMat) m,n=shape(xMat) returnMat = zeros((numIt,n)) #testing code remove ws = zeros((n,1)); wsTest = ws.copy(); wsMax = ws.copy() for i in range(numIt):#could change this to while loop #print ws.T lowestError = inf; for j in range(n): for sign in [-1,1]: wsTest = ws.copy() wsTest[j] += eps*sign yTest = xMat*wsTest rssE = rssError(yMat.A,yTest.A) if rssE < lowestError: lowestError = rssE wsMax = wsTest ws = wsMax.copy() returnMat[i,:]=ws.T return returnMat
逐步线性回归主要优点在于它可以帮助人们理解现有模型并做出改进。当构建一个模型后,运行该算法找出重要的特征,这样就可以及时停止对那些不重要特征的收集。当应用缩减方法时,模型增加了偏差(bias),也减少了方差。
对数几率回归(逻辑回归)
上面是回归任务,如果我们需要的是分类任务呢?我们只需要找一个单调可微函数将分类任务的真实标记与线性回归的预测值就可以了。
二分类最理想的是“单位阶跃函数”(unit-step function)。但是此函数不连续,于是我们希望找一个单调可微的替代函数:
logistic function是一种Sigmoid函数,我们将z代入线性回归模型:
变换一下:
如果y是正样本的可能性,那么1-y就是负样本的可能性,两者比值称为几率,左边的意义就是对数几率。
实际上上式是在用线性回归的模型预测结果去逼近真实标记的对数几率。虽然名字叫“回归”,却是一种分类方法。这种方法优点很多,它直接对分类可能性进行建模,无需事先假设数据分布。此外,对率函数是任意阶可导的凸函数,利用现有的数值优化算法可以直接得到最优解。
下面来看以下具体推导:
假设y=1是二分类中正样本,
于是,我们采用极大似然来估计w和b:
即令每个样本属于其真实标记的概率越大越好。
我们可以再转换成最小值问题,用经典的数值优化算法如梯度下降法(gradient descent method),牛顿法(Newton method)解决。
在此处我们简便起见,直接采用梯度上升算法。我们知道梯度算子总是指向函数值最快的方向。我们每次向增长最快的方向移动一个值,称为步长,记为
该公式将一直迭代执行,直到达到某个停止条件(比如迭代次数)为止。
实现代码为:(当然之前数据先标准化)
def gradAscent(dataMatIn, classLabels): dataMatrix = mat(dataMatIn) labelMat = mat(classLabels).transpose() m,n = shape(dataMatrix) alpha = 0.001 maxCycles = 500 weights = ones((n,1)) for k in range(maxCycles): h = sigmoid(dataMatrix*weights) error = (labelMat - h) #vector subtraction weights = weights + alpha * dataMatrix.transpose()* error return weights
代码中求导不好操作,这里我们用差分可以起到同样的效果。
梯度上升算法在每次更新回归系数时要遍历整个数据集,改进方法是一次仅用一个样本点来更新回归系数,称为“随机梯度上升算法”,这是一种在线算法。上述代码仍有改进之处,比如
改进后的随机梯度上升代码如下:
def stocGradAscent(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
这里用个例子来使用Logistic回归来预测患有疝病的马存活问题。但是我们发现了样本数据缺失问题,通常的解决方法有:
- 使用可用特征均值填补
- 使用特殊值来填补缺失值,如-1
- 忽略有缺失值的样本
- 使用相似样本的均值填补
- 使用另外的机器学习算法预测缺失值
- …
这里我们全部用0来代替缺失值,这样在更新时不会影响系数。即特征对应0时,系数将保持0.5。我们在数据中还发现了标签缺失,这个在强化学习中可以通过更靠近某些标签就将其标记为那个标签,在本例中由于此类较少,我们直接丢弃。
线性判别分析
(Linear Discriminant Analysis,LDA)与LDA(Latent Dirichlet Allocation)算法不要搞混了哦,虽然简写都是一样的。
LDA的思想很简单:设法将样例投影到一条直线上,使得同类样例的投影点近可能接近,异类样例的投影尽可能原理,在对新样本进行分类时,将其投影到这条直线上,再根据投影点位置来确定分类。
多分类学习
二分类问题推广到多分类主要用拆解法,主要策略有:
- 一对一
- 一对多
- 多对多
这样那个容易碰到类别不平衡问题,就是某类的数据量特别大或者特别少。
最后就是本文数据集和代码的下载地址啦,请点击这里。
- 机器学习之回归模型
- 机器学习之线性回归模型
- 机器学习之逻辑回归改善模型
- 机器学习之线性回归模型
- 机器学习-广义回归模型
- 机器学习之——线性回归模型及其扩展
- 机器学习——线性模型之回归与分类
- 机器学习——线性模型之逻辑回归
- 机器学习——线性模型之softmax回归
- 机器学习笔记(3)线性模型之线性回归
- 机器学习之回归
- 机器学习之回归
- 机器学习教程 之 线性模型:线性回归、对数几率回归、线性判别分析
- 【机器学习】贝叶斯线性回归模型
- [机器怎么老学习]线性回归模型
- 机器学习实战(二)线性回归模型
- 机器学习实例-线性回归模型
- spark机器学习构建回归模型
- Postgresql+ArcGIS数据对接
- Java小知识
- 第六周项目三-IP地址类
- 银行系统
- 第五周项目三 时间类(2)
- 机器学习之回归模型
- js中clone的运用和clone后datepicker的显示问题
- Intent数据传递
- oc: Runtime
- hdu1402 A*B FFT
- 博客用途
- note-网络-TCP-客户端
- java安装的环境配置
- 交换排序总结(快排,冒泡)