回归

回归

线性回归

回归系数求解方法:常用最小二乘法

缺点:由于采用具有最小均方误差的无偏估计,可能出现欠拟合现象
解决办法: 局部加权线性回归

局部加权线性回归(Locally Weighted Linear Regression, LWLR)

思想:给待测点附近每一个点赋予一定的权重,在这个子集上基于最小均方差进行普通回归

与KNN一样这种算法每次预测都需要事先选取对应数据子集

LWLR: 使用了“核”(与支持向量机中的核类似)来对附近的点赋予更高的权重。核的类型可以

自由选择,最常用的核是高斯核

\[高斯核公式 \]

缺点:增加了计算量,由于对每个点最预测时,都必须使用数据集。

解决方式:缩减技术

缩减技术

缩减系数来“理解”数据

特征比样点多,即不是矩阵不是满秩矩阵,则求解矩阵的秩时会出问题

则无法使用线性回归和之前的方法来做预测,解决方法如下:

1 岭回归

使用场景:特征数多于样本数情况

普通回归方法可能产生错误,岭回归仍然可以正常工作,但同时也需要对数据进行检查

所以,使用岭回归和缩减技术,首先需要对特征做标准化处理

2 lasso

普通的最小二乘法会得到与岭回归一样的公式

所有回归系数平方和不能大于lambda,lasso也类似对回归系数有限定,回归系数的绝对值之和不大于lambda

缺点:计算复杂,因为需要求出回归系数,要使用二次规划算法

3 前向逐步回归

优点:可以得到与lasso差不多效果,但更加简单,属于贪心算法

每一步尽可能减少误差

缺点:使用缩减技术时,模型增加了偏差,此时也减小了模型的方差,处理方法如下

权衡偏差和方差

树回归

代码实践

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
回归
"""
from numpy import *



def loadDataSet(fileName):
    fr = open(fileName)
    numFeat = len(fr.readline().split('\t')) - 1
    dataMat = []
    labelMat = []
    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:
        print(f'This matrix is singular, cannot do inverse')
        return
    ws = xTx.I * (xMat.T * yMat)

    return ws


def lwlr(testPoint, xArr, yArr, k=1.0):
    """
    局部加权线性回归
    :param testPoint:
    :param xArr:
    :param yArr:
    :param k:
    :return:
    """
    xMat = mat(xArr)
    yMat = mat(yArr).T
    m = shape(xMat)[0]
    weights = mat(eye((m)))
    for j in range(m):
        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:
        print(f'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):
    """
    局部加权回归测试
    :param testArr:
    :param xArr:
    :param yArr:
    :param k:
    :return:
    """
    m = shape(testArr)[0]
    yHat = zeros(m)
    for i in range(m):
        yHat[i] = lwlr(testArr[i], xArr, yArr, k)
    return yHat


def ridgeRegres(xMat, yMat, lam=0.2):
    """
    岭回归,计算回归系数
    :param xMat:
    :param yMat:
    :param lam:
    :return:
    """
    xTx = xMat.T * xMat
    denom = xTx + eye(shape(xMat)[1]) * lam
    if linalg.det(denom) == 0:
        print(f'This matrix is singular, cannot do inverse')
        return
    ws = denom.I * (xMat.T * yMat)

    return ws


def ridgeTest(xArr, yArr):
    """
    岭回归测试, 用于一组lambda下岭回归求解
    :param xArr:
    :param yArr:
    :return:
    """
    xMat = mat(xArr)
    yMat = mat(yArr).T
    yMean = mean(yMat, 0)
    # 数据标准化
    yMat = yMat - yMean
    xMeans = mean(xMat, 0)
    xVar = var(xMat, 0)
    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




def stageWise(xArr, yArr, eps=0.01, numIt=100):
    """
    逐步向前
    :param xArr:
    :param yArr:
    :param eps:
    :param numIt:
    :return:
    """
    xMat = mat(xArr)
    yMat = mat(yArr).T
    yMean = mean(yMat, 0)
    yMat = yMat - yMean
    # 数据标准化
    # xMat = regularize(xMat)

    xMeans = mean(xMat, 0)
    xVar = var(xMat, 0)
    xMat = (xMat - xMeans) / xVar

    m, n = shape(xMat)
    returnMat = zeros((numIt, n))
    ws = zeros((n , 1))
    wsTest = ws.copy()
    wsMax = ws.copy()
    for i in range(numIt):
        print(f'{ws.T}')
        lowerError = inf
        for j in range(n):
            wsTest = ws.copy()
            wsTest[j] += eps * sign
            yTest = xMat * wsTest
            rssE = rssError(yMat.A, yTest.A)
            if rssE < lowerError:
                lowerError = rssE
                wsMax = wsTest
        ws = wsMax.copy()
        returnMat[i, :] = ws.T

    return returnMat
posted @ 2022-09-14 13:34  酷酷的排球  阅读(124)  评论(0编辑  收藏  举报