2016-04-27 2 views
2

Я линейно регресс k переменных отклика y на на k х n предикторов X, где к> = п. Используя Scikit-Learn, регрессия кажется правильной, за исключением случаев, когда n = k; т. е. когда матрица предикторов является квадратной. Рассмотрим следующую MWE, где я случайно генерировать матрицу X и коэффициенты b построить y, а затем выполнить регрессию с помощью scikit учиться, чтобы проверить, что коэффициенты такие же, как истинные коэффициенты:Scikit-Learn Линейная регрессия на площади Матрица Кажется Неверная

import numpy as np 
from sklearn import linear_model 


n = 5 # number of predictor variables         
k = 5 # number of response variables, >= n *** Set = n for issue *** 
mu_b = 2.0 # mean of each component of b, used to create coeffs   

print "n = ", n 

# generate true coefficients ~ N(2,0.09)         
b = np.random.normal(2.0, 0.3, n) 

print "b = ", b 

# generate true predictors ~ N(0,25)          
X = np.random.normal(0.0, 5.0, (k,n)) 

# generate true target variables           
y = X.dot(b) 


# create linear regression object          
regr = linear_model.LinearRegression() 

# train model               
regr.fit(X,y) 

# print coeffs               
print "estimated b = ", regr.coef_ 

# print difference              
print "difference = ", np.linalg.norm(b - regr.coef_) 

Если к> n нет никакой разницы по модулю точности машины, но когда k = n, может быть довольно разная. кто-нибудь еще сталкивался с этим? Это известная ошибка?

+0

Я думаю, что вы смешиваете свои концепции, в вашем коде это выглядит как «k» - это число переменных-предикторов, а 'n' - размер выборки; и вам нужно иметь 'n' строго больше, чем' k', чтобы регрессия имела смысл. Подумайте об этом, образ you 'k = 1', поэтому у вас есть только одна переменная, которую вы пытаетесь предсказать, т. Е. Вы пытаетесь вычислить градиент линии. Вам понадобится как минимум два балла, чтобы вывести их из строя, поэтому вы должны иметь «n> 2». – maxymoo

+0

@maxymoo нет, код правильный. Он работает, когда я решаю, что система использует lstsq из np.linalg для квадратной матрицы, а для k> = n используется scikit-learn. Я считаю, что в scikit-learn есть ошибка. – bcf

ответ

1

По умолчанию атрибут fit_intercept класса LinearRegression установлен в True. Кажется, это имеет два эффекта. Во-первых, прежде чем модель будет установлена ​​с использованием linalg.lstsq, матрицы, X и y, центрируются путем вычитания среднего значения в методе _center_data. Во-вторых, после того, как модель пригодна, то _set_intercept наборы:

regr.intercept_ = y_mean - np.dot(X_mean, regr.coef_.T) 

Это не ясно из документации, как получен этот термин перехватывать.

В вашем случае, вы можете проверить, что в тех случаях, когда в результате k > nintercept_ термина порядка 1e-14, но для k = n, intercept_ ненулевой, объясняя, почему вектор коэффициентов рассогласования в случае k = n. Вы можете исправить все это, просто установив fit_intercept=False в свою модель.

Caveat: более значимый ответ, конечно, мог бы объяснить, как происходит термин перехватывать, а также дать представление о том, почему термин перехватывать равен нулю для k > n.

Смежные вопросы