Тот факт, что коэффициенты совсем не похожи на «истинные», которые вы установили, указывает на то, что мультиколлинеарность может быть проблемой. Проблема с вашим кодом в том, что ваша матрица X
почти единственная, что делает числовые результаты нестабильными. Как видно из графиков @ R.yan, ваши X1
и X2
практически идентичны, за исключением линейного сдвига. Это подтверждается тем фактом, что ваша матрица X
, которая имеет 1000 строк и три столбца, имеет ранг только 2. См .:
np.linalg.matrix_rank(X)
Out[26]: 2
Попробуйте вместо этого:
import pandas as pd
import numpy as np
import scipy.stats as st
import sklearn
from sklearn.linear_model import LinearRegression
n = 1000
# adding noise to your data:
X1 = np.linspace(2, 8.5, n) + st.norm.rvs(size=n ,loc = 0, scale = 1)
X2 = np.linspace(-4, 2.9, n) + st.norm.rvs(size=n ,loc = 0, scale = 1)
X3 = np.linspace(-1, 16, n) + st.norm.rvs(size=n ,loc = 0, scale = 1)
X = np.transpose( [X1, X2, X3] )
Y = 2*X1 + 3.2*X2 -1.2*X3 + 4 + st.norm.rvs(size=1000 ,loc = 0, scale = 1)
X = pd.DataFrame( X , columns = ["X1", "X2", "X3"])
Y = pd.DataFrame(Y, columns = ["Y"])
#Create linear regression object:
my_reg = sklearn.linear_model.LinearRegression(fit_intercept = True)
#Train:
res = my_reg.fit(X, Y)
print('Coefficients: \n', my_reg.coef_)
print('Constant: \n', my_reg.intercept_)
Coefficients:
[[ 1.99273588 3.20068392 -1.19688422]]
Constant:
[ 4.02296003]
Теперь мы получаем правильные коэффициенты и матрицу полного ранга:
np.linalg.matrix_rank(X)
Out[32]: 3
Обратите внимание, что в линейной регрессии X
должен иметь ранг, равный количеству столбцов (или строк, если оно меньше). Если это не так, это означает, что существует мультиколлинеарность, которая отображает числовые результаты для инверсии X'X
нестабильной (в зависимости от того, какой алгоритм используется). См. это описание для получения дополнительной информации о мультиколлинеарности.