1,用线性回归找到最佳拟合直线

回归的目的是预测数值型的目标值。

回归方程(regression equation)主要是求回归系数,一旦有了回归系数,在给定输入,做预测就是用回归系数乘以输入值,在将结果全部加在一起,就得到了预测值。(因为回归系数是一个向量,输入也是向量,这些运算就是求出二者的内积)

回归的一般方法:

1)收集数据:采用任意方法收集数据

2)准备数据:回归需要数值型数据,标称型数据将被转换为二值型数据

3)分析数据,二维图

4)训练算法:找到回归系数

5)测试算法:使用或者预测值和数据的拟合度,来分析模型的效果

6)使用算法:使用回归,在给定的时候预测出一个数值

求回归方程:

假定输入数据存放在矩阵X中,而回归系数存放在向量w中。那么对于给定的数据,预测结果将会通过给出。通过x,y数据找到回归系数向量w,一个常用的方法是找出误差最小的w。这里的误差是指预测值和真实值之间的差值。避免正差值和负差值之间相互抵消,因此采用平方误差。

平方误差可以写作

用矩阵表示还可以写作,如果对w求导,得到,令其等于零,解出w

w上方的小标记表示,这事当前可以估计出的w的最优解,从现有数据上估计出的w可能并不是数据中的真实值,所以这里使用了一个"帽"符号来表示是w的一个最佳估计。注意:公式中包含,也就是需要对矩阵求逆,代码中需要判断矩阵的逆到底存不存在

另外还可以使用NumPy库中的矩阵方法,该方法叫OLS,意思是“普通最小二乘法”(ordinary least squares)

from numpy import *#加载数据
def loadDataSet(fileName):      #general function to parse tab -delimited floatsnumFeat = len(open(fileName).readline().split('\t')) - 1 #get number of fields dataMat = []; labelMat = []fr = open(fileName)for line in fr.readlines():lineArr =[]curLine = line.strip().split('\t')for i in range(numFeat):lineArr.append(float(curLine[i]))dataMat.append(lineArr)labelMat.append(float(curLine[-1]))return dataMat,labelMat#返回回归系数
def standRegres(xArr,yArr):xMat = mat(xArr); yMat = mat(yArr).TxTx = xMat.T*xMatif linalg.det(xTx) == 0.0:# det判断行列式print ("This matrix is singular, cannot do inverse")returnws = xTx.I * (xMat.T*yMat)return wsimport matplotlib.pyplot as plt
xmat=mat(xarr)
ymat=mat(yarr)
yhat=xmat*ws
fig=plt.figure()
ax=fig.add_subplot(111)
#a是个矩阵或者数组,a.flatten()就是把a降到一维,默认是按横的方向降
# 此时的a是个矩阵,降维后还是个矩阵,矩阵.A(等效于矩阵.getA())变成了数组,A[0]就是数组里的第一个元素
ax.scatter(xmat[:,1].flatten().A[0],ymat.T[:,0].flatten().A[0])
xCopy=xmat.copy()
xCopy.sort(0)
yhat=xCopy*ws
ax.plot(xCopy[:,1],yhat)
plt.savefig("2.png")
plt.show()

几乎任意数据集都可以用上述方法建立模型,但是判断模型的好坏,可以通过计算着两个序列的相关系数来,计算预测值yHat序列和真实值y序列的匹配程度。

yhatT=yhat.T
coef=corrcoef(yhatT,ymat)
print(coef)[[1.         0.13653777][0.13653777 1.        ]]

2,局部加权线性回归

线性回归的一个问题是有可能出现欠拟合现象,因为它求的是具有最小均方误差的无偏估计。

局部加权线性回归(Locally weighted linear regression,LWLR)。在该算法中,给每个待测点附近的每个点赋予一定的权重;然后基于最小均方差来进行普通的回归。

其中w是一个矩阵,用来给每个数据点赋予权重

LWLR使用“核”(与支持向量机中的核类似)来对附近的点赋予更高的权重。核的类型可以自由选择,最常用的核是高斯核,高斯核对应的权重如下

这样就构建了一个只含有对角元素的权重矩阵,并且点x与x(i)越近,w(i,i)将会越大()。参数k,决定了对附近的点赋予多大的权重,这也是LWLR时唯一需要考虑的参数,

