封闭式岭回归

时间:2019-02-19 17:22:20

标签: python numpy machine-learning regression linear-algebra

我无法理解实现多岭回归的函数输出。我在Python中从头开始为方法的封闭形式进行此操作。此关闭的表单如下所示:

Closed form

我有一个X的训练集100 rows x 10 columns和一个y的向量100x1

我的尝试如下:

def ridgeRegression(xMatrix, yVector, lambdaRange):
    wList = []

    for i in range(1, lambdaRange+1):
        lambVal = i

        # compute the inner values (X.T X + lambda I)
        xTranspose = np.transpose(x)
        xTx = xTranspose @ x
        lamb_I = lambVal * np.eye(xTx.shape[0])

        # invert inner, e.g. (inner)**(-1)
        inner_matInv = np.linalg.inv(xTx + lamb_I)

        # compute outer (X.T y)
        outer_xTy = np.dot(xTranspose, y)

        # multiply together
        w = inner_matInv @ outer_xTy
        wList.append(w)

    print(wList)

为了进行测试,我使用前5个lambda值运行它。 wList变成5个numpy.arrays,每个长度为10(我假设是10个系数)。

这是这5个数组中的第一个:

array([ 0.29686755,  1.48420319,  0.36388528,  0.70324668, -0.51604451,
        2.39045735,  1.45295857,  2.21437745,  0.98222546,  0.86124358])

我的问题和澄清:

应该没有11个系数(y截距1个+ 10个斜率)吗? 如何从此计算中获得Minimum Square Error? 如果我想绘制这条线,接下来会发生什么?

由于我仍在研究线性代数,所以我对所要查看的内容感到非常困惑。

谢谢!

3 个答案:

答案 0 :(得分:2)

首先,我将修改岭回归以使其类似于以下内容:

import numpy as np
def ridgeRegression(X, y, lambdaRange):
    wList = []
    # Get normal form of `X`
    A = X.T @ X 
    # Get Identity matrix
    I = np.eye(A.shape[0])
    # Get right hand side
    c = X.T @ y
    for lambVal in range(1, lambdaRange+1):
        # Set up equations Bw = c        
        lamb_I = lambVal * I
        B = A + lamb_I
        # Solve for w
        w = np.linalg.solve(B,c)
        wList.append(w)        
    return wList

请注意,我用一个隐式求解替换了您的inv调用来计算矩阵逆。这在数值上更加稳定,尤其是对于这些类型的问题而言,这是一个重要的考虑因素。

我还将循环中的A=X.T@X计算,单位矩阵I生成和右侧向量c=X.T@y计算从循环中移除了,这些在循环中不会改变并且计算起来相对昂贵。

正如@qwr指出的那样,X的列数将确定您拥有的系数数。您尚未描述模型,因此尚不清楚基础域x是如何构建为X的。

传统上,人们可能会使用多项式回归,在这种情况下,XVandermonde Matrix。在那种情况下,第一系数将与y轴截距相关。但是,根据问题的背景,您似乎对多元线性回归感兴趣。无论如何,都需要明确定义模型。一旦确定,则可以使用返回的权重进一步分析您的数据。

答案 1 :(得分:1)

  1. 通常使表示法更紧凑,矩阵X包含一列用于截距的列,因此,如果您有p个预测变量,则矩阵的维度为n p+1。有关示例,请参见Wikipedia article on linear regression

  2. 要计算样本内MSE,请使用MSE的定义:残差平方的平均值。要计算泛化误差,您需要交叉验证。

答案 2 :(得分:1)

此外,您不应该将lambVal用作整数。如果目的只是为了避免在xTx状况不佳时避免数值错误,则可以将其设置为较小(接近0)。

我建议您使用对数范围而不是线性范围,如果您愿意,请从0.001开始,增加到100或更大。例如,您可以将代码更改为:

powerMin = -3
powerMax = 3

for i in range(powerMin, powerMax):
    lambVal = 10**i
    print(lambVal)

然后,使用交叉验证的数据找出lambVal的正确顺序后,可以尝试使用较小的范围或线性范围。