利用回归预测数值型数据

目录

源码下载

一、用线性回归找到最佳拟合直线

二、局部加权线性回归

三、示例:预测鲍鱼的年龄

源码下载

GitHub - 1578630119/Regression

利用逻辑回归可以实现分类,将直线的两侧划分为两类。现在要利用线性回归实现对连续型的数据做出预测,例如销售量预测或者制造缺陷预测等。

一、用线性回归找到最佳拟合直线

线性回归

优点:结果易于理解,计算上不复杂。

缺点:对非线性的数据拟合不好。

适用数据类型:数值型和标称型数据。

\mathrm{Y_{1}=X_{1}^{T}w}\rightarrow y=w_0x_0+w_1x_1+w_2x_2+\cdots+w_nx_n

假设输入数据存放在X矩阵[x0,x1,....,xn]中,而回归系数存放在向量w[w0,w1,...,wn]中。我们需要用手里已知的一些X和对应的Y来找到w的。一个常用的方法是找出使误差最小的w,这里的误差是指预测y值和真实的y值之间的差值,使用该误差的简单累加将使得正差值和负差值相互抵消,所以采用平方误差。平方误差可以写做:

\sum_{i=1}^m(y_i-x_i^\mathrm{T}w)^2

用矩阵表示还可以写做(y-Xw)^T(y-Xw),如果对w求导,得到X^T(Y-Xw),令其等于0,解出w如下:

\hat{w}=(X^{\intercal}X)^{-1}X^{\intercal}y

w上方的小标记表示这是当前可以估计出的w的最优解。从现有的数据上估计出的w可能并不是数据中的真实w值,所以这里使用了一个“帽”符号来表示它仅是w的一个最佳估计。这种最佳w求解是统计学中常见问题,在代码中可以调用Numpy库里的矩阵方法,该方法也称作OLS,意思是“普通最小二乘法”(ordinary least squares)。

从ex0.txt得到的样例数据

针对于ex0.txt中的数据,利用上面的方法求出该数据的最佳拟合直线

def load_data_set(file_name):
    #提取txt文本中的数据,将特征保存在data_mat中,真实标签保存在label_mat中。
    num_feat = len(open(file_name).readline().split('\t')) - 1
    data_mat = []
    label_mat = []

    with open(file_name, 'r') as fr:
        for line in fr.readlines():
            line_arr = []
            cur_line = line.strip().split('\t')
            for i in range(num_feat):
                line_arr.append(float(cur_line[i]))
            data_mat.append(line_arr)
            label_mat.append(float(cur_line[-1]))
    return data_mat, label_mat


def stand_regres(x_arr, y_arr):
    x_mat = np.mat(x_arr)     #转为numpy矩阵类型
    y_mat = np.mat(y_arr).T   #转为numpy矩阵类型同时转置
    xTx = x_mat.T * x_mat      #X的转置 * X

    if np.linalg.det(xTx) == 0.0:  #判断矩阵的逆矩阵是否存在
        print("This matrix is singular, cannot do inverse")
        return

    ws = xTx.I * (x_mat.T * y_mat)  #(X的转置 * X)求逆后*(X的转置 * Y)
    return ws

ex0.txt的数据集与它最佳拟合直线

二、局部加权线性回归

线性回归的一个问题是有可能出现欠拟合现象,上面的数据集和它的最佳拟合直线可以看出,模型欠拟合对预测无法取得最好的效果。处理这种情况的一个方法是局部加权线性回归(Locally weighted Linear Regression,LWLR),该算法给待预测点附近的每个点赋予一定的权重。与第一节类似,在这个子集上基于最小均方差来进行普通的回归,与kNN一样,这种算法每次预测均需要事先选取出对应的数据子集,该算法解出回归系数w的形式如下:

\hat{w}=(X^{\mathrm{T}}WX)^{-1}X^{\mathrm{T}}Wy

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

LWLR使用“核”来对附近的点赋予更高的权重,核的类型可以自由选择,最常用的核就是高斯核,高斯核对应的权重如下:

w(i,i)=\exp\left(\frac{\left|x^{(i)}-x\right|}{-2k^{2}}\right)

这样就构建了一个只含对角元素的权重矩阵w,并且点x与x(i)越近,w(i,i)将会越大。公式中的k是用户指定的参数k,他决定对附近的点赋予多大的权重。

 局部加权线性回归函数

def lwlr(test_point, x_arr, y_arr, k=1.0):
    x_mat = mat(x_arr)
    y_mat = mat(y_arr).T
    m = shape(x_mat)[0]
    weights = np.mat(np.eye((m))) #生成m*m的单位矩阵

    for j in range(m):
        diff_mat = test_point - x_mat[j, :] #x-x(i)
        weights[j, j] = exp(diff_mat * diff_mat.T / (-2.0 * k**2))  #高斯核
    xTx = x_mat.T * (weights * x_mat)   #X的转置*(高斯核 * X)

    if linalg.det(xTx) == 0.0:
        print("This matrix is singular, cannot do inverse")
        return

    ws = xTx.I * (x_mat.T * (weights * y_mat)) #LWLR
    return test_point * ws


def lwlr_test(test_arr, x_arr, y_arr, k=1.0):
    #测试函数,得到通过LWLR得到的模型预测结果
    m = shape(test_arr)[0]
    y_hat = zeros(m)

    for i in range(m):
        y_hat[i] = lwlr(test_arr[i], x_arr, y_arr, k)
    return y_hat
k=1

k=0.01
k=0.003

上面三张图是高斯核中k在三种不同取值下的结果图,当k=1.0时权重很大,如同将所有的数据视为等权重,得出的最佳拟合直线与标准的回归一致。使用k=0.01得到了非常好的效果,抓住了数据的潜在模式。下图使用k=0.003纳入了太多的噪声点,拟合的直线与数据点过于贴近。局部加权线性回归也存在一个问题,即增加了计算量,因为它对每个点做预测时都必须使用整个数据集。

三、示例:预测鲍鱼的年龄

本节将利用回归用于真实数据,在data目录下有一份来自UCI数据集合的数据,记录了鲍鱼(一种介壳类水生动物)的年龄。鲍鱼的年龄可以从鲍鱼壳的层数推算得到。

需要添加以下代码计算预测结果和真是结果之间的差距。

def rss_error(y_arr, y_hat_arr):
    return ((y_arr - y_hat_arr) ** 2).sum()

结果如下:

  • 30
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值