Ответ на вопрос 1
Я предполагаю, что вы имеете в виду первые две модели reg1
и reg2
. Дайте нам знать, если это не так.
Линейная регрессия имеет такую же прогностическую силу, если вы нормализуете данные или нет. Следовательно, использование normalize=True
не влияет на прогнозы. Один из способов понять это - увидеть, что нормализация (по столбцам) - это линейная операция над каждым из столбцов ((x-a)/b
), и линейные преобразования данных по линейной регрессии не влияют на оценку коэффициента, а только изменяют их значения. Обратите внимание, что это утверждение не верно для Lasso / Ridge / ElasticNet.
Итак, почему коэффициенты не отличаются? Ну, normalize=True
также принимает во внимание, что обычно пользователь хочет получить коэффициенты на исходные характеристики, а не нормализованные функции. Как таковой, он корректирует коэффициенты. Один из способов проверить, имеет ли это смысл, - использовать более простой пример:
# two features, normal distributed with sigma=10
x1 = np.random.normal(0, 10, size=100)
x2 = np.random.normal(0, 10, size=100)
# y is related to each of them plus some noise
y = 3 + 2*x1 + 1*x2 + np.random.normal(0, 1, size=100)
X = np.array([x1, x2]).T # X has two columns
reg1 = LinearRegression().fit(X, y)
reg2 = LinearRegression(normalize=True).fit(X, y)
# check that coefficients are the same and equal to [2,1]
np.testing.assert_allclose(reg1.coef_, reg2.coef_)
np.testing.assert_allclose(reg1.coef_, np.array([2, 1]), rtol=0.01)
Что подтверждает, что оба метода правильно фиксируют реальный сигнал между [x1, x2] и y, а именно 2 и 1. соответственно.
Ответ на вопрос 2
Normalizer
не то, что вы ожидаете. Он нормализует каждый ряд по строкам. Таким образом, результаты резко изменятся и, вероятно, разрушат отношения между объектами и целью, которых вы хотите избежать, за исключением особых случаев (например, TF-IDF).
Чтобы увидеть, как, предположим, приведенный выше пример, но рассмотрим другую функцию, x3
, которая не связана с y
. Использование Normalizer
приводит к изменению x1
на значение x3
, уменьшая прочность его отношения с y
.
Расхождение коэффициентов между моделями (1,2) и (4,5)
Несоответствие между коэффициентами заключается в том, что при стандартизации перед подгонкой коэффициенты будут соответствовать стандартизированным признакам, то есть коэффициентам, которые я указывал в первой части ответа. Они могут быть сопоставлены с исходными параметрами, используя reg4.coef_ / scaler.scale_
:
x1 = np.random.normal(0, 10, size=100)
x2 = np.random.normal(0, 10, size=100)
y = 3 + 2*x1 + 1*x2 + np.random.normal(0, 1, size=100)
X = np.array([x1, x2]).T
reg1 = LinearRegression().fit(X, y)
reg2 = LinearRegression(normalize=True).fit(X, y)
scaler = StandardScaler()
reg4 = LinearRegression().fit(scaler.fit_transform(X), y)
np.testing.assert_allclose(reg1.coef_, reg2.coef_)
np.testing.assert_allclose(reg1.coef_, np.array([2, 1]), rtol=0.01)
# here
coefficients = reg4.coef_ / scaler.scale_
np.testing.assert_allclose(coefficients, np.array([2, 1]), rtol=0.01)
Это связано с тем, что математически, установив z = (x - mu)/sigma
, модель reg4 решает y = a1*z1 + a2*z2 + a0
. Мы можем восстановить связь между y и x с помощью простой алгебры: y = a1*[(x1 - mu1)/sigma1] + a2*[(x2 - mu2)/sigma2] + a0
, которую можно упростить до y = (a1/sigma1)*x1 + (a2/sigma2)*x2 + (a0 - a1*mu1/sigma1 - a2*mu2/sigma2)
.
reg4.coef_ / scaler.scale_
представляет [a1/sigma1, a2/sigma2]
в приведенных выше обозначениях, что именно то, что normalize=True
делает, чтобы гарантировать, что коэффициенты одинаковы.
Расхождение балла модели 5.
Стандартизированные функции имеют нулевое среднее значение, но целевая переменная не обязательно. Следовательно, отсутствие соответствия перехвату приводит к тому, что модель игнорирует среднее значение цели. В примере, который я использовал, «3» в y = 3 + ...
не подходит, что, естественно, уменьшает предсказательную силу модели. :)