import matplotlib.pyplot as pltdef lwlr(testPoint,xArr,yArr,k=1.0):xMat = mat(xArr); yMat = mat(yArr).Tm = shape(xMat)[0]weights = mat(eye((m)))for j in range(m):                      #next 2 lines create weights matrixdiffMat = 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")returnws = xTx.I * (xMat.T * (weights * yMat))return testPoint * wsdef lwlrTest(testArr,xArr,yArr,k=1.0):  #loops over all the data points and applies lwlr to each onem = shape(testArr)[0]yHat = zeros(m)for i in range(m):yHat[i] = lwlr(testArr[i],xArr,yArr,k)return yHatxarr,yarr=loadDataSet('ex0.txt')
xmat=mat(xarr)
ymat=mat(yarr)
yhat=lwlrTest(xarr,xarr,yarr,0.01)
srcInd=xmat[:,1].argsort(0)
xsort=xmat[srcInd][:,0,:]
print(xsort)
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(xsort[:,1],yhat[srcInd])
ax.scatter(xmat[:,1].flatten().A[0],mat(yarr).T.flatten().A[0],s=2,c='red')
plt.show()

局部加权线性回归也存在一个问题,即增加了计算量,因为他对每个点做预测是都必须使用整个数据集

3,预测鲍鱼的年龄

使用较小的核将得到较低的误差,但是不能所有数据集都使用最小的核,因为使用最小的核将造成过拟合,对新数据不一定能达到最好的预测效果。

4,缩减发来“理解”数据,

如果数据的特征比样本点还多,就不能使用之前的方法来做预测。因为计算的时候回报错。特征比样本点还多(n>m),也就是说输入数据的矩阵X不是满秩矩阵。非满秩矩阵在求逆向时会出现问题。一般采用岭回归和lasso回归

4.1岭回归(ridge regression)

岭回归就是在矩阵上加一个I 求逆,其中矩阵I是mxm的单位矩阵,是用户定义的一个数值,回归系数变为

岭回归最先用来处理特征数多于样本数的情况,现在也用于在估计中加入偏差,从而得到更好的估计。通过限制来限制所有w之和,通过引入惩罚性,能够减少不重要的参数,能更好的理解数据,这个技术叫做缩减(shrinkage)

通过预测误差最小化得到。通过选取不同的来重复上述测试过程,最终得到一个是测试误差最小的

import matplotlib.pyplot as plt#岭回归
def ridgeRegres(xMat,yMat,lam=0.2):xTx = xMat.T*xMatdenom = xTx + eye(shape(xMat)[1])*lamif linalg.det(denom) == 0.0:print("This matrix is singular, cannot do inverse")returnws = denom.I * (xMat.T*yMat)return wsdef ridgeTest(xArr,yArr):xMat = mat(xArr); yMat=mat(yArr).TyMean = mean(yMat,0)yMat = yMat - yMean     #to eliminate X0 take mean off of Y#regularize X'sxMeans = mean(xMat,0)   #calc mean then subtract it offxVar = var(xMat,0)      #calc variance of Xi then divide by itxMat = (xMat - xMeans)/xVar #特征数据标准化处理 numTestPts = 30wMat = zeros((numTestPts,shape(xMat)[1]))for i in range(numTestPts):ws = ridgeRegres(xMat,yMat,exp(i-10))wMat[i,:]=ws.Treturn wMatabx,aby=loadDataSet('abalone.txt')
ridgeweights=ridgeTest(abx,aby)
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(ridgeweights)
plt.show()

4.2 lasso回归

增加如下约束时,普通的最小二乘法回归会得到与岭回归的一样的公式:

使用普通的最小二乘法回归在当两个或更多的特征相关时,可能会得出一个很大的正系数和一个很大的负系数。正是因为此约束条件存在,使用岭回归可以避免此问题。

与岭回归类似,另一个缩减方法lasso也对回归系数做了限定,对应的约束条件

此处约束条件使用绝对值取代了平方和。当足够小的时候,一些系数会因此被迫缩减到0,这个特性可以帮我们更好的理解数据。

4.3前向逐步回归

一种贪心算法,即每一步都尽可能减少误差。一开始所有权重都等于1,然后每一步所做的决策是对某个权重增加或减少一个很小的值。

'''
数据标准化,使其分布满足0均值和单位方差
在每轮跌倒过程中:设置当前最小误差lowestError为正无穷对每个特征:增大或缩小:改变一个系数得到一个新的w计算新w下的误差如果误差Error小于当前最小误差lowestError:设置wbest等于当前的w将w设置为新的wbest
'''
def regularize(xMat):#regularize by columnsinMat = xMat.copy()inMeans = mean(inMat,0)   #calc mean then subtract it offinVar = var(inMat,0)      #calc variance of Xi then divide by itinMat = (inMat - inMeans)/inVarreturn inMat#逐步线性回归算法的实现,与lasso做法相似单计算简单
def stageWise(xArr,yArr,eps=0.01,numIt=100):xMat = mat(xArr); yMat=mat(yArr).TyMean = mean(yMat,0)yMat = yMat - yMean     #can also regularize ys but will get smaller coefxMat = regularize(xMat)m,n=shape(xMat)#returnMat = zeros((numIt,n)) #testing code removews = zeros((n,1)); wsTest = ws.copy(); wsMax = ws.copy()for i in range(numIt):print(ws.T)lowestError = inf; #正无穷for j in range(n):for sign in [-1,1]:wsTest = ws.copy()wsTest[j] += eps*signyTest = xMat*wsTestrssE = rssError(yMat.A,yTest.A)if rssE < lowestError:lowestError = rssEwsMax = wsTestws = wsMax.copy()stagedata2=stageWise(abx,aby,0.001,5000)xmat=mat(abx)
ymat=mat(aby).T
xmat=regularize(xmat)
ym=mean(ymat,0)
ymat=ymat-ym
weights=standRegres(xmat,ymat.T)
print(weights.T)...
[[ 0.044 -0.011  0.12   0.022  2.023 -0.963 -0.105  0.187]]
[[ 0.0430442  -0.02274163  0.13214087  0.02075182  2.22403814 -0.99895312-0.11725427  0.16622915]]

可以看到进过5000次迭代后,逐步线性回归算法与常规的最小二乘法效果类似。该算法主要优点可以找出重要的特征,这样就可能及时停止对那些不重要特征的收集。

5,权衡偏差和方差

模型和测量之间存在差异,就出现了误差。对复杂的过程进行简化,这将导致差异的发生。

一般采用降低核大小和采用缩减法。缩减法通过吧一些特征的回归系数缩减到0,同时也就减少了模型的复杂度。

6,实例:预测乐高玩具套装的价格

用回归法预测乐高套装的价格:

1)收集数据:任何方式

2)准备数据:从返回的JSON中抽取价格

3)分析数据:可视化并观察数据

4)训练算法:构建不同的模型,采用逐步线性回归和直接的线性回归模型

5)测试算法:使用交叉验证来测试不同的模型,分析哪个效果最好

6)使用算法:这次练习的目标就是生产数据模型

6.1收集数据,

from time import sleep
import json
import urllib
def searchForSet(retX, retY, setNum, yr, numPce, origPrc):sleep(10) #防止短时间内有过多的api调用myAPIstr = 'AIzaSyD2cR2KFyx12hXu6PFU-wrWot3NXvko8vY'searchURL = 'https://www.googleapis.com/shopping/search/v1/public/products?key=%s&country=US&q=lego+%d&alt=json' % (myAPIstr, setNum)pg = urllib.request.urlopen(searchURL)retDict = json.loads(pg.read()) #打开和解析操作for i in range(len(retDict['items'])):try:currItem = retDict['items'][i]if currItem['product']['condition'] == 'new':newFlag = 1else: newFlag = 0listOfInv = currItem['product']['inventories']for item in listOfInv:sellingPrice = item['price']#信息过滤可以采用贝叶斯来判断,此处使用剪短的启发式if  sellingPrice > origPrc * 0.5: print("%d\t%d\t%d\t%f\t%f" % (yr,numPce,newFlag,origPrc, sellingPrice))retX.append([yr, numPce, newFlag, origPrc])retY.append(sellingPrice)except: print('problem with item %d' % i)def setDataCollect(retX, retY):searchForSet(retX, retY, 8288, 2006, 800, 49.99)searchForSet(retX, retY, 10030, 2002, 3096, 269.99)searchForSet(retX, retY, 10179, 2007, 5195, 499.99)searchForSet(retX, retY, 10181, 2007, 3428, 199.99)searchForSet(retX, retY, 10189, 2008, 5922, 299.99)searchForSet(retX, retY, 10196, 2009, 3263, 249.99)

