7 votos

Regresión múltiple: ¿cómo calcular el valor predicho tras la normalización de las características?

Actualmente estoy haciendo el curso de aprendizaje automático de Andrew Ng en coursera, y en la semana 2 habla del escalado de características.

He visto la conferencia y he leído muchos posts; entiendo el razonamiento que hay detrás del escalado de características (básicamente para hacer que el descenso de gradiente converja más rápido representando todas las características más o menos a la misma escala).

Mi problema surge cuando intento hacerlo. Estoy usando Octave, y tengo el código para el descenso de gradiente con regresión lineal configurado: calcula la matriz 'theta' para la hipótesis muy bien para los valores no escalados, dando predicciones precisas.

Cuando utilizo los valores escalados de la matriz de entrada X y el vector de salida Y, los valores de theta y la función de coste J(theta) calculados son diferentes a los de los valores sin escalar. ¿Es esto normal? ¿Cómo puedo "deshacer" el escalado para que, cuando pruebe mi hipótesis con datos reales, obtenga resultados precisos?

Como referencia, aquí está la función de escala que estoy utilizando (en Octave):

function [scaledX, avgX, stdX] = feature_scale(X)
    is_first_column_ones=0; %a flag indicating if the first column is ones
    sum(X==1)
    if sum(X==1)(1) == size(X)(1)   %if the first column is ones
        is_first_column_ones=1;
        X=X(:,2:size(X)(2));    %strip away the first column;
    end

    stdX=std(X);
    avgX=mean(X);

    scaledX=(X-avgX)./stdX;

    if is_first_column_ones
        %add back the first column of ones; they require no scaling.
        scaledX=[ones(size(X)(1),1),scaledX];
    end
end

¿Escala mi entrada de prueba, escala mi theta, o ambos?

También debo señalar que estoy escalando como tal:

scaledX=feature_scale(X);
scaledY=feature_scale(Y);

donde X e Y son mi entrada y mi salida respectivamente. Cada columna de X representa una característica diferente (la primera columna es siempre 1 para la característica de sesgo theta0) y cada fila de X representa un ejemplo de entrada diferente. Y es una matriz de columnas 1-D donde cada fila es un ejemplo de salida, correspondiente a la entrada de X.

eg: X = [1, x, x^2]

 1.00000    18.78152   352.74566
 1.00000     0.61030     0.37246
 1.00000    21.41895   458.77124
 1.00000     3.83865    14.73521

Y =

99.8043
 1.8283
168.9060
-29.0058

^ esto es para la función y=x^2 - 14x + 10

9voto

outis Puntos 39377

Debe realizar la normalización de las características sólo en las características, es decir, sólo en su vector de entrada $x$ . No en la salida $y$ o $\theta$ . Cuando se ha entrenado un modelo usando la normalización de características, entonces se debe aplicar esa normalización cada vez que se haga una predicción. También es de esperar que tenga diferentes $\theta$ y la función de costes $J(\theta)$ con y sin normalización. No es necesario deshacer nunca el escalado de características.

2voto

abhi divekar Puntos 188

EDIT: He hecho algunos cambios en el código basado en la respuesta de @Yurii.

Bueno, parece que después de un poco de tocar el violín y la comprobación de este respuesta, he conseguido que funcione:

Como he mencionado, he utilizado

[scaledX,avgX,stdX]=feature_scale(X)

para escalar las características. A continuación, utilicé el descenso de gradiente para obtener el vector theta, que se utiliza para hacer predicciones.

Concretamente, sí:

>> Y   % y=(a^2 -14*a + 10) as the equation of my data
Y = 
-38.4218
-31.8576
 74.2568
 38.2865
-10.7453
 36.6208
-35.3849
-9.2554
 137.4463
 3.0049

>> X  %[ 1, a, a^2 ] as my features
X = 
 1.00000     6.23961    38.93277
 1.00000     4.32748    18.72707
 1.00000    17.64222   311.24782
 1.00000     7.84469    61.53913
 1.00000     1.68448     2.83749
 1.00000     5.45754    29.78479
 1.00000     5.09865    25.99620
 1.00000     1.54614     2.39056
 1.00000    20.28331   411.41264
 1.00000     0.51888     0.26924

>> [scaledX, avgX, stdX]=feature_scale(X)

scaledX =
   1.00000  -0.12307  -0.35196
   1.00000  -0.40844  -0.49038
   1.00000   1.57863   1.51342
   1.00000   0.11646  -0.19711
   1.00000  -0.80287  -0.59922
   1.00000  -0.23979  -0.41463
   1.00000  -0.29335  -0.44058
   1.00000  -0.82352  -0.60228
   1.00000   1.97278   2.19956
   1.00000  -0.97683  -0.61681

avgX =
    7.0643   90.3138

stdX =
     6.7007   145.9833

>> %No need to scale Y

>> [theta,costs_vector]=LinearRegression_GradientDescent(scaledX, Y, alpha=1, number_of_iterations=2000);

FINAL THETA:
theta =
  -16.390
  -70.020
   75.617

FINAL COST: 3.41577e-28

Ahora, el modelo ha sido entrenado.

Cuando no utilizaba el escalado de características, la matriz theta llegaba aproximadamente a: theta=[10, -14, 1], que reflejaba la función y=x^2 -14x + 10 que estamos tratando de predecir.

Con el escalado de rasgos, como puedes ver, la matriz theta es completamente diferente. Sin embargo, seguimos utilizándola para hacer predicciones, de la siguiente manera:

>> test_input = 15;
>> testX=[1, test_input, test_input^2]
testX =
     1    15   225
>> scaledTestX=testX;
>> scaledTestX(2)=(scaledTestX(2)-avgX(1))/stdX(1);
>> scaledTestX(3)=(scaledTestX(3)-avgX(2))/stdX(2);
>> scaledTestX
scaledTestX =
   1.00000   1.18431   0.92261
>>
>> final_predicted=(theta')*(scaledTestX')
scaledPredicted =  25.000
>> % 25 is the correct value:
>> % f(a)=a^2-14a+10, at a=15 (our input value) is 25

1voto

Max Puntos 732

Entiendo los conceptos explicados en las 2 respuestas anteriores, es decir, después de hacer el escalado de características y calcular el intercepto (θ 0 ) y la pendiente (θ 1 ), obtenemos una función de hipótesis ( h(x) ) que utiliza las características reducidas (Suponiendo una regresión lineal univariante/de una sola variable)

h(x) = θ 0 + θ 1 x' -- (1)

donde

x' = (x-μ)/σ -- (2)

(μ = media del conjunto de características x; σ = desviación estándar del conjunto de características x)

Como dijo Yurii más arriba, no escalamos el objetivo, es decir y al hacer el escalado de características. Así que para predecir y para algún x m simplemente escalamos el nuevo valor de entrada y lo introducimos en la nueva función de hipótesis (1) utilizando (2)

x' m \= (x m -μ)/σ -- (3)

Y utilizar esto en (1) para obtener la estimación y . Y creo que esto debería funcionar perfectamente en la práctica.

Pero quería trazar la línea de regresión contra el original, es decir, las características sin escalar y los valores objetivo. Por lo tanto, necesitaba una forma de reducir la escala. Geometría de coordenadas al rescate :)

La ecuación (1) nos da la hipótesis con la característica escalada x' . Y sabemos que (2) es la relación entre la característica escalada x' y la característica original x . Así que sustituimos (2) en (1) y obtenemos (después de simplificar):

h(x) = (θ 0 - θ 1 *μ/σ) + (θ 1 /σ)x -- (4)

Por lo tanto, para trazar una línea con las características originales, es decir, sin escalar, simplemente utilizamos el intercepto como (θ 0 - θ 1 *μ/σ) y la pendiente como (θ 1 /σ).

Aquí está mi código R completo que hace lo mismo y traza la línea de regresión:

if(exists("dev")) {dev.off()} # Close the plot

rm(list=c("f", "X", "Y", "m", "alpha", "theta0", "theta1", "i")) # clear variables

f<-read.csv("slr12.csv") # read in source data (data from here: http://goo.gl/fuOV8m)

mu<-mean(f$X) # mean

sig<-sd(f$X) # standard deviation

X<-(f$X-mu)/sig # feature scaled

Y<-f$Y # No scaling of target
m<-length(X)

alpha<-0.05

theta0<-0.5

theta1<-0.5

for(i in 1:350) {
    theta0<-theta0 - alpha/m*sum(theta0+theta1*X-Y)
    theta1<-theta1 - alpha/m*sum((theta0+theta1*X-Y)*X)
    print(c(theta0, theta1))
}
plot(f$X,f$Y) # Plot original data
theta0p<-(theta0-theta1*mu/sig) # "Unscale" the intercept
theta1p<-theta1/sig # "Unscale" the slope
abline(theta0p, theta1p, col="green") # Plot regression line

Puede probar que theta0p y theta1p son correctos arriba ejecutando lm(f$Y~f$X) para utilizar la función de regresión lineal incorporada. Los valores son los mismos.

> print(c(theta0p, theta1p))
[1] 867.6042128   0.3731579
> lm(f$Y~f$X)

Call:
lm(formula = f$Y ~ f$X)

Coefficients:
(Intercept)          f$X  
   867.6042       0.3732  

enter image description here

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X