机器学习算法--回归

回归主要用来解决数值预测问题,给定数据集D={(xi, yi)} ,xi={xi1,xi2...xid} 即每个样本有d个属性,求出x与y的最佳拟合曲线。

1.线性回归

假设x与y之间存在线性关系:

将数据矩阵进行处理,添加x0=1这一项,将b看成w参数的一部分,即:

若使线性方程能够很好地你和所有点,这里使用均方误差作为优化目标:

 对于W求导有:

导数等于零,可以解得:

其中当XTX是满秩矩阵时。

若XTX不是满秩,一般通过引入正则化的方式来求解。

数据集准备:  数据X只有一个属性特征  第一列为处理加入的数据

加载数据集  转换成数据矩阵X以及类别向量Y

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 plot(xArr, yArr, ws):
    xMat = mat(xArr)
    yMat = mat(yArr)
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111)
    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.show()

首先绘出数据集的分布,然后将X排序,再与回归系数ws相乘,得到样本点的预测值,画出最佳拟合曲线

预测值yHat与真实值yMat的匹配程度,使用相关系数来计算:

协方差:如果两个变量的变化趋势一致,其中一个大于自身的期望值时另外一个也大于自身的期望值,两个变量之间的协方差就是正值;如果两个变量的变化趋势相反,即其中一个变量大于自身的期望值时另外一个却小于自身的期望值,那么两个变量之间的协方差就是负值。

相关系数:相关系数是用以反映变量之间相关关系密切程度的统计指标。相关系数也可以看成协方差:一种剔除了两个变量量纲影响、标准化后的特殊协方差,它消除了两个变量变化幅度的影响,而只是单纯反应两个变量每单位变化时的相似程度。

计算结果如下所示:

当数据集并不是线性关系时,拟合效果不好,容易欠拟合。

2.局部加权线性回归LWLR

高斯核:对于靠近测试点的样本点,赋予更大的权值。距离测试点越远的样本点,权值越小。

k的取值影响了权重大小的分配情况

局部加权线性回归的模型:

最终解:

其中W为只含对角元素的权重矩阵,给与数据点的附近点赋予相应的权重。

求解LWLR,求出回归系数以及权重矩阵,给出预测值

def lwlr(testPoint,xArr,yArr,k=1.0):
    xMat = mat(xArr); yMat = mat(yArr).T
    m = shape(xMat)[0]
	#声明一个对角矩阵  对角线为1  其余为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

eye生成一个对角矩阵  对角为1其余为0.高斯核,当样本向量X多维时,应该计算向量的模。

结合数据集D,绘出数据分布以及拟合曲线

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 lwlrplot(k):
    xArr, yArr = loadDataSet('ex0.txt')
    xMat = mat(xArr)
    yMat = mat(yArr)
    yHat = lwlrTest(xArr, xArr, yArr, k)
    srtInd = xMat[:,1].argsort(0)
    #print(srtInd)
    xSort = xMat[srtInd][:,0,:]
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(xSort[:,1], yHat[srtInd])
    ax.scatter(xMat[:,1].flatten().A[0], yMat.T[:,0].flatten().A[0], s=2, c='red')
    plt.show()

x.argsort()  将x中的元素从小到大排列提取其对应的index(索引),然后输出到y

改变高斯核参数K,从1,0.01以及0.003可以任意k=0.01时拟合较好,第一种出现欠拟合  第三种出现过拟合

         

LWLR增加了计算量,每次都必须使用整个数据集

下面以鲍鱼数据进行测试比较

数据集样本如下:

平方误差之和的实现:

 这里不需要平均m

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

采用LWLR,前100行作为训练样本,后100行作为测试样本,改变高斯核来观察曲线的拟合程度:

def testRssError():
    abX, abY = loadDataSet('abalone.txt')
    yHat01 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 0.1)
    yHat1 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 1)
    yHat10 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 10)
    print('train error k = 0.1 ', rssError(abY[0:99], yHat01.T))
    print('train error k = 1 ', rssError(abY[0:99], yHat1.T))
    print('train error k = 10 ', rssError(abY[0:99], yHat10.T))

可知随着k的减小,平方误差越来越小,当K过于小时,易出现过拟合。

在测试集上,K很小时,误差很大,说明出现了过拟合。最后一项为线性回归的误差分析。

猜你喜欢

转载自blog.csdn.net/u014106644/article/details/83510279