如何对动态数据框执行 OLS 回归并估计斜率系数?

How to perform a OLS regression on dynamic data frame and estimate the slope coefficient?

我有一个如下所示的数据框,它的结构不固定,在不同的时刻它可以有不同的列数。

    A_Name  B_Info  Value_Yn  Value_Yn-1   Value_Yn-2   ......  Value_Y1
0   AA      X1        0.9       0.8           0.7       ......   0.1   
1   BB      Y1        0.1       0.2           0.3       ......   0.9
2   CC      Z1        -0.9       -0.8         -0.7      ......   -0.1
3   DD      L1        -0.1       -0.2         -0.3      ......   -0.9

我想对 X 和 Y 的值为

的每一行执行线性回归
X = [n, n-1, n-2, .....2, 1]

Y = [Value_Yn, Value_Yn-1, Value_Yn-2.......Value_Y2, Value_Y1]

此处 'n' 是将以 'Value_'

为前缀的列数

假设 n = 9

我将拥有

的价值

对于第 0 行

X = [9, 8, 7, 6, 5, 4, 3, 2, 1]
Y = [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1]

第 1 行

X = [9, 8, 7, 6, 5, 4, 3, 2, 1]
Y = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

其他行也类似...

我想要这种格式的输出...

    A_Name  B_Info  Intercept  Slope_Coefficent
0   AA      X1        0         0.1  
1   BB      Y1        1         -0.1
2   CC      Z1        0         -0.1        
3   DD      L1        -1        0.1

数据集很大,循环执行不是正确的方法...

这个问题可以用numpy和线性代数来解决。基本思想是因为您一遍又一遍地重复使用相同的 x 值,我们可以重复使用中间计算。

推导.

线性回归通常这样求解:

  1. 给定数据集 (x_1, y_1) ... (x_n, y_n),我们求解最小二乘法 形式为 A x = b.
  2. 的问题
  3. A 是一个 n x 2 矩阵,x 值作为一列,x 值作为第二列,向量 b 包含 y 值,x 具有斜率和截距。
  4. 我们将两边乘以 A 转置,得到 A^T A x= A^T b,这是一个可求解斜率和截距的二维系统。

假设您的数据框有 k 行。您正在尝试对相同的 x 值但不同的 y 值执行 k 次最小二乘法。这转化为使用相同的 A 和不同的 b 解决潜在的最小二乘问题 k 次。

我们可以通过两种方式利用它。第一种是只计算 A^T A 一次。第二,也是大部分加速的结果,是同时 使用矩阵乘法一次解决所有 k 个最小二乘问题。这个想法是将所有 k b 作为矩阵 B 的列。然后,用右侧的大 B 替换小 b,并进行所有相同的矩阵乘法。您最终会得到一个矩阵 X,其列与 B 的列相对应。

请注意,B 是列为 Y_1、Y_2、... Y_n 的矩阵的转置。所以这是你的数据帧的转置。

换句话说,X = (A^T A)^(-1) A^T B,其中 B 是数据框的转置。如果数学不清楚,这是我的代码(使用虚拟数据)。如果有什么不对,请告诉我。

import numpy as np
import numpy.linalg as la

n = 3
k= 10
#replace this with your data matrix whose columns are the Y's
yvals = np.arange(k*n).reshape(k,n)
xvals = np.arange(1,n+1)
print "X values:", xvals
print "Y Values:"
print yvals

A = np.zeros((n,2))
A[:,0] = xvals
A[:,1] = 1

Q = A.T.dot(A)
#slopes are the first column, intercepts are the second
res =  la.inv(Q).dot(A.T.dot(yvals.T)).T
print res

输出:

X values: [1 2 3]
Y Values:
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]
 [12 13 14]
 [15 16 17]
 [18 19 20]
 [21 22 23]
 [24 25 26]
 [27 28 29]]
Result:
[[  1.  -1.]
 [  1.   2.]
 [  1.   5.]
 [  1.   8.]
 [  1.  11.]
 [  1.  14.]
 [  1.  17.]
 [  1.  20.]
 [  1.  23.]
 [  1.  26.]]

由于向量化和矩阵乘法的渐近加速,这应该相当快。