Tengo 3 variables X, Y y Z. Quiero realizar 3 regresiones OLS: X dependiente de Y y Z, Y dependiente de X y Z, y Z dependiente de X y Y.
En lugar de hacer las 3 por separado, quiero saber cómo puedo hacerlas todas a la vez a través de:
$A = B \beta + \epsilon$
Donde $A$ es una matriz n x 3
(n observaciones de las 3 variables)
Le pregunté a ChatGPT y sugirió crear una matriz $B$ con forma (n, 6) (o 7 si consideramos el intercepto) donde las columnas serían las variables Y, Z, X, Z, X, Y
y luego regresarlo para obtener una matriz de parámetros beta con forma (6, 3) (o (7, 3) con el intercepto). Pero después de eso no estoy seguro de cómo interpretar esta matriz resultante o si incluso tiene sentido (CGPT definitivamente dejó de tener sentido al hablar sobre esta matriz resultante y cómo interpretarla).
Otra cosa extraña es que incluso si esto tiene sentido y lo estoy haciendo correctamente (lo cual dudo), no estoy obteniendo los resultados que esperaría. Si ejecuto una regresión de X sobre Y y Z solamente, obtengo los parámetros
array([1.84477116, 0.74949417, 0.46818174])
Pero si ejecuto todas las regresiones al mismo tiempo obtengo la matriz:
array([[ 1.32178002e-09, 9.02019792e-10, -2.18881269e-09],
[ 9.83568782e-11, 5.00000000e-01, -1.72848402e-10],
[ 5.98987526e-12, 2.35829134e-11, 5.00000000e-01],
[ 5.00000000e-01, -9.13527032e-11, 3.39086093e-10],
[ 1.90638616e-11, 3.31752403e-11, 5.00000000e-01],
[ 5.00000000e-01, -4.81339413e-11, 3.72506470e-10],
[ 1.19651844e-10, 5.00000000e-01, -1.60753189e-10]])
Lo cual no muestra los resultados de la OLS individual en ningún lugar.
Aquí está el código que estoy usando:
y = df.to_numpy() #df es un dataframe con 3 columnas y n filas (observaciones)
x = add_constant(pd.DataFrame(data=[df.iloc[:,1], df.iloc[:,2], df.iloc[:,0], df.iloc[:,2], df.iloc[:,0], df.iloc[:,1]]).T).to_numpy() #agrega una nueva columna de unos para el intercepto
cov = np.dot(x.T, x)
inv = np.linalg.pinv(cov)
H = np.dot(inv, x.T)
betas = np.dot(H, y)