2,训练算法:建立模型

使用 standRegres ,在新数据集上进行回归处理拿到ws,得到公式

#交叉验证测试回归
def crossValidation(xArr,yArr,numVal=10):m = len(yArr)                           indexList = range(m)errorMat = zeros((numVal,30))#create error mat 30columns numVal rowsfor i in range(numVal):trainX=[]; trainY=[]testX = []; testY = []random.shuffle(indexList) #对数据进行混洗for j in range(m):#create training set based on first 90% of values in indexListif j < m*0.9: trainX.append(xArr[indexList[j]])trainY.append(yArr[indexList[j]])else:testX.append(xArr[indexList[j]])testY.append(yArr[indexList[j]])wMat = ridgeTest(trainX,trainY)    #get 30 weight vectors from ridgefor k in range(30):#loop over all of the ridge estimatesmatTestX = mat(testX); matTrainX=mat(trainX)meanTrain = mean(matTrainX,0)varTrain = var(matTrainX,0)matTestX = (matTestX-meanTrain)/varTrain #regularize test with training paramsyEst = matTestX * mat(wMat[k,:]).T + mean(trainY)#test ridge results and storeerrorMat[i,k]=rssError(yEst.T.A,array(testY))#保存每个λ对应的多个误差值#print errorMat[i,k]meanErrors = mean(errorMat,0)#calc avg performance of the different ridge weight vectorsminMean = float(min(meanErrors))bestWeights = wMat[nonzero(meanErrors==minMean)]#can unregularize to get model#when we regularized we wrote Xreg = (x-meanX)/var(x)#we can now write in terms of x not Xreg:  x*w/var(x) - meanX/var(x) +meanYxMat = mat(xArr); yMat=mat(yArr).TmeanX = mean(xMat,0); varX = var(xMat,0)unReg = bestWeights/varXprint("the best model from Ridge Regression is:\n",unReg)print ("with constant term: ",-1*sum(multiply(meanX,unReg)) + mean(yMat))

通过交叉验证落后得到的的回归系数,存在大小不一,如果在特征很多的情况下,可以方便的选择出那些特征是关键的,那些特征是不重要的。

7,总结

回归与分类不同,分类预测离散型变量,回归预测连续性变量。求特征对应的最佳回归系数的方法是最小化误差的平方和。前提是的逆存在。数据集上计算的回归方程不一定是最佳的,可以使用预测yhat和原始值y,的相关性来度量回归方程的好坏。

当样本数比特征数还少的时候,的逆不能直接计算,可以考虑是用岭回归,

岭回归是缩减法的一种,相当于对回归系数的大小做了限制。另一种锁甲你发是lasso,lasso难以求解,可以考虑使用简单的逐步线性回归来求得近似结果

缩减法可以看成是对一个模型增加编差的同时减少方差。偏差方差折中是一个重要的概念

