Saltar al contenido

Comparación de resultados de StandardScaler vs Normalizer en regresión lineal

Este grupo de especialistas pasados algunos días de trabajo y recopilación de de datos, obtuvimos los datos necesarios, queremos que resulte de gran utilidad para tu plan.

Solución:

  1. La razón de que no haya diferencias en los coeficientes entre los dos primeros modelos es que Sklearn desnormalizar los coeficientes detrás de escena después de calcular los coeficientes de datos de entrada normalizados. Referencia

Esta desnormalización se ha realizado porque para los datos de prueba, podemos aplicar directamente los coeficientes. y obtenga la predicción sin normalizar los datos de prueba.

Por lo tanto, establecer normalize=True tienen impacto en los coeficientes, pero no afectan a la línea de mejor ajuste de todos modos.

  1. Normalizer realiza la normalización con respecto a cada muestra (es decir, por filas). Ves el código de referencia aquí.

De la documentación:

Normalice las muestras individualmente a la norma de la unidad.

mientras que normalize=True realiza la normalización con respecto a cada columna / característica. Referencia

Ejemplo para comprender el impacto de la normalización en diferentes dimensiones de los datos. Tomemos dos dimensiones x1 y x2 e y sea la variable objetivo. El valor de la variable objetivo está codificado por colores en la figura.

import matplotlib.pyplot as plt
from sklearn.preprocessing import Normalizer,StandardScaler
from sklearn.preprocessing.data import normalize

n=50
x1 = np.random.normal(0, 2, size=n)
x2 = np.random.normal(0, 2, size=n)
noise = np.random.normal(0, 1, size=n)
y = 5 + 0.5*x1 + 2.5*x2 + noise

fig,ax=plt.subplots(1,4,figsize=(20,6))

ax[0].scatter(x1,x2,c=y)
ax[0].set_title('raw_data',size=15)

X = np.column_stack((x1,x2))

column_normalized=normalize(X, axis=0)
ax[1].scatter(column_normalized[:,0],column_normalized[:,1],c=y)
ax[1].set_title('column_normalized data',size=15)

row_normalized=Normalizer().fit_transform(X)
ax[2].scatter(row_normalized[:,0],row_normalized[:,1],c=y)
ax[2].set_title('row_normalized data',size=15)

standardized_data=StandardScaler().fit_transform(X)
ax[3].scatter(standardized_data[:,0],standardized_data[:,1],c=y)
ax[3].set_title('standardized data',size=15)

plt.subplots_adjust(left=0.3, bottom=None, right=0.9, top=None, wspace=0.3, hspace=None)
plt.show()

ingrese la descripción de la imagen aquí

Puede ver que la línea de mejor ajuste para los datos de las figuras 1, 2 y 4 sería la misma; significa que la puntuación R2_ no cambiará debido a la normalización de la columna / función o la estandarización de datos. Solo eso, termina con diferentes co-efectos. valores.

Nota: la mejor línea de ajuste para fig3 sería diferente.

  1. Cuando establece fit_intercept = False, el término de sesgo se resta de la predicción. Lo que significa que la intersección se establece en cero, que de otro modo habría sido la media de la variable objetivo.

Se esperaría que la predicción con la intersección como cero funcione mal para problemas en los que las variables objetivo no se escalan (media = 0). Puede ver una diferencia de 22,532 en cada fila, lo que significa el impacto de la salida.

Respuesta a la P1

Supongo que lo que quieres decir con los primeros 2 modelos es reg1 y reg2. Háganos saber si ese no es el caso.

Una regresión lineal tiene el mismo poder predictivo si normaliza los datos o no. Por lo tanto, usando normalize=True no tiene ningún impacto en las predicciones. Una forma de entender esto es ver que la normalización (por columnas) es una operación lineal en cada una de las columnas ((x-a)/b) y las transformaciones lineales de los datos en una regresión lineal no afectan la estimación de coeficientes, solo cambian sus valores. Tenga en cuenta que esta declaración no es true para Lasso / Ridge / ElasticNet.

Entonces, ¿por qué los coeficientes no son diferentes? Bien, normalize=True también tiene en cuenta que lo que el usuario normalmente desea son los coeficientes de las características originales, no las características normalizadas. Como tal, ajusta los coeficientes. Una forma de comprobar que esto tiene sentido es utilizar un ejemplo más simple:

# 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)

Lo que confirma que ambos métodos capturan correctamente la señal real entre [x1,x2] ey, a saber, el 2 y el 1 respectivamente.

Respuesta a la P2

Normalizer no es lo que esperarías. Normaliza cada fila por filas. Por lo tanto, los resultados cambiarán drásticamente y probablemente destruyan la relación entre las características y el objetivo que desea evitar, excepto en casos específicos (por ejemplo, TF-IDF).

Para ver cómo, asuma el ejemplo anterior, pero considere una característica diferente, x3, que no está relacionado con y. Utilizando Normalizer causas x1 ser modifcado por el valor de x3, disminuyendo la fuerza de su relación con y.

Discrepancia de coeficientes entre modelos (1,2) y (4,5)

La discrepancia entre los coeficientes es que cuando estandarizas antes de ajustar, los coeficientes serán con respecto a las características estandarizadas, los mismos coeficientes a los que me referí en la primera parte de la respuesta. Se pueden asignar a los parámetros originales utilizando 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)

Esto se debe a que, matemáticamente, establecer z = (x - mu)/sigma, el modelo reg4 está resolviendo y = a1*z1 + a2*z2 + a0. Podemos recuperar la relación entre y y x mediante álgebra simple: y = a1*[(x1 - mu1)/sigma1] + a2*[(x2 - mu2)/sigma2] + a0, que se puede simplificar a y = (a1/sigma1)*x1 + (a2/sigma2)*x2 + (a0 - a1*mu1/sigma1 - a2*mu2/sigma2).

reg4.coef_ / scaler.scale_ representa [a1/sigma1, a2/sigma2] en la notación anterior, que es exactamente lo que normalize=True hace para garantizar que los coeficientes sean los mismos.

Discrepancia de la puntuación del modelo 5.

Las características estandarizadas tienen media cero, pero la variable objetivo no es necesariamente. Por lo tanto, no ajustar la intersección hace que el modelo ignore la media del objetivo. En el ejemplo que he estado usando, el “3” en y = 3 + ... no está ajustado, lo que naturalmente disminuye el poder predictivo del modelo. 🙂

Sección de Reseñas y Valoraciones

Más adelante puedes encontrar las ilustraciones de otros desarrolladores, tú asimismo tienes la opción de mostrar el tuyo si lo deseas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *