机器学习随笔——线性回归

预测型数据:回归

一、概述

1.1回归

“回归”一词的来历: 今天我们知道的  回归是由达尔文(Charles Darwin)的表弟Francis Galton发明的。Galton于1877年完成了第一次回归预测,目的是根据上一代豌豆种子(双亲)的尺寸来预测下一代豌豆种子(孩子)的尺寸。Galton在大量对象上应用了回归分析,甚至包括人的身高。他观察到,如果双亲的身高高于平均身高,他们的子代也倾向于高于平均身高但不及双亲高。子代的身高向着平均身高回退(回归)。

  提及回归一般是指线性回归(Linear Regression),至于非线性回归,本文先不做相关说明。在回归方程中,求回归系数的过程就是回归。

  和之前分类得到的离散型数据相比,这里的回归是为了处理连续型目标数据,所以,回归的目的也就是预测数值型目标变量值。

1.2最小二乘法

  最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找到数据的最佳匹配函数。在一元线性回归方程中,最小化乘法的原则是以“参差平方和最小”确定拟合直线的位置。

  我们应该怎样从一大堆数据里求出回归方程呢? 假定输入数据存放在矩阵 x 中,而回归系数存放在向量 w 中。那么对于给定的数据 X1,预测结果将会通过 Y = X1^T w 给出。现在的问题是,手里有一些 X 和对应的 y,怎样才能找到 w 呢?一个常用的方法就是找出使误差最小的 w 。这里的误差是指预测 y 值和真实 y 值之间的差值,使用该误差的简单累加将使得正差值和负差值相互抵消,所以我们采用平方误差(实际上就是我们通常所说的最小二乘法)。  平方误差可以写做(也就是回归中使用的 loss function):

w是当前可以估计的最优解:

二、线性回归流程

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

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

3.分析数据:绘制出可视化的二维图将有助于对数据进行理解和分析,在采用缩减法求得新的回归系数之后,可以将新的拟合线绘制在图上进行比较分析。      

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

5.测试算法:使用R^2或者预测值与数据的拟合度,来分析模型的效果。      

6.使用算法:使用回归,可以在给定输入时预测出一个数值,这是对分类算法的提升,因为这样可以预测连续型数据而不仅仅只预测离散型的分类标签。

 

例子:ex0.txt数据集及最佳拟合曲线

机器学习随笔——线性回归_第1张图片

 

3、局部加权线性回归

  线性回归中可能会遇到的一个问题是出现欠拟合现象,因为它要求的是具有最小均方误差的无偏估计。显然,如果模型欠拟合将不能取得最好的预测效果。所以有些方法允许引入一些偏差,进而降低预测的均方误差。这里的局部加权线性回归(Locally Weights Linear Regression, LWLR)就是其中方法之一。在该算法中,我们给予待预测点附近的每个点赋予一定的权重,与上面简单线性回归类似,基于这个子集上基于最小均方差来进行普通回归。

 

具体流程:

(1)用高斯核函数计算出第i个样本处,其它所有样本点的权重W  

(2)用权重w对第i个样本作加权线性回归,得到回归方程,即拟合的直线方程

(3)用刚才得到的经验回归直线计算出xi处的估计值y^i

(4)重复一至三步,得到每个样本点的估计值

 

个人理解:

1、局部加权线性回归,对于样本的预测,其实就是对每个点的预测(或者说拟合),样本点有m个点,则预测出来的也是m个点,而这m个点不在一条直线上,而是离散的点,因此最终拟合的'线性'(实为非线性)曲线则是m个点的(m-1条线段)组成的估计曲线。

 2、在对测试集上的样本点进行预测时,需要依赖于训练集数据集合,因为它需要计算该点与所有点的'距离',来给出不同的权值。

 

高斯核函数

 机器学习随笔——线性回归_第2张图片

  我们可以注意到,k的取值越小,权重衰减的越快,仅仅在要预测的点附近很有限的数据点才可以对回归系数的学习起到作用,其他的数据点权重为0无法参与到回归系数的学习过程当中。

 

例子:

机器学习随笔——线性回归_第3张图片

k=0.01

机器学习随笔——线性回归_第4张图片

 

k=0.1

4.预测鲍鱼年龄

  机器学习随笔——线性回归_第5张图片

使用较小的核得到较低的训练误差,但会导致过拟合,也即对新的数据预测的效果比较糟糕。在简单线性回归中,达到了与局部加权线性回归类似的效果,在未知数据中,比较效果才能选取到最佳模型。


参考文献:

机器学习实战——Peter Harrington 著    人民邮电出版社出版


代码实现:

from numpy import *

def loadDataSet(fileName):      #general function to parse tab -delimited floats
    numFeat = 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).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

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

def lwlrTest(testArr,xArr,yArr,k=1.0):  #loops over all the data points and applies lwlr to each one
    m = shape(testArr)[0]
    yHat = zeros(m)
    for i in range(m):
        yHat[i] = lwlr(testArr[i],xArr,yArr,k)
    return yHat

def rssError(yArr,yHatArr): #yArr and yHatArr both need to be arrays
    return ((yArr-yHatArr)**2).sum()

你可能感兴趣的:(机器学习随笔——线性回归)