机器学习实战-预测数值型数据:回归相关推荐

  1. 机器学习实战—预测数值型数据:回归

    一.用线性回归找到最佳拟合直线 回归的目的是预测数值型的目标值,即依据输入写出一个目标值的计算公式. 这个公式就是所谓的回归方程,此处的HorsePower是我们要求的目标值,0.0015和-0.99 ...

  2. 机器学习实战(八)——预测数值型数据:回归

    机器学习实战(八)--预测数值型数据:回归 一.用线性回归找到最佳拟合曲线 1.线性回归与非线性回归 线性回归:具体是可以将输入项分别乘上一些常量,然后再进行求和得到输出 非线性回归:输入项之间不只是 ...

  3. 机器学习实战(八)预测数值型数据:回归

    文章目录 第八章 预测数值型数据:回归 8.1 用线性回归找到最佳拟合直线 8.1.1 线性回归 8.1.2数据可视化 8.1.3 求回归系数向量,并根据系数绘制回归曲线 8.2 局部加权线性回归(L ...

  4. Machine Learning in Action 读书笔记---第8章 预测数值型数据:回归

    Machine Learning in Action 读书笔记 第8章 预测数值型数据:回归 文章目录 Machine Learning in Action 读书笔记 一.回归 1.回归的一般过程 2 ...

  5. 机器学习实战——第八章(回归):回归——预测数值型数据

    前言 接着上一篇继续学习. 首先感谢博主:Jack-Cui 主页:http://blog.csdn.net/c406495762 回归博文地址:https://blog.csdn.net/c40649 ...

  6. 预测数值型数据:回归

    之前博客中,我有介绍到分类机器学习算法,分类的目标变量是标称型数据,本篇博客将重点对连续型的数据做出预测及回归算法.有些人会问:"回归能用来做什么?"其实回归能够做任何事情. 本文 ...

  7. 预测数值型数据:回归源码分析(1)

    回归模型比较简单,这里先简单介绍下,后面遇到难点再具体分析. 回归的一般方法: (1)收集数据:采用任意方法收集数据. (2)准备数据:回归需要数值型数据,标称型数据将被转成二值型数据. (3)分析数 ...

  8. 预测数值型数据:回归 源码分析(2)

    4. 缩减系数来"理解"数据 4.1 岭回归 如果数据的特征比样本点还多,那么就不能使用线性回归,因为在计算(XTX)−1(X^TX)^{-1}的时候会出错.也就是输入数据的矩阵X ...

  9. 机器学习实战第8章预测数值型数据:回归2

    1. Shrinkage(缩减) Methods 当特征比样本点还多时(n>m),输入的数据矩阵X不是满秩矩阵,在求解(XTX)-1时会出现错误.接下来主要介绍岭回归(ridge regress ...

最新文章

  1. 几种机器学习算法的偏差以及防范
  2. HDOJ 1914 The Stable Marriage Problem
  3. 如何查询电脑的文件系统的分类是哪一种?
  4. mysql5.7.14操作命令_Mysql5.7.14安装配置方法操作图文教程(密码问题解决办法)
  5. 【转】C#执行rar,zip文件压缩的几种方法及我遇到的坑总结
  6. 如何在VisualStudio中加入你自己的assembly的Intellisense?
  7. 腾讯注册狗头表情包商标
  8. 应急响应之ARP欺骗
  9. php 转换为自定义类,PHP面向对象教程之自定义类_PHP
  10. Windows自动更新API (1)
  11. 思科网院-网络简介----Packet Tracer交换机使用的基本操作
  12. MicrosoftActiveSync 安装
  13. 能否构成三角形的条件代码_初中阶段数学三角形相关知识点汇总,超全
  14. 国内搜索引擎技术现状
  15. android 设置壁纸上下显示不全,默认锁屏壁纸及锁屏壁纸被拉伸显示不全的问题...
  16. 07-图4 哈利·波特的考试(25 分)
  17. RestAssured实现POST请求
  18. SCL编程指南,常用样例
  19. 陌上谁家年少足风流?
  20. 影像匹配代码,论文:Remote sensing image matching featured by the optimal entropy classification

热门文章

  1. 线性动态规划-文件排版
  2. mac地址修改_全球首款支持电脑名称和MAC地址修改的浏览器 VMLogin超级防关联指纹浏览器 同时支持模拟真人输入,支持自定义经纬度...
  3. java.lang.NoClassDefFoundError: org/jdom2/Content
  4. cocos2d-x创建新项目模板
  5. spring 远程连接 rabbitMQ 报错
  6. 分析bootstrap class path not set in conjunction with -source 1.6
  7. 宽带DDC matlab,基于DDC和DUC的大带宽DRFM设计与实现
  8. 12月6日云栖精选夜读:语音购票、刷脸进站:上海联手阿里打造全球首个AI地铁之城...
  9. JMockit @mocked 注释标签
  10. Macbook M1 安装node(亲测)