Dirección de Educación Continua.
En una regresión múltiple se tiene una variable objetivo
(Target
) \(Y\) la cual es
cuantitativa y es de interés para el investigador. Se quiere entonces
construir una función \(f(X)\) donde
\(X=(X_1, \ldots, X_p)\) es un conjunto
de variables explicativas (Features
) que se utilizaran para
pronosticar y explicar las diferencias presentes en la variable target
\(Y\).
En un modelo de regresión lineal, se usan las funciones del tipo: \[Y=\beta_0 +\beta_1X_1+\beta_2X_2+...+\beta_pX_p +\epsilon \]
donde \(\epsilon\) se conoce como el error o ruido del modelo.
Sobre este error se realizan varios supuestos para que el modelo tenga validez estadística. 1. Normalidad o gaussianidad: Campana de Gauss 2. Homocedasticidad: La variabilidad de mi modelo no depende de las X 3. Independencia.
En una lectura anterior, aprendimos cómo la regresión lineal puede ser una herramienta poderosa para comprender el comportamiento de una variable de interés en relación con otras variables en nuestro conjunto de datos. Sin embargo, en muchas situaciones de la vida real, es posible que nuestros datos no cumplan con los supuestos básicos que se necesitan para que un modelo de regresión lineal sea adecuado. En los casos en que la regresión lineal no sea directamente aplicable, en estos escenarios debemos descubrir cómo solucionar este problema.
Vamos a abordar:
El Dataset se obtuvo de Kaggle
e incluye precios de venta de casas en el estado de Washington (condado
de King, donde se encuentra Seattle) entre mayo de 2014 y mayo de
2015.
Vamos a crear un modelo que use como variable target el precio de
venta (price
) y como las features las características de
los predios. Todo basado en ventas anteriores en Seattle para recomendar
un precio de venta óptimo.
# Cargar los datos desde la URL
file_url <- paste0(url_base, "kc_house_data.csv")
houses <- read_csv(file_url)
## Rows: 21613 Columns: 21
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (20): id, price, bedrooms, bathrooms, sqft_living, sqft_lot, floors, wa...
## dttm (1): date
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Mostrar las primeras filas del dataframe
head(houses)
## # A tibble: 6 × 21
## id date price bedrooms bathrooms sqft_living sqft_lot
## <dbl> <dttm> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7129300520 2014-10-13 00:00:00 221900 3 1 1180 5650
## 2 6414100192 2014-12-09 00:00:00 538000 3 2.25 2570 7242
## 3 5631500400 2015-02-25 00:00:00 180000 2 1 770 10000
## 4 2487200875 2014-12-09 00:00:00 604000 4 3 1960 5000
## 5 1954400510 2015-02-18 00:00:00 510000 3 2 1680 8080
## 6 7237550310 2014-05-12 00:00:00 1225000 4 4.5 5420 101930
## # ℹ 14 more variables: floors <dbl>, waterfront <dbl>, view <dbl>,
## # condition <dbl>, grade <dbl>, sqft_above <dbl>, sqft_basement <dbl>,
## # yr_built <dbl>, yr_renovated <dbl>, zipcode <dbl>, lat <dbl>, long <dbl>,
## # sqft_living15 <dbl>, sqft_lot15 <dbl>
Comencemos por revisar las columnas del conjunto de datos y lo que significan:
# Vamos a formar nuestro Dataset de trabajo
df <- houses
# Eliminar columnas no deseadas
df <- df %>%
dplyr::select(-id, -sqft_living15, -sqft_lot15)
# Mostrar la estructura del dataframe (similar a .info())
glimpse(df)
## Rows: 21,613
## Columns: 18
## $ date <dttm> 2014-10-13, 2014-12-09, 2015-02-25, 2014-12-09, 2015-02…
## $ price <dbl> 221900, 538000, 180000, 604000, 510000, 1225000, 257500,…
## $ bedrooms <dbl> 3, 3, 2, 4, 3, 4, 3, 3, 3, 3, 3, 2, 3, 3, 5, 4, 3, 4, 2,…
## $ bathrooms <dbl> 1.00, 2.25, 1.00, 3.00, 2.00, 4.50, 2.25, 1.50, 1.00, 2.…
## $ sqft_living <dbl> 1180, 2570, 770, 1960, 1680, 5420, 1715, 1060, 1780, 189…
## $ sqft_lot <dbl> 5650, 7242, 10000, 5000, 8080, 101930, 6819, 9711, 7470,…
## $ floors <dbl> 1.0, 2.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 2.0, 1.0, 1…
## $ waterfront <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ view <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,…
## $ condition <dbl> 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 4, 4,…
## $ grade <dbl> 7, 7, 6, 7, 8, 11, 7, 7, 7, 7, 8, 7, 7, 7, 7, 9, 7, 7, 7…
## $ sqft_above <dbl> 1180, 2170, 770, 1050, 1680, 3890, 1715, 1060, 1050, 189…
## $ sqft_basement <dbl> 0, 400, 0, 910, 0, 1530, 0, 0, 730, 0, 1700, 300, 0, 0, …
## $ yr_built <dbl> 1955, 1951, 1933, 1965, 1987, 2001, 1995, 1963, 1960, 20…
## $ yr_renovated <dbl> 0, 1991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ zipcode <dbl> 98178, 98125, 98028, 98136, 98074, 98053, 98003, 98198, …
## $ lat <dbl> 47.5112, 47.7210, 47.7379, 47.5208, 47.6168, 47.6561, 47…
## $ long <dbl> -122.257, -122.319, -122.233, -122.393, -122.045, -122.0…
Esta es la distribución de los precios de la vivienda caracterizada por sus estadísticas descriptivas y un histograma:
# Resumen estadístico de la variable 'price'
summary(df$price)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 75000 321950 450000 540088 645000 7700000
# Histograma de los precios
ggplot(df, aes(x = price)) +
geom_histogram(aes(y = ..density..), bins = 50, fill = "lightblue", color = "black") +
geom_density(color = "blue", size = 1) +
labs(title = "Histograma de los precios.")
Basándose únicamente en estos resultados, ¿diría que la distribución de precios es normal?
Respuesta.
Del histograma podemos ver que la distribución está bastante sesgada hacia la derecha. Esto se corrobora con el hecho de que la diferencia entre el percentil 25 y el percentil 50 es notablemente menor que la diferencia entre el percentil 50 y el percentil 75. Por lo tanto, es casi seguro que la distribución de precios no es normal.
Una forma de evaluar si los datos provienen de una distribución dada en particular es dibujar un Gráfico de cuantil cuantil(QQ-plot) . En un gráfico QQ, los cuantiles de los datos se representan frente a los cuantiles de la distribución deseada. Si la gráfica resultante se desvía lo suficiente de la línea de identidad (es decir, la línea \(y = x\)), podemos decir que nuestros datos no provienen de esa distribución en particular.
Para entender mejor cómo interpretar gráficos QQ, consideremos una variable normalmente distribuida y encontremos sus percentiles (100 cuantiles):
# N(145,19²) encontramos 99 percentiles (0.01-0.99)
set.seed(1880)
theor_data <- rnorm(10000, mean = 145, sd = 19)
percentil_theo <- quantile(theor_data, probs = seq(0.01, 0.99, 0.01))
# Gráfico de densidad con percentiles
ggplot(data.frame(x = theor_data), aes(x = x)) +
geom_density(fill = "lightblue") +
geom_vline(xintercept = percentil_theo, color = "orange") +
labs(title = "Una distribución normal y sus percentiles")
Tomemos ahora una muestra de la misma variable. Esta muestra consta de 99 observaciones y, por lo tanto, cada observación cuenta como un percentil (es decir, después de ordenarlas, la \(i\)-ésima observación será exactamente el \(i\)-el percentil).
set.seed(1880)
percentil_sample <- sort(rnorm(99, mean = 145, sd = 19))
# Gráfico de los percentiles de la muestra
ggplot(data.frame(x = percentil_sample)) +
geom_vline(aes(xintercept = x), color = "orange") +
labs(title = "Percentiles distribución normal N(145,19²)") +
ylim(0, 0.020)
Si graficamos los percentiles de la distribución normal contra los percentiles de la muestra como un diagrama de dispersión, obtenemos lo siguiente:
# Gráfico QQ del original frente a la muestra
plot_data <- data.frame(theo = percentil_theo, sample = percentil_sample)
ggplot(plot_data, aes(x = theo, y = sample)) +
geom_point(size = 1) +
labs(x = "Percentiles distribución original",
y = "Percentiles de las 99 observaciones de la muestra",
title = "Scatterplot cuantil vs. cuantil\nDistribución original y la muestra")
Se observa que los puntos siguen aproximadamente una línea recta desde la esquina inferior izquierda hasta la esquina superior derecha (es decir, aproximadamente la línea \(y = x\)). Esto tiene sentido: dado que las formas de las distribuciones son similares, sus percentiles (que resumen esas formas) también deberían ser similares.
Ahora comparemos nuestra distribución original con otra distribución que también es normal pero que tiene una media y una desviación estándar muy diferentes (observe el cambio en el eje \(y\)):
set.seed(1000)
sample_data_other <- quantile(rnorm(100, mean = 1485, sd = 190), probs = seq(0.01, 0.99, 0.01))
plot_data_other <- data.frame(theo = percentil_theo, sample = sample_data_other)
ggplot(plot_data_other, aes(x = theo, y = sample)) +
geom_point(size = 0.7) +
labs(x = "Percentiles distribución original",
y = "Percentiles N(1485,190²)",
title = "Scatterplot cuantil vs.cuantil\nDistribución original y otra normal")
La relación lineal entre los percentiles se mantiene. En general, si dibuja una gráfica QQ de dos variables normales, los puntos tenderán a formar una línea recta incluso si las dos distribuciones tienen medias y desviaciones estándar diferentes.
Este es el gráfico QQ para price
frente a la
distribución normal estandar. ¿Qué puedes concluir?
# QQ plot de price
qqnorm(df$price, main = "QQ Plot para los precios.", xlab = "Cuantiles teóricos", ylab = "Valores ordenados")
qqline(df$price, col = "red", lwd = 2)
Al parecer la distribución de price
no es normal…
Problema!!!! Se necesita en el modelo de regresión múltiple que la
variable respuesta se distribuya normal– :(
Examine la relación entre los precios de la vivienda y el precio por pie cuadrado de espacio habitable (gráfico a continuación). ¿Qué puede concluir?
# Relación lineal entre sqft_living y price
ggplot(df, aes(x = sqft_living, y = price)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm", color = "red") +
labs(title = "Price vs. Sqft_living")
## `geom_smooth()` using formula = 'y ~ x'
Respuesta.
Dada la forma en que el precio de la vivienda frente al precio por pie cuadrado parece “abanicarse”, vemos que la relación no parece ser lineal. De hecho, no es inmediatamente obvio qué tipo de relación se exhibe aquí.
LA prueba de normalidad establece como hipótesis:
\[H_0: \text{Normal}\]
\[H_a: \text{No Normal}\]
formula0 <- price ~ sqft_living
model0 <- lm(formula = formula0, data = df)
summary(model0)
##
## Call:
## lm(formula = formula0, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1476062 -147486 -24043 106182 4362067
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -43580.743 4402.690 -9.899 <2e-16 ***
## sqft_living 280.624 1.936 144.920 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 261500 on 21611 degrees of freedom
## Multiple R-squared: 0.4929, Adjusted R-squared: 0.4928
## F-statistic: 2.1e+04 on 1 and 21611 DF, p-value: < 2.2e-16
Vimos en el Ejercicio 1 que la distribución de los precios de la
vivienda no es normal, y que esto puede estar contribuyendo al efecto de
“abanico” que observamos en el Ejercicio 2. Queremos encontrar una
manera de eliminar el efecto de “abanico”, ya que implica que un ajuste
lineal se vuelve cada vez menos adecuado para valores más grandes de
sqft_living
. Un método común para abordar este problema es
transformar la variable dependiente y/o la variable independiente. Tal
transformación de variable implica aplicar una función
a una o más de estas variables para lograr condiciones que sean
adecuadas para la aplicación de un modelo lineal.
Las funciones matemáticas típicas utilizadas para transformar variables incluyen potencias (cuadráticas, cúbicas, raíces cuadradas, etc.), logaritmos y funciones trigonométricas. Comencemos con la transformación logarítmica en busca de lograr “linealizar” la relación.
Tomamos el logaritmo de price
y al crear las siguientes
gráficas y tablas. Determinar si esto hizo que la distribución de la
variable transformada fuera más o menos normal.
# Gráficos para log(price)
p1 <- ggplot(df, aes(x = log(price))) +
geom_histogram(aes(y = ..density..), bins = 50, fill = "lightblue", color = "black") +
geom_density(color = "blue") +
labs(title = "Histograma de Log prices", y = "")
# Para el QQ-plot en R, creamos el gráfico dentro del chunk
# No se puede asignar a una variable como en Python
qq_plot_data <- data.frame(y = sort(log(df$price)))
p2 <- ggplot(qq_plot_data, aes(sample = y)) +
stat_qq() +
stat_qq_line(color = "red") +
labs(title = "QQ-plot", x = "Cuantiles teóricos", y = "Valores ordenados")
# Mostrar los gráficos uno al lado del otro
grid.arrange(p1, p2, ncol = 2)
summary(log(df$price))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 11.23 12.68 13.02 13.05 13.38 15.86
Respuesta.
Podemos ver en el gráfico QQ, el histograma y la tabla que la distribución está mucho más cerca de una distribución normal.
No estamos restringidos a solo aplicar la transformación logarítmica
a la variable price
, podemos hacerlo a cualquier otra
variable en nuestro conjunto de datos. Transformemos tanto
price
como sqft_living
con este método y
ajustemos el siguiente modelo lineal:
\[ \log(price) = \beta_0 + \beta_1 \log(sqft{\_}living) + \varepsilon \]
A continuación se muestra el diagrama y la tabla de salida
correspondientes (en esta y en todas las tablas de salida posteriores,
cada vez que una variable es una transformación logarítmica, tiene el
prefijo np.log
y aparece entre paréntesis):
# Crear un nuevo data frame con las variables transformadas
houses_1 <- df %>%
mutate(log_price = log(price),
sqft_living_log = log(sqft_living))
# Relación lineal entre log(sqft_living) y log(price)
ggplot(houses_1, aes(x = sqft_living_log, y = log_price)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm", color = "red") +
labs(title = "Sqft_living vs. Precio (log-log)",
x = "log(sqft_living)",
y = "log(price)")
## `geom_smooth()` using formula = 'y ~ x'
formula1 <- log(price) ~ log(sqft_living)
log_log_model <- lm(formula = formula1, data = df)
summary(log_log_model)
##
## Call:
## lm(formula = formula1, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.10511 -0.29300 0.01262 0.25701 1.33011
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.729916 0.047062 143.0 <2e-16 ***
## log(sqft_living) 0.836771 0.006223 134.5 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.3886 on 21611 degrees of freedom
## Multiple R-squared: 0.4555, Adjusted R-squared: 0.4555
## F-statistic: 1.808e+04 on 1 and 21611 DF, p-value: < 2.2e-16
Tenemos que ser conscientes de cómo interpretamos los coeficientes aquí. En una regresión en la que tanto la variable independiente como la dependiente son transformaciones logarítmicas (una log-log regression), el coeficiente \(\beta_1\) debe interpretarse como el cambio porcentual en la variable dependiente asociada con el 1% de cambio en la variable independiente. Esta comparación de cambio de porcentaje frente a porcentaje se conoce como elasticidad. Así, en nuestro modelo:
Un aumento del 1% en la superficie habitable se asocia con un aumento del 0,8368% en el precio.
Ahora construyamos un modelo lineal donde la transformación logarítmica solo se aplica a los precios de la vivienda, es decir, un modelo de la forma:
\[ \log(price) = \beta_0 + \beta_1 sqft{\_}living + \varepsilon \]
El plot y la tabla de salida están a continuación:
# Relación lineal entre sqft_living y log(price)
ggplot(houses_1, aes(x = sqft_living, y = log_price)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm", color = "red") +
labs(title = "Log de Price vs. Sqft_living (log-level)",
y = "log(price)")
## `geom_smooth()` using formula = 'y ~ x'
formula2 <- log(price) ~ sqft_living
log_level <- lm(formula = formula2, data = df)
summary(log_level)
##
## Call:
## lm(formula = formula2, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.97781 -0.28543 0.01472 0.26070 1.27628
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.222e+01 6.374e-03 1916.9 <2e-16 ***
## sqft_living 3.987e-04 2.803e-06 142.2 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.3785 on 21611 degrees of freedom
## Multiple R-squared: 0.4835, Adjusted R-squared: 0.4835
## F-statistic: 2.023e+04 on 1 and 21611 DF, p-value: < 2.2e-16
La interpretación del coeficiente de regresión vuelve a ser
diferente. Esta es una log-level regression; es decir, uno en
el que la variable dependiente se ha transformado logarítmicamente y la
variable independiente no. Interpretamos el coeficiente como una
semi-elasticidad, donde un aumento absoluto en
sqft_living
(porque no se le ha aplicado la función
logarítmica) corresponde a un aumento porcentual en price
.
Específicamente, aquí podemos decir que:
Un aumento en el espacio habitable de 1 pie cuadrado conduce a un aumento del 0,04 % en el precio.
De las gráficas de los modelos log-log y log-level, ¿cuál de los dos es “más lineal”?
Respuesta.
Podemos ver en estos gráficos que los puntos de datos del modelo log-log se agrupan más uniformemente alrededor de la línea de mejor ajuste en diferentes niveles de la variable independiente en comparación con el otro modelo, lo que sugiere que el modelo log-log es más lineal.
Las transformaciones logarítmicas son solo una posible transformación para hacer que nuestras relaciones sean más lineales. Anteriormente, mencionamos potencias (por ejemplo, cuadrados, cubos, raíces cuadradas, etc.), así como funciones trigonométricas. En algunos casos, elegir una transformación puede ser sencillo (por ejemplo, el logaritmo porque es fácilmente interpretable); otras veces, es mucho más difícil. Una manera formal de decidir qué transformación es usar la transformación de Box-Cox criterio. Esta es una ingeniosa función matemática que genera un número cuando lo aplicas a una variable. Este número suele representarse con la letra griega \(\lambda\) (lambda). La interpretación de algunos valores comunes de \(\lambda\) se muestra a continuación:
Si se obtiene un valor lambda (\(λ\)) de… | entonces transformamos \(Y\) usando esta función |
---|---|
-3 | \(Y^{-3} = \frac{1}{Y^3}\) |
-2 | \(Y^{-2} = \frac{1}{Y^2}\) |
-1 | \(Y^{-1} = \frac{1}{Y^1}\) |
-0.5 | \(Y^{-0.5} = \frac{1}{Y^{0.5}} = \frac{1}{\sqrt{Y}}\) |
0 | \(log(Y)\) |
0.5 | \(Y^{0.5} = \sqrt{Y}\) |
1 | \(Y^1 = Y\) |
2 | \(Y^2\) |
3 | \(Y^3\) |
Por ejemplo, si tiene una variable \(Y\) y obtuvo \(\lambda=2\) después de aplicar la función Box-Cox, entonces \(Y^2\) debería tener una distribución aproximadamente normal. Como caso especial, cuando \(\lambda=0\) no transformamos usando \(Y^0\) (que le daría el número constante 1), sino usando \(\log(Y)\).
# Generar una distribución normal
set.seed(42) # para reproducibilidad
normal_data <- rnorm(1000, mean = 10, sd = 2)
# La transformación de raíz cúbica
cbrt_transformed_data <- normal_data^(1/3)
# Aplicar la transformación de Box-Cox
# Nota: Box-Cox en R funciona sobre un modelo lineal, por lo que usamos ~ 1 para modelar solo la intercepción.
# La función de Python es un poco diferente, pero el concepto es el mismo.
# Para evitar errores con valores negativos/cero en los datos de demostración, los manejaremos
cbrt_transformed_data_pos <- cbrt_transformed_data[cbrt_transformed_data > 0]
bc_result <- boxcox(cbrt_transformed_data_pos ~ 1, plotit = FALSE)
lambda_value <- bc_result$x[which.max(bc_result$y)]
boxcox_transformed_data <- (cbrt_transformed_data_pos^lambda_value - 1) / lambda_value
# Preparar datos para graficar
p1 <- ggplot(data.frame(x = normal_data), aes(x)) + geom_histogram(kde = TRUE) + labs(title = "Distribución Normal Original")
p2 <- ggplot(data.frame(x = cbrt_transformed_data), aes(x)) + geom_histogram(kde = TRUE) + labs(title = "Distribución Transformada por Raíz Cúbica")
p3 <- ggplot(data.frame(x = boxcox_transformed_data), aes(x)) + geom_histogram(kde = TRUE) + labs(title = paste0("Distribución Transformada por Box-Cox (λ = ", round(lambda_value, 2), ")"))
grid.arrange(p1, p2, p3, ncol = 3)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
cat(paste("El valor de lambda calculado por Box-Cox es:", round(lambda_value, 3)))
## El valor de lambda calculado por Box-Cox es: 2
# Generar datos log-normales
set.seed(42)
normal_data <- rnorm(1000, mean = 5, sd = 1)
exp_transformed_data <- exp(normal_data)
# Aplicar la transformación de Box-Cox
bc_exp_result <- boxcox(exp_transformed_data ~ 1, plotit = FALSE)
lambda_exp_value <- bc_exp_result$x[which.max(bc_exp_result$y)]
boxcox_output_data <- (exp_transformed_data^lambda_exp_value - 1) / lambda_exp_value
# Preparar gráficos
p1_exp <- ggplot(data.frame(x = normal_data), aes(x)) + geom_histogram(kde = TRUE) + labs(title = "Distribución Normal Original")
p2_exp <- ggplot(data.frame(x = exp_transformed_data), aes(x)) + geom_histogram(kde = TRUE) + labs(title = "Distribución Transformada Exponencialmente (Log-Normal)")
p3_exp <- ggplot(data.frame(x = boxcox_output_data), aes(x)) + geom_histogram(kde = TRUE) + labs(title = paste0("Distribución Transformada por Box-Cox (λ = ", round(lambda_exp_value, 2), ")"))
grid.arrange(p1_exp, p2_exp, p3_exp, ncol = 3)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
cat(paste("El valor de lambda calculado por Box-Cox es:", round(lambda_exp_value, 3), "\n"))
## El valor de lambda calculado por Box-Cox es: 0
cat("Un valor de lambda cercano a 0 sugiere una transformación logarítmica.")
## Un valor de lambda cercano a 0 sugiere una transformación logarítmica.
En R
procedemos así:
# La función boxcox() de la librería MASS es útil porque también genera un gráfico
# del perfil de verosimilitud para lambda.
bc_price_result <- boxcox(df$price ~ 1, plotit = TRUE)
# Extraer el valor óptimo de lambda
lambda_price <- bc_price_result$x[which.max(bc_price_result$y)]
# Realizar la transformación con el lambda encontrado
transformed_price <- (df$price^lambda_price - 1) / lambda_price
Esta es la serie transformada por Box-Cox:
head(transformed_price)
## [1] 4.208138 4.260279 4.194245 4.266365 4.257415 4.300339
# Histograma de los valores transformados por Box-Cox
ggplot(data.frame(x = transformed_price), aes(x = x)) +
geom_histogram(bins = 50, fill = "lightblue", color = "black") +
labs(title = "Histograma de precios transformados por Box-Cox")
Y este es el \(\lambda\):
print(paste("El valor de lambda en Box-Cox es: ", round(lambda_price, 3)))
## [1] "El valor de lambda en Box-Cox es: -0.222"
Tenemos que BC es \(\lambda=-0.23\), por lo que parece sensato usar la transformación logarítmica ya que el valor de Box-Cox es cercano a cero. Aunque es muy útil, el criterio de Box-Cox no es perfecto, por lo que siempre debe verificar el QQ-plot después de transformar la variable para confirmar que parece tener una distribución normal.
# Re-evaluamos el modelo log-level y graficamos los residuos
# En el cuaderno original, este chunk parece graficar log(price) de nuevo, no residuos.
# Replicaremos eso para ser fieles al original.
p1_log <- ggplot(df, aes(x = log(price))) +
geom_histogram(aes(y = ..density..), bins = 50, fill = "lightblue", color = "black") +
geom_density(color = "blue") +
labs(title = "Histograma de Log prices", y = "")
qq_plot_data_log <- data.frame(y = sort(log(df$price)))
p2_log <- ggplot(qq_plot_data_log, aes(sample = y)) +
stat_qq() +
stat_qq_line(color = "red") +
labs(title = "QQ-plot", x = "Cuantiles teóricos", y = "Valores ordenados")
grid.arrange(p1_log, p2_log, ncol = 2)
Por supuesto, no tiene sentido limitarnos a modelar los precios de la vivienda usando solo una variable independiente. Agreguemos varias variables más, algunas transformadas y otras no.
A continuación se muestra la tabla de salida del siguiente modelo:
\[ \log(price) = \beta_0 + \beta_1 \log(sqft{\_}living) + \beta_2 \log(sqft{\_}lot) + \beta_3 bedrooms + \beta_4 floors + \beta_5 bathrooms + \beta_6 waterfront + \beta_7 condition + \beta_8 view + \beta_9 grade + \beta_{10} yr{\\_}built + \beta_{11} lat + \beta_{12} long + \varepsilon \]
Proporcionar interpretaciones para el coeficiente de log
sqft_living
, y waterfront
.
Nota: Las variables de este modelo que son
categóricas aparecen en la tabla entre paréntesis y después de una letra
C
que significa “categórica”. Esta sintaxis proviene de la
libreria de software que usamos para ajustar el modelo.
# Convertir 'waterfront' a un factor para tratarla como categórica en el modelo
df$waterfront <- as.factor(df$waterfront)
table(df$waterfront)
##
## 0 1
## 21450 163
glimpse(df)
## Rows: 21,613
## Columns: 18
## $ date <dttm> 2014-10-13, 2014-12-09, 2015-02-25, 2014-12-09, 2015-02…
## $ price <dbl> 221900, 538000, 180000, 604000, 510000, 1225000, 257500,…
## $ bedrooms <dbl> 3, 3, 2, 4, 3, 4, 3, 3, 3, 3, 3, 2, 3, 3, 5, 4, 3, 4, 2,…
## $ bathrooms <dbl> 1.00, 2.25, 1.00, 3.00, 2.00, 4.50, 2.25, 1.50, 1.00, 2.…
## $ sqft_living <dbl> 1180, 2570, 770, 1960, 1680, 5420, 1715, 1060, 1780, 189…
## $ sqft_lot <dbl> 5650, 7242, 10000, 5000, 8080, 101930, 6819, 9711, 7470,…
## $ floors <dbl> 1.0, 2.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 2.0, 1.0, 1…
## $ waterfront <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ view <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,…
## $ condition <dbl> 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 4, 4,…
## $ grade <dbl> 7, 7, 6, 7, 8, 11, 7, 7, 7, 7, 8, 7, 7, 7, 7, 9, 7, 7, 7…
## $ sqft_above <dbl> 1180, 2170, 770, 1050, 1680, 3890, 1715, 1060, 1050, 189…
## $ sqft_basement <dbl> 0, 400, 0, 910, 0, 1530, 0, 0, 730, 0, 1700, 300, 0, 0, …
## $ yr_built <dbl> 1955, 1951, 1933, 1965, 1987, 2001, 1995, 1963, 1960, 20…
## $ yr_renovated <dbl> 0, 1991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ zipcode <dbl> 98178, 98125, 98028, 98136, 98074, 98053, 98003, 98198, …
## $ lat <dbl> 47.5112, 47.7210, 47.7379, 47.5208, 47.6168, 47.6561, 47…
## $ long <dbl> -122.257, -122.319, -122.233, -122.393, -122.045, -122.0…
# Modelo intermedio para demostrar la sintaxis de variables categóricas
prueba <- lm(log(price) ~ log(sqft_living) + waterfront, data = df)
summary(prueba)
##
## Call:
## lm(formula = log(price) ~ log(sqft_living) + waterfront, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.35282 -0.29040 0.01599 0.25814 1.34260
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.814767 0.046550 146.40 <2e-16 ***
## log(sqft_living) 0.824792 0.006158 133.94 <2e-16 ***
## waterfront1 0.741642 0.030236 24.53 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.3834 on 21610 degrees of freedom
## Multiple R-squared: 0.4703, Adjusted R-squared: 0.4702
## F-statistic: 9592 on 2 and 21610 DF, p-value: < 2.2e-16
# Resumen de las variables numéricas para referencia
summary(df %>% select_if(is.numeric))
## price bedrooms bathrooms sqft_living
## Min. : 75000 Min. : 0.000 Min. :0.000 Min. : 290
## 1st Qu.: 321950 1st Qu.: 3.000 1st Qu.:1.750 1st Qu.: 1427
## Median : 450000 Median : 3.000 Median :2.250 Median : 1910
## Mean : 540088 Mean : 3.371 Mean :2.115 Mean : 2080
## 3rd Qu.: 645000 3rd Qu.: 4.000 3rd Qu.:2.500 3rd Qu.: 2550
## Max. :7700000 Max. :33.000 Max. :8.000 Max. :13540
##
## sqft_lot floors view condition
## Min. : 520 Min. :1.000 Min. :0.0000 Min. :1.000
## 1st Qu.: 5040 1st Qu.:1.000 1st Qu.:0.0000 1st Qu.:3.000
## Median : 7618 Median :1.500 Median :0.0000 Median :3.000
## Mean : 15107 Mean :1.494 Mean :0.2343 Mean :3.409
## 3rd Qu.: 10688 3rd Qu.:2.000 3rd Qu.:0.0000 3rd Qu.:4.000
## Max. :1651359 Max. :3.500 Max. :4.0000 Max. :5.000
##
## grade sqft_above sqft_basement yr_built
## Min. : 1.000 Min. : 290 Min. : 0.0 Min. :1900
## 1st Qu.: 7.000 1st Qu.:1190 1st Qu.: 0.0 1st Qu.:1951
## Median : 7.000 Median :1560 Median : 0.0 Median :1975
## Mean : 7.657 Mean :1788 Mean : 291.5 Mean :1971
## 3rd Qu.: 8.000 3rd Qu.:2210 3rd Qu.: 560.0 3rd Qu.:1997
## Max. :13.000 Max. :9410 Max. :4820.0 Max. :2015
## NA's :2
## yr_renovated zipcode lat long
## Min. : 0.0 Min. :98001 Min. :47.16 Min. :-122.5
## 1st Qu.: 0.0 1st Qu.:98033 1st Qu.:47.47 1st Qu.:-122.3
## Median : 0.0 Median :98065 Median :47.57 Median :-122.2
## Mean : 84.4 Mean :98078 Mean :47.56 Mean :-122.2
## 3rd Qu.: 0.0 3rd Qu.:98118 3rd Qu.:47.68 3rd Qu.:-122.1
## Max. :2015.0 Max. :98199 Max. :47.78 Max. :-121.3
##
# Asegurarse de que 'view' sea tratada como categórica
df$view <- as.factor(df$view)
formula3 <- as.formula("log(price) ~ log(sqft_living) + log(sqft_lot) + bedrooms + floors + bathrooms +
waterfront + condition + view + grade + yr_built + lat + long")
model3 <- lm(formula = formula3, data = df)
summary(model3)
##
## Call:
## lm(formula = formula3, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.28749 -0.16300 -0.00363 0.15455 1.45593
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -3.899e+01 2.035e+00 -19.157 < 2e-16 ***
## log(sqft_living) 4.067e-01 8.767e-03 46.385 < 2e-16 ***
## log(sqft_lot) -7.620e-03 2.477e-03 -3.076 0.0021 **
## bedrooms -2.519e-02 2.494e-03 -10.100 < 2e-16 ***
## floors 5.021e-02 4.328e-03 11.602 < 2e-16 ***
## bathrooms 7.025e-02 4.030e-03 17.432 < 2e-16 ***
## waterfront1 3.995e-01 2.510e-02 15.919 < 2e-16 ***
## condition 5.519e-02 2.926e-03 18.866 < 2e-16 ***
## view1 1.950e-01 1.433e-02 13.605 < 2e-16 ***
## view2 1.383e-01 8.666e-03 15.964 < 2e-16 ***
## view3 2.039e-01 1.184e-02 17.215 < 2e-16 ***
## view4 2.805e-01 1.824e-02 15.380 < 2e-16 ***
## grade 1.858e-01 2.498e-03 74.364 < 2e-16 ***
## yr_built -3.814e-03 8.646e-05 -44.108 < 2e-16 ***
## lat 1.344e+00 1.335e-02 100.666 < 2e-16 ***
## long 7.465e-02 1.514e-02 4.932 8.19e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2564 on 21597 degrees of freedom
## Multiple R-squared: 0.7631, Adjusted R-squared: 0.763
## F-statistic: 4638 on 15 and 21597 DF, p-value: < 2.2e-16
Respuesta.
Todas las variables son estadísticamente significativas (todos los valores p menores a 0.05). En general, este modelo lineal explica más del 76 por ciento de la variabilidad total de la variable dependiente.
Un aumento del 1% en el espacio habitable conduce a un aumento del 0,4067% en el precio. Una propiedad con vista al agua generalmente tiene un precio de 39.95% más que una sin tal vista.
Note que nuestro modelo establece que por cada dormitorio adicional, el precio de una casa disminuye 2,5%. Esto parece una tontería: revisaremos por qué esto probablemente sucedió más adelante.
¿Qué otros factores que omitimos podrían afectar el precio? Los ejemplos pueden incluir la proximidad a los servicios (hospitales, escuelas, áreas comerciales, cines, paradas de metro, etc.) y las tasas de criminalidad. Nuestro conjunto de datos no tiene una lista completa de posibles factores; sin embargo, tenemos algunas variables que sería interesante investigar más a fondo.
En general, los precios de la vivienda cambian según la ubicación. Dos casas con características comparables pueden tener un precio muy diferente según el vecindario y la posición geográfica. En este conjunto de datos, tenemos código postal y coordenadas geográficas. Empecemos echando un vistazo a la relación entre latitud y precios.
En el siguiente gráfico, podemos ver la relación entre la latitud y el logaritmo de los precios de la vivienda. ¿Qué observas? ¿Qué función de transformación podría ser apropiada aquí?
# Se asume que el dataframe 'df' ya está cargado
# y contiene las columnas 'lat' y 'price'.
ggplot(df, aes(x = lat, y = log(price))) +
geom_point(color = "blue", alpha = 0.5, size = 2) +
labs(
title = "lat vs. Log_Price",
x = "Latitud",
y = "Log_Precio"
) +
theme_minimal()
Respuesta.
Podemos ver que existe una relación no lineal entre la latitud y el precio. Basado en la curvatura cóncava en la mitad derecha de la gráfica anterior, parece que agregar un término cuadrático podría ayudarnos a explicar esto.
Agreguemos el cuadrado de la latitud como una variable independiente adicional al modelo del Ejercicio 5:
# Esta es la fórmula inferida del modelo del Ejercicio 5 (modelo3)
# a partir de la salida del modelo4 en el cuaderno original.
formula3 <- "log(price) ~ factor(waterfront) + factor(view) + log(sqft_living) +
log(sqft_lot) + bedrooms + floors + bathrooms + condition + grade +
yr_built + lat + long"
# Se agrega el término cuadrático para latitud
formula4 <- as.formula(paste(formula3, "+ I(lat^2)"))
# Ajuste del modelo de regresión lineal
model4 <- lm(formula4, data = df)
# Muestra del resumen del modelo
summary(model4)
##
## Call:
## lm(formula = formula4, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.20222 -0.15376 -0.00348 0.14555 1.35244
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -7.715e+03 1.990e+02 -38.776 < 2e-16 ***
## factor(waterfront)1 3.800e-01 2.428e-02 15.649 < 2e-16 ***
## factor(view)1 1.715e-01 1.388e-02 12.356 < 2e-16 ***
## factor(view)2 1.299e-01 8.385e-03 15.498 < 2e-16 ***
## factor(view)3 2.004e-01 1.145e-02 17.491 < 2e-16 ***
## factor(view)4 2.733e-01 1.764e-02 15.491 < 2e-16 ***
## log(sqft_living) 4.060e-01 8.480e-03 47.876 < 2e-16 ***
## log(sqft_lot) 1.202e-02 2.449e-03 4.909 9.22e-07 ***
## bedrooms -2.498e-02 2.412e-03 -10.358 < 2e-16 ***
## floors 4.982e-02 4.186e-03 11.900 < 2e-16 ***
## bathrooms 6.587e-02 3.900e-03 16.892 < 2e-16 ***
## condition 5.975e-02 2.832e-03 21.097 < 2e-16 ***
## grade 1.763e-01 2.428e-03 72.614 < 2e-16 ***
## yr_built -3.174e-03 8.525e-05 -37.235 < 2e-16 ***
## lat 3.238e+02 8.357e+00 38.743 < 2e-16 ***
## long -1.645e-02 1.483e-02 -1.109 0.267
## I(lat^2) -3.392e+00 8.791e-02 -38.582 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.248 on 21596 degrees of freedom
## Multiple R-squared: 0.7784, Adjusted R-squared: 0.7782
## F-statistic: 4741 on 16 and 21596 DF, p-value: < 2.2e-16
¿Es significativo el coeficiente de esta nueva variable
independiente? ¿Qué puedes decir sobre el \(R^2\) de este modelo? (el coeficiente
relevante en la tabla de salida es el de la variable
I(lat^2)
; esto proviene de la sintaxis de la libreria que
usamos para ejecutar la regresión).
Una de las propiedades de \(R^2\) es que nunca puede disminuir cuando aumenta el conjunto de predictores. En otras palabras, no hay penalización por continuar agregando variables al modelo. ¿Por qué crees que esto puede ser un inconveniente de \(R^2\)? ¿Cómo haría para decidir el conjunto correcto de predictores a utilizar?
Respuesta.
Dado que no hay penalización por continuar agregando variables, podemos terminar usando variables que tienen poco poder explicativo. En consecuencia, seleccionar variables independientes con el único propósito de maximizar \(R^2\) puede llevar a elegir modelos innecesariamente complejos y redundantes. Esto puede llevarnos a un overfitting; es decir, adaptar el modelo tanto a los datos particulares que tenemos a expensas de generalizar bien a otros datos que no tenemos. Una forma de evitar el sobreajuste es implementar una medida que imponga una penalización por cada variable independiente agregada. Esta es \(R²_{adj}\), pues penaliza el ingreso de nuevos parámetros, él solo aumentará si se reduce la varianza estimada del modelo.
Existen varios criterios de selección de modelos que cuantifican la calidad de un modelo mediante la gestión del equilibrio entre la bondad de ajuste y la simplicidad. El más común es el AIC (Criterio de información de Akaike). El AIC penaliza la adición de más términos a un modelo, por lo que para que un modelo actualizado tenga un mejor AIC, su \(R^2\) debe mejorar al menos tanto como la penalización adicional impuesta. Dados varios modelos, el que tiene el AIC más bajo es el recomendado.
Por ahora, no se preocupe por los detalles técnicos detrás de AIC (puede leer más sobre esto aquí).
Utilice la puntuación AIC (puede buscarla en la tabla de salida del resumen del modelo) para evaluar si el modelo con el término cuadrado agregado es mejor o no que el modelo sin él.
El AIC mide la calidad relativa de un modelo estadístico, penalizando tanto el error de predicción como la complejidad del modelo. Fue desarrollado por el estadístico japonés Hirotugu Akaike.
Fórmula general del AIC:
\[ \text{AIC} = 2k - 2\ln(\hat{L}) \]
Donde:
- \(k\): número de parámetros del modelo
- \(\hat{L}\): valor máximo de la función de verosimilitud (likelihood) del modelo
Supongamos que ajustamos tres modelos sobre los mismos datos:
Modelo | AIC |
---|---|
M1 | 120.5 |
M2 | 115.2 |
M3 | 119.8 |
Respuesta.
Comparando este modelo con el anterior podemos ver que el AIC ha mejorado de ~2597 a ~1086. Por lo tanto, es preferible el modelo con el término al cuadrado.
Los efectos de interacción pueden complicar el efecto percibido de
las variables independientes sobre la variable dependiente.
Profundicemos en las interacciones potenciales observando dos de los
predictores en tándem: waterfront
y posición geográfica
(lat
and long
). Específicamente, ¿el efecto de
la posición geográfica es diferente entre las casas que tienen vista
frente al mar y las que no?
A continuación, dibujamos un gráfico de la relación entre
log_price
y lat
. Este gráfico se ajusta a dos
líneas de regresión separadas para las casas que tienen y no tienen una
vista waterfront
. ¿Que ves? ¿La relación es igual o
diferente?
# Se asume el dataframe 'df' y la columna 'log_price'
# El argumento 'hue' de seaborn.lmplot se traduce al estético 'color' en ggplot2.
# Para asegurar que 'waterfront' se trate como una categoría, usamos factor().
ggplot(df, aes(x = lat, y = log(price), color = factor(waterfront))) +
geom_point(size = 1.5, alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE, fullrange = TRUE) + # se=FALSE para quitar el intervalo de confianza
labs(
title = "Log-price vs. Latitude",
x = "Latitude",
y = "log_price",
color = "Waterfront"
) +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
Respuesta.
Vemos que los efectos de la posición geográfica son más pronunciados para el subgrupo de casas con vista al mar. En otras palabras, la línea tiene una pendiente más pronunciada y, por lo tanto, por cada grado de incremento en la latitud, el precio aumentará a una tasa más alta para las casas con vista al mar que para las casas sin ella.
Esta es una gráfica que se ajusta a líneas de regresión separadas
para casas con diferentes índices de view
(es decir, qué
tan buena era la vista de la propiedad). ¿Que ves? ¿La relación es igual
o diferente?
ggplot(df, aes(x = lat, y = log(price), color = factor(view))) +
geom_point(size = 2, alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE, fullrange = TRUE) +
coord_cartesian(xlim = c(47.1, 47.8), ylim = c(11, 17)) +
labs(
title = "Log-price vs. Latitude",
x = "Latitude",
y = "log_price",
color = "View"
) +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
Respuesta.
Vemos que las casas con mejores índices de vista tienden a tener
precios más altos. Sin embargo, las pendientes de las diferentes líneas
de regresión parecen casi iguales. Por lo tanto, un grado de incremento
en lat
aumenta el precio de una casa a (casi) la misma
tasa, independientemente de cuán buena sea la view
de la
casa. Por lo tanto, concluimos que la vista de la casa probablemente
no interactúa con la relación entre el precio y la latitud.
Podemos verificar los hallazgos del Ejercicio 8 agregando
términos de interacción a nuestro modelo lineal. Los
sumamos incluyendo una multiplicación en el modelo. Por ejemplo, el
siguiente modelo incluye un término de interacción entre
lat
y waterfront
:
\[ \log(price) = \beta_0 + \beta_1 waterfront + \beta_2 lat + \beta_3 (lat \times waterfront) + \varepsilon \]
Para entender por qué incluimos términos de interacción de esta manera, supongamos un modelo lineal (este ejemplo se tomó de este enlace):
\[ y=\beta_0+\beta_1 x_1+\gamma x_2+e \]
donde \(\gamma\) depende linealmente de \(x_1\):
\[ \gamma = \beta_2+\beta_3 x_1 \]
Esto significa que el efecto de \(x_2\) que ves en \(y\) no solo depende del valor de \(x_2\) sino también del valor de \(x_1\). Ambas variables están interactuando. Si sustituimos esta ecuación en la anterior, obtenemos nuestro término de interacción multiplicativa:
\[\begin{align} y&=\beta_0+\beta_1 x_1 + (\beta_2+\beta_3 x_1)x_2+e\\ &=\beta_0 + \beta_1 x_1 + \beta_2 x_2+\beta_3 x_1x_2+e \end{align} \]
Esta es la tabla de salida que corresponde a este modelo:
formula5 <- as.formula("log(price) ~ lat * factor(waterfront)")
modelo5 <- lm(formula5, data = df)
summary(modelo5)
##
## Call:
## lm(formula = formula5, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.93054 -0.30387 -0.03811 0.26891 2.69825
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -68.08797 1.07769 -63.180 < 2e-16 ***
## lat 1.70579 0.02266 75.280 < 2e-16 ***
## factor(waterfront)1 -102.30396 14.90875 -6.862 6.97e-12 ***
## lat:factor(waterfront)1 2.17525 0.31362 6.936 4.15e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4603 on 21609 degrees of freedom
## Multiple R-squared: 0.2362, Adjusted R-squared: 0.2361
## F-statistic: 2228 on 3 and 21609 DF, p-value: < 2.2e-16
La forma en que leemos el efecto de interacción dado por este resumen es la siguiente:
factor(waterfront)1
: El modelo establece que se debe
hacer un ajuste de -102.3040 al intercepto para una casa con vista al
mar. Vimos antes que waterfront
tuvo un impacto positivo en
el precio de la casa, sin embargo, este modelo simple probablemente está
dando más peso a otros factores. Este ajuste por sí solo no es
directamente interpretable como un porcentaje sin considerar el término
de interacción.
lat
: Por cada incremento de una unidad en la
latitud, el logaritmo del precio de la casa debería aumentar en 1.7058
entre las casas que NO tienen frente (o vista) al
mar (el grupo de referencia).
lat:factor(waterfront)1
: Por cada unidad de
incremento en la latitud, el precio de la casa debería aumentar en \(1.7058 + 2.1753 = 3.8811\) en el logaritmo
del precio entre las casas que SÍ tienen frente al
mar. El efecto de la latitud es significativamente
diferente (y más fuerte) para las casas con vista al mar.
Ahora, considere un modelo con un término de interacción entre
lat
y view
. ¿Que ves? ¿Estos resultados
concuerdan con sus hallazgos del Ejercicio 8.2?
formula6 <- as.formula("log(price) ~ lat * factor(view)")
model6 <- lm(formula6, data = df)
summary(model6)
##
## Call:
## lm(formula = formula6, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.97302 -0.28377 -0.02795 0.26345 2.42652
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -66.68497 1.05319 -63.317 < 2e-16 ***
## lat 1.67527 0.02214 75.652 < 2e-16 ***
## factor(view)1 -17.05690 10.95274 -1.557 0.11941
## factor(view)2 -7.71828 5.44437 -1.418 0.15630
## factor(view)3 -9.62701 6.93634 -1.388 0.16518
## factor(view)4 -26.44613 10.31057 -2.565 0.01033 *
## lat:factor(view)1 0.36765 0.23020 1.597 0.11025
## lat:factor(view)2 0.17154 0.11447 1.499 0.13398
## lat:factor(view)3 0.21641 0.14588 1.483 0.13796
## lat:factor(view)4 0.57693 0.21672 2.662 0.00777 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4334 on 21603 degrees of freedom
## Multiple R-squared: 0.3231, Adjusted R-squared: 0.3228
## F-statistic: 1145 on 9 and 21603 DF, p-value: < 2.2e-16
Respuesta.
La tabla de resumen muestra alguna interacción entre lat
y view
; sin embargo, la mayoría de estos no son
estadísticamente significativos (los valores p para
lat:factor(view)1
, lat:factor(view)2
y
lat:factor(view)3
son mayores que 0.05). Hay cierta
interacción estadísticamente significativa cuando las casas tienen un
índice de view
de 4 (que también se puede ver mirando la
pendiente de la línea morada en el ejercicio 8), pero es razonable decir
que hay muy poca evidencia estadística de una interacción general entre
las variables lat
y view
.
Ajustemos un modelo de referencia que incluya todas las otras
variables que hemos discutido antes. Además, incorporemos al modelo una
variable zipcode
y una nueva variable
renovated
indicando si la casa fue renovada anteriormente o
no:
\[ \log(price) = \beta_0 + \beta_1 \log(sqft{\_}living)+ \beta_2 \log(sqft{\_}lot) + \beta_3 bedrooms + \beta_4 floors + \beta_5 bathrooms + \beta_6 waterfront + \beta_7 condition + \beta_8 view + \beta_9 grade + \beta_{10} yr{\_}built + \beta_{11} lat + \beta_{12} (lat^2) + \beta_{13}long + \beta_{14}zipcode + \beta_{15}renovated + \varepsilon \]
La tabla de salida es la siguiente:
# Creación de la nueva variable 'renovated'
df <- df %>%
mutate(renovated = yr_renovated > 0)
formula7 <- as.formula("log(price) ~ log(sqft_living) + log(sqft_lot) + bedrooms +
floors + bathrooms + factor(waterfront) + condition +
factor(view) + grade + yr_built + lat + I(lat^2) +
long + factor(zipcode) + factor(renovated)")
model7 <- lm(formula7, data = df)
summary(model7)
##
## Call:
## lm(formula = formula7, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.24402 -0.09918 0.00561 0.10468 1.03868
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6.004e+03 5.250e+02 -11.435 < 2e-16 ***
## log(sqft_living) 4.217e-01 6.336e-03 66.545 < 2e-16 ***
## log(sqft_lot) 7.097e-02 2.078e-03 34.155 < 2e-16 ***
## bedrooms -1.402e-02 1.806e-03 -7.765 8.51e-15 ***
## floors 1.799e-02 3.251e-03 5.535 3.15e-08 ***
## bathrooms 3.486e-02 2.929e-03 11.903 < 2e-16 ***
## factor(waterfront)1 4.354e-01 1.830e-02 23.793 < 2e-16 ***
## condition 4.499e-02 2.181e-03 20.626 < 2e-16 ***
## factor(view)1 1.204e-01 1.034e-02 11.644 < 2e-16 ***
## factor(view)2 1.110e-01 6.285e-03 17.664 < 2e-16 ***
## factor(view)3 1.834e-01 8.573e-03 21.398 < 2e-16 ***
## factor(view)4 2.904e-01 1.321e-02 21.986 < 2e-16 ***
## grade 1.115e-01 1.911e-03 58.332 < 2e-16 ***
## yr_built -3.569e-04 7.502e-05 -4.758 1.97e-06 ***
## lat 2.504e+02 2.211e+01 11.324 < 2e-16 ***
## I(lat^2) -2.628e+00 2.326e-01 -11.299 < 2e-16 ***
## long -4.088e-01 5.213e-02 -7.842 4.65e-15 ***
## factor(zipcode)98002 2.011e-02 1.650e-02 1.219 0.222954
## factor(zipcode)98003 -1.090e-02 1.473e-02 -0.740 0.459455
## factor(zipcode)98004 9.063e-01 2.806e-02 32.305 < 2e-16 ***
## factor(zipcode)98005 5.165e-01 2.989e-02 17.280 < 2e-16 ***
## factor(zipcode)98006 4.546e-01 2.561e-02 17.748 < 2e-16 ***
## factor(zipcode)98007 4.437e-01 3.084e-02 14.389 < 2e-16 ***
## factor(zipcode)98008 4.540e-01 2.943e-02 15.427 < 2e-16 ***
## factor(zipcode)98010 3.073e-01 2.528e-02 12.154 < 2e-16 ***
## factor(zipcode)98011 2.650e-01 3.651e-02 7.258 4.07e-13 ***
## factor(zipcode)98014 1.968e-01 4.049e-02 4.861 1.18e-06 ***
## factor(zipcode)98019 2.173e-01 3.950e-02 5.501 3.81e-08 ***
## factor(zipcode)98022 3.431e-01 2.443e-02 14.043 < 2e-16 ***
## factor(zipcode)98023 -6.298e-02 1.354e-02 -4.653 3.30e-06 ***
## factor(zipcode)98024 3.142e-01 3.683e-02 8.530 < 2e-16 ***
## factor(zipcode)98027 3.759e-01 2.637e-02 14.254 < 2e-16 ***
## factor(zipcode)98028 2.056e-01 3.547e-02 5.797 6.85e-09 ***
## factor(zipcode)98029 4.751e-01 2.958e-02 16.064 < 2e-16 ***
## factor(zipcode)98030 2.599e-03 1.710e-02 0.152 0.879196
## factor(zipcode)98031 -2.401e-02 1.851e-02 -1.297 0.194518
## factor(zipcode)98032 -1.287e-01 2.033e-02 -6.330 2.51e-10 ***
## factor(zipcode)98033 5.719e-01 3.076e-02 18.593 < 2e-16 ***
## factor(zipcode)98034 3.267e-01 3.260e-02 10.022 < 2e-16 ***
## factor(zipcode)98038 1.915e-01 1.916e-02 9.996 < 2e-16 ***
## factor(zipcode)98039 1.077e+00 3.700e-02 29.101 < 2e-16 ***
## factor(zipcode)98040 6.601e-01 2.574e-02 25.647 < 2e-16 ***
## factor(zipcode)98042 5.091e-02 1.641e-02 3.102 0.001922 **
## factor(zipcode)98045 3.160e-01 3.547e-02 8.909 < 2e-16 ***
## factor(zipcode)98052 4.534e-01 3.139e-02 14.445 < 2e-16 ***
## factor(zipcode)98053 4.509e-01 3.362e-02 13.412 < 2e-16 ***
## factor(zipcode)98055 -5.778e-03 2.119e-02 -0.273 0.785133
## factor(zipcode)98056 1.432e-01 2.308e-02 6.204 5.61e-10 ***
## factor(zipcode)98058 3.740e-02 2.018e-02 1.853 0.063869 .
## factor(zipcode)98059 2.034e-01 2.269e-02 8.962 < 2e-16 ***
## factor(zipcode)98065 3.744e-01 3.316e-02 11.291 < 2e-16 ***
## factor(zipcode)98070 3.340e-02 2.467e-02 1.354 0.175815
## factor(zipcode)98072 3.060e-01 3.629e-02 8.432 < 2e-16 ***
## factor(zipcode)98074 3.963e-01 3.061e-02 12.947 < 2e-16 ***
## factor(zipcode)98075 4.334e-01 2.998e-02 14.454 < 2e-16 ***
## factor(zipcode)98077 2.956e-01 3.774e-02 7.834 4.96e-15 ***
## factor(zipcode)98092 8.256e-02 1.471e-02 5.611 2.03e-08 ***
## factor(zipcode)98102 7.063e-01 3.215e-02 21.970 < 2e-16 ***
## factor(zipcode)98103 5.483e-01 2.972e-02 18.448 < 2e-16 ***
## factor(zipcode)98105 6.989e-01 3.068e-02 22.776 < 2e-16 ***
## factor(zipcode)98106 7.769e-02 2.404e-02 3.232 0.001230 **
## factor(zipcode)98107 5.569e-01 3.069e-02 18.148 < 2e-16 ***
## factor(zipcode)98108 1.054e-01 2.611e-02 4.036 5.46e-05 ***
## factor(zipcode)98109 7.183e-01 3.202e-02 22.432 < 2e-16 ***
## factor(zipcode)98112 7.980e-01 2.872e-02 27.782 < 2e-16 ***
## factor(zipcode)98115 5.551e-01 3.012e-02 18.428 < 2e-16 ***
## factor(zipcode)98116 4.531e-01 2.606e-02 17.385 < 2e-16 ***
## factor(zipcode)98117 5.208e-01 3.044e-02 17.107 < 2e-16 ***
## factor(zipcode)98118 2.308e-01 2.362e-02 9.771 < 2e-16 ***
## factor(zipcode)98119 6.881e-01 3.025e-02 22.742 < 2e-16 ***
## factor(zipcode)98122 5.509e-01 2.766e-02 19.915 < 2e-16 ***
## factor(zipcode)98125 3.070e-01 3.227e-02 9.515 < 2e-16 ***
## factor(zipcode)98126 2.712e-01 2.444e-02 11.095 < 2e-16 ***
## factor(zipcode)98133 1.985e-01 3.328e-02 5.965 2.48e-09 ***
## factor(zipcode)98136 3.950e-01 2.499e-02 15.803 < 2e-16 ***
## factor(zipcode)98144 4.237e-01 2.622e-02 16.159 < 2e-16 ***
## factor(zipcode)98146 1.940e-02 2.283e-02 0.850 0.395542
## factor(zipcode)98148 -2.994e-02 2.914e-02 -1.027 0.304256
## factor(zipcode)98155 1.894e-01 3.470e-02 5.459 4.84e-08 ***
## factor(zipcode)98166 8.044e-02 2.086e-02 3.856 0.000116 ***
## factor(zipcode)98168 -1.559e-01 2.222e-02 -7.018 2.33e-12 ***
## factor(zipcode)98177 3.239e-01 3.478e-02 9.312 < 2e-16 ***
## factor(zipcode)98178 -6.019e-02 2.295e-02 -2.622 0.008735 **
## factor(zipcode)98188 -9.044e-02 2.290e-02 -3.949 7.86e-05 ***
## factor(zipcode)98198 -7.458e-02 1.713e-02 -4.353 1.35e-05 ***
## factor(zipcode)98199 5.534e-01 2.939e-02 18.834 < 2e-16 ***
## factor(renovated)TRUE 5.721e-02 6.677e-03 8.568 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1829 on 21526 degrees of freedom
## Multiple R-squared: 0.8798, Adjusted R-squared: 0.8794
## F-statistic: 1833 on 86 and 21526 DF, p-value: < 2.2e-16
Podemos ver que tanto una vista frente al mar como las renovaciones tienen un impacto positivo en el precio. El efecto de una vista frente al mar es ~43.54 por ciento en los precios de viviendas comparables, mientras que el efecto de las renovaciones es ~5.72 por ciento.
Hasta ahora, hemos analizado los efectos globales de las variables independientes, independientemente de los valores de las otras variables. Sin embargo, podríamos preguntarnos si el efecto de una vista frente al mar es diferente para las casas que se renovaron recientemente en comparación con las que no lo fueron. Para responder a esta pregunta, necesitamos agregar un término de interacción:
\[ \log(price) = \beta_0 + \dots + \beta_{15}renovated + \beta_{16} (waterfront \times renovated)+ \varepsilon \]
formula8 <- as.formula("log(price) ~ log(sqft_living) + log(sqft_lot) + bedrooms +
floors + bathrooms + condition + factor(view) + grade +
yr_built + lat + I(lat^2) + long + factor(zipcode) +
factor(waterfront) * factor(renovated)")
model8 <- lm(formula8, data = df)
summary(model8)
##
## Call:
## lm(formula = formula8, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.24388 -0.09904 0.00561 0.10466 1.03887
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) -5.991e+03 5.250e+02 -11.412
## log(sqft_living) 4.217e-01 6.336e-03 66.566
## log(sqft_lot) 7.097e-02 2.078e-03 34.160
## bedrooms -1.404e-02 1.806e-03 -7.776
## floors 1.803e-02 3.250e-03 5.549
## bathrooms 3.483e-02 2.928e-03 11.893
## condition 4.501e-02 2.181e-03 20.639
## factor(view)1 1.202e-01 1.034e-02 11.627
## factor(view)2 1.110e-01 6.284e-03 17.659
## factor(view)3 1.833e-01 8.572e-03 21.383
## factor(view)4 2.904e-01 1.321e-02 21.989
## grade 1.114e-01 1.911e-03 58.301
## yr_built -3.547e-04 7.501e-05 -4.729
## lat 2.498e+02 2.211e+01 11.302
## I(lat^2) -2.623e+00 2.326e-01 -11.276
## long -4.085e-01 5.212e-02 -7.837
## factor(zipcode)98002 2.005e-02 1.650e-02 1.215
## factor(zipcode)98003 -1.079e-02 1.473e-02 -0.733
## factor(zipcode)98004 9.068e-01 2.805e-02 32.326
## factor(zipcode)98005 5.170e-01 2.989e-02 17.298
## factor(zipcode)98006 4.554e-01 2.561e-02 17.781
## factor(zipcode)98007 4.441e-01 3.083e-02 14.405
## factor(zipcode)98008 4.544e-01 2.943e-02 15.441
## factor(zipcode)98010 3.070e-01 2.528e-02 12.144
## factor(zipcode)98011 2.652e-01 3.650e-02 7.266
## factor(zipcode)98014 1.971e-01 4.048e-02 4.868
## factor(zipcode)98019 2.174e-01 3.949e-02 5.506
## factor(zipcode)98022 3.425e-01 2.443e-02 14.022
## factor(zipcode)98023 -6.253e-02 1.354e-02 -4.619
## factor(zipcode)98024 3.143e-01 3.683e-02 8.535
## factor(zipcode)98027 3.762e-01 2.637e-02 14.267
## factor(zipcode)98028 2.059e-01 3.547e-02 5.804
## factor(zipcode)98029 4.755e-01 2.957e-02 16.081
## factor(zipcode)98030 2.805e-03 1.710e-02 0.164
## factor(zipcode)98031 -2.372e-02 1.850e-02 -1.282
## factor(zipcode)98032 -1.285e-01 2.033e-02 -6.319
## factor(zipcode)98033 5.722e-01 3.076e-02 18.606
## factor(zipcode)98034 3.270e-01 3.259e-02 10.032
## factor(zipcode)98038 1.916e-01 1.915e-02 10.002
## factor(zipcode)98039 1.076e+00 3.700e-02 29.092
## factor(zipcode)98040 6.607e-01 2.574e-02 25.672
## factor(zipcode)98042 5.099e-02 1.641e-02 3.108
## factor(zipcode)98045 3.163e-01 3.547e-02 8.917
## factor(zipcode)98052 4.537e-01 3.138e-02 14.456
## factor(zipcode)98053 4.513e-01 3.361e-02 13.425
## factor(zipcode)98055 -5.441e-03 2.119e-02 -0.257
## factor(zipcode)98056 1.434e-01 2.308e-02 6.215
## factor(zipcode)98058 3.766e-02 2.018e-02 1.866
## factor(zipcode)98059 2.038e-01 2.269e-02 8.980
## factor(zipcode)98065 3.747e-01 3.315e-02 11.302
## factor(zipcode)98070 3.434e-02 2.467e-02 1.392
## factor(zipcode)98072 3.063e-01 3.628e-02 8.441
## factor(zipcode)98074 3.964e-01 3.060e-02 12.953
## factor(zipcode)98075 4.335e-01 2.998e-02 14.458
## factor(zipcode)98077 2.959e-01 3.773e-02 7.843
## factor(zipcode)98092 8.254e-02 1.471e-02 5.611
## factor(zipcode)98102 7.067e-01 3.214e-02 21.986
## factor(zipcode)98103 5.487e-01 2.972e-02 18.462
## factor(zipcode)98105 6.989e-01 3.068e-02 22.782
## factor(zipcode)98106 7.806e-02 2.403e-02 3.248
## factor(zipcode)98107 5.573e-01 3.068e-02 18.163
## factor(zipcode)98108 1.058e-01 2.610e-02 4.054
## factor(zipcode)98109 7.187e-01 3.202e-02 22.447
## factor(zipcode)98112 7.982e-01 2.872e-02 27.795
## factor(zipcode)98115 5.554e-01 3.012e-02 18.439
## factor(zipcode)98116 4.533e-01 2.606e-02 17.396
## factor(zipcode)98117 5.212e-01 3.044e-02 17.123
## factor(zipcode)98118 2.309e-01 2.361e-02 9.780
## factor(zipcode)98119 6.883e-01 3.025e-02 22.755
## factor(zipcode)98122 5.511e-01 2.766e-02 19.926
## factor(zipcode)98125 3.082e-01 3.226e-02 9.554
## factor(zipcode)98126 2.716e-01 2.444e-02 11.113
## factor(zipcode)98133 1.988e-01 3.327e-02 5.975
## factor(zipcode)98136 3.952e-01 2.499e-02 15.816
## factor(zipcode)98144 4.244e-01 2.622e-02 16.188
## factor(zipcode)98146 1.930e-02 2.283e-02 0.845
## factor(zipcode)98148 -2.957e-02 2.913e-02 -1.015
## factor(zipcode)98155 1.896e-01 3.469e-02 5.465
## factor(zipcode)98166 8.071e-02 2.086e-02 3.869
## factor(zipcode)98168 -1.555e-01 2.221e-02 -7.001
## factor(zipcode)98177 3.240e-01 3.478e-02 9.317
## factor(zipcode)98178 -6.028e-02 2.295e-02 -2.626
## factor(zipcode)98188 -9.008e-02 2.290e-02 -3.934
## factor(zipcode)98198 -7.421e-02 1.713e-02 -4.332
## factor(zipcode)98199 5.538e-01 2.938e-02 18.847
## factor(waterfront)1 4.585e-01 2.011e-02 22.793
## factor(renovated)TRUE 6.065e-02 6.791e-03 8.931
## factor(waterfront)1:factor(renovated)TRUE -9.231e-02 3.344e-02 -2.761
## Pr(>|t|)
## (Intercept) < 2e-16 ***
## log(sqft_living) < 2e-16 ***
## log(sqft_lot) < 2e-16 ***
## bedrooms 7.84e-15 ***
## floors 2.91e-08 ***
## bathrooms < 2e-16 ***
## condition < 2e-16 ***
## factor(view)1 < 2e-16 ***
## factor(view)2 < 2e-16 ***
## factor(view)3 < 2e-16 ***
## factor(view)4 < 2e-16 ***
## grade < 2e-16 ***
## yr_built 2.27e-06 ***
## lat < 2e-16 ***
## I(lat^2) < 2e-16 ***
## long 4.82e-15 ***
## factor(zipcode)98002 0.22422
## factor(zipcode)98003 0.46385
## factor(zipcode)98004 < 2e-16 ***
## factor(zipcode)98005 < 2e-16 ***
## factor(zipcode)98006 < 2e-16 ***
## factor(zipcode)98007 < 2e-16 ***
## factor(zipcode)98008 < 2e-16 ***
## factor(zipcode)98010 < 2e-16 ***
## factor(zipcode)98011 3.82e-13 ***
## factor(zipcode)98014 1.14e-06 ***
## factor(zipcode)98019 3.71e-08 ***
## factor(zipcode)98022 < 2e-16 ***
## factor(zipcode)98023 3.87e-06 ***
## factor(zipcode)98024 < 2e-16 ***
## factor(zipcode)98027 < 2e-16 ***
## factor(zipcode)98028 6.55e-09 ***
## factor(zipcode)98029 < 2e-16 ***
## factor(zipcode)98030 0.86967
## factor(zipcode)98031 0.19983
## factor(zipcode)98032 2.68e-10 ***
## factor(zipcode)98033 < 2e-16 ***
## factor(zipcode)98034 < 2e-16 ***
## factor(zipcode)98038 < 2e-16 ***
## factor(zipcode)98039 < 2e-16 ***
## factor(zipcode)98040 < 2e-16 ***
## factor(zipcode)98042 0.00189 **
## factor(zipcode)98045 < 2e-16 ***
## factor(zipcode)98052 < 2e-16 ***
## factor(zipcode)98053 < 2e-16 ***
## factor(zipcode)98055 0.79736
## factor(zipcode)98056 5.24e-10 ***
## factor(zipcode)98058 0.06200 .
## factor(zipcode)98059 < 2e-16 ***
## factor(zipcode)98065 < 2e-16 ***
## factor(zipcode)98070 0.16400
## factor(zipcode)98072 < 2e-16 ***
## factor(zipcode)98074 < 2e-16 ***
## factor(zipcode)98075 < 2e-16 ***
## factor(zipcode)98077 4.59e-15 ***
## factor(zipcode)98092 2.04e-08 ***
## factor(zipcode)98102 < 2e-16 ***
## factor(zipcode)98103 < 2e-16 ***
## factor(zipcode)98105 < 2e-16 ***
## factor(zipcode)98106 0.00116 **
## factor(zipcode)98107 < 2e-16 ***
## factor(zipcode)98108 5.04e-05 ***
## factor(zipcode)98109 < 2e-16 ***
## factor(zipcode)98112 < 2e-16 ***
## factor(zipcode)98115 < 2e-16 ***
## factor(zipcode)98116 < 2e-16 ***
## factor(zipcode)98117 < 2e-16 ***
## factor(zipcode)98118 < 2e-16 ***
## factor(zipcode)98119 < 2e-16 ***
## factor(zipcode)98122 < 2e-16 ***
## factor(zipcode)98125 < 2e-16 ***
## factor(zipcode)98126 < 2e-16 ***
## factor(zipcode)98133 2.34e-09 ***
## factor(zipcode)98136 < 2e-16 ***
## factor(zipcode)98144 < 2e-16 ***
## factor(zipcode)98146 0.39789
## factor(zipcode)98148 0.31020
## factor(zipcode)98155 4.69e-08 ***
## factor(zipcode)98166 0.00011 ***
## factor(zipcode)98168 2.61e-12 ***
## factor(zipcode)98177 < 2e-16 ***
## factor(zipcode)98178 0.00864 **
## factor(zipcode)98188 8.37e-05 ***
## factor(zipcode)98198 1.48e-05 ***
## factor(zipcode)98199 < 2e-16 ***
## factor(waterfront)1 < 2e-16 ***
## factor(renovated)TRUE < 2e-16 ***
## factor(waterfront)1:factor(renovated)TRUE 0.00578 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1829 on 21525 degrees of freedom
## Multiple R-squared: 0.8799, Adjusted R-squared: 0.8794
## F-statistic: 1812 on 87 and 21525 DF, p-value: < 2.2e-16
Parece haber un pequeño efecto diferencial entre las propiedades con frente al mar que se renovaron frente a las que no se renovaron (\(\beta_{16}=-0,0923\)).
Consideremos el siguiente modelo de referencia.
# Modelo de referencia final con interacciones
formula_ref <- as.formula("log(price) ~ log(sqft_living) * factor(renovated) +
log(sqft_lot) + bedrooms + floors + bathrooms +
condition + factor(view) + grade + yr_built +
lat * factor(waterfront) + I(lat^2) + long +
factor(zipcode)")
model_ref <- lm(formula_ref, data = df)
summary(model_ref)
##
## Call:
## lm(formula = formula_ref, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.24455 -0.09884 0.00580 0.10424 1.03863
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -5.899e+03 5.247e+02 -11.242 < 2e-16
## log(sqft_living) 4.205e-01 6.354e-03 66.169 < 2e-16
## factor(renovated)TRUE -1.557e-01 1.084e-01 -1.436 0.150901
## log(sqft_lot) 7.079e-02 2.076e-03 34.099 < 2e-16
## bedrooms -1.405e-02 1.804e-03 -7.791 6.96e-15
## floors 1.784e-02 3.248e-03 5.492 4.03e-08
## bathrooms 3.446e-02 2.929e-03 11.763 < 2e-16
## condition 4.507e-02 2.179e-03 20.685 < 2e-16
## factor(view)1 1.197e-01 1.033e-02 11.587 < 2e-16
## factor(view)2 1.110e-01 6.280e-03 17.668 < 2e-16
## factor(view)3 1.840e-01 8.570e-03 21.471 < 2e-16
## factor(view)4 2.863e-01 1.321e-02 21.680 < 2e-16
## grade 1.114e-01 1.910e-03 58.335 < 2e-16
## yr_built -3.531e-04 7.501e-05 -4.707 2.52e-06
## lat 2.460e+02 2.210e+01 11.131 < 2e-16
## factor(waterfront)1 -3.922e+01 6.093e+00 -6.437 1.24e-10
## I(lat^2) -2.582e+00 2.325e-01 -11.106 < 2e-16
## long -4.103e-01 5.209e-02 -7.876 3.53e-15
## factor(zipcode)98002 1.975e-02 1.648e-02 1.198 0.230880
## factor(zipcode)98003 -1.101e-02 1.472e-02 -0.748 0.454516
## factor(zipcode)98004 9.112e-01 2.805e-02 32.490 < 2e-16
## factor(zipcode)98005 5.227e-01 2.988e-02 17.494 < 2e-16
## factor(zipcode)98006 4.607e-01 2.560e-02 17.991 < 2e-16
## factor(zipcode)98007 4.495e-01 3.082e-02 14.584 < 2e-16
## factor(zipcode)98008 4.584e-01 2.941e-02 15.587 < 2e-16
## factor(zipcode)98010 3.090e-01 2.526e-02 12.235 < 2e-16
## factor(zipcode)98011 2.708e-01 3.648e-02 7.424 1.18e-13
## factor(zipcode)98014 2.036e-01 4.046e-02 5.032 4.89e-07
## factor(zipcode)98019 2.236e-01 3.947e-02 5.665 1.49e-08
## factor(zipcode)98022 3.401e-01 2.441e-02 13.932 < 2e-16
## factor(zipcode)98023 -6.187e-02 1.352e-02 -4.574 4.80e-06
## factor(zipcode)98024 3.202e-01 3.681e-02 8.701 < 2e-16
## factor(zipcode)98027 3.814e-01 2.636e-02 14.468 < 2e-16
## factor(zipcode)98028 2.104e-01 3.544e-02 5.937 2.95e-09
## factor(zipcode)98029 4.810e-01 2.956e-02 16.270 < 2e-16
## factor(zipcode)98030 4.362e-03 1.709e-02 0.255 0.798492
## factor(zipcode)98031 -2.145e-02 1.849e-02 -1.160 0.246155
## factor(zipcode)98032 -1.272e-01 2.031e-02 -6.262 3.88e-10
## factor(zipcode)98033 5.770e-01 3.074e-02 18.771 < 2e-16
## factor(zipcode)98034 3.307e-01 3.257e-02 10.152 < 2e-16
## factor(zipcode)98038 1.937e-01 1.914e-02 10.120 < 2e-16
## factor(zipcode)98039 1.079e+00 3.699e-02 29.182 < 2e-16
## factor(zipcode)98040 6.642e-01 2.573e-02 25.817 < 2e-16
## factor(zipcode)98042 5.298e-02 1.640e-02 3.231 0.001237
## factor(zipcode)98045 3.211e-01 3.545e-02 9.057 < 2e-16
## factor(zipcode)98052 4.592e-01 3.137e-02 14.639 < 2e-16
## factor(zipcode)98053 4.574e-01 3.360e-02 13.611 < 2e-16
## factor(zipcode)98055 -2.006e-03 2.118e-02 -0.095 0.924543
## factor(zipcode)98056 1.479e-01 2.307e-02 6.411 1.48e-10
## factor(zipcode)98058 4.125e-02 2.017e-02 2.045 0.040875
## factor(zipcode)98059 2.082e-01 2.268e-02 9.178 < 2e-16
## factor(zipcode)98065 3.805e-01 3.314e-02 11.481 < 2e-16
## factor(zipcode)98070 5.955e-02 2.495e-02 2.387 0.016997
## factor(zipcode)98072 3.117e-01 3.626e-02 8.595 < 2e-16
## factor(zipcode)98074 4.018e-01 3.059e-02 13.136 < 2e-16
## factor(zipcode)98075 4.392e-01 2.997e-02 14.657 < 2e-16
## factor(zipcode)98077 3.022e-01 3.771e-02 8.014 1.16e-15
## factor(zipcode)98092 8.260e-02 1.470e-02 5.620 1.94e-08
## factor(zipcode)98102 7.113e-01 3.213e-02 22.140 < 2e-16
## factor(zipcode)98103 5.536e-01 2.970e-02 18.637 < 2e-16
## factor(zipcode)98105 7.028e-01 3.066e-02 22.924 < 2e-16
## factor(zipcode)98106 8.211e-02 2.402e-02 3.418 0.000631
## factor(zipcode)98107 5.620e-01 3.067e-02 18.327 < 2e-16
## factor(zipcode)98108 1.101e-01 2.609e-02 4.219 2.47e-05
## factor(zipcode)98109 7.237e-01 3.200e-02 22.616 < 2e-16
## factor(zipcode)98112 8.037e-01 2.871e-02 27.996 < 2e-16
## factor(zipcode)98115 5.603e-01 3.010e-02 18.612 < 2e-16
## factor(zipcode)98116 4.584e-01 2.605e-02 17.598 < 2e-16
## factor(zipcode)98117 5.259e-01 3.042e-02 17.285 < 2e-16
## factor(zipcode)98118 2.353e-01 2.361e-02 9.970 < 2e-16
## factor(zipcode)98119 6.934e-01 3.023e-02 22.935 < 2e-16
## factor(zipcode)98122 5.562e-01 2.765e-02 20.117 < 2e-16
## factor(zipcode)98125 3.094e-01 3.224e-02 9.598 < 2e-16
## factor(zipcode)98126 2.755e-01 2.443e-02 11.280 < 2e-16
## factor(zipcode)98133 2.034e-01 3.325e-02 6.116 9.78e-10
## factor(zipcode)98136 3.996e-01 2.498e-02 15.999 < 2e-16
## factor(zipcode)98144 4.280e-01 2.621e-02 16.334 < 2e-16
## factor(zipcode)98146 2.453e-02 2.282e-02 1.075 0.282475
## factor(zipcode)98148 -2.690e-02 2.911e-02 -0.924 0.355511
## factor(zipcode)98155 1.921e-01 3.466e-02 5.540 3.05e-08
## factor(zipcode)98166 8.839e-02 2.088e-02 4.233 2.31e-05
## factor(zipcode)98168 -1.520e-01 2.220e-02 -6.846 7.78e-12
## factor(zipcode)98177 3.280e-01 3.475e-02 9.438 < 2e-16
## factor(zipcode)98178 -5.493e-02 2.294e-02 -2.394 0.016679
## factor(zipcode)98188 -8.701e-02 2.288e-02 -3.803 0.000144
## factor(zipcode)98198 -6.716e-02 1.715e-02 -3.916 9.04e-05
## factor(zipcode)98199 5.583e-01 2.937e-02 19.014 < 2e-16
## log(sqft_living):factor(renovated)TRUE 2.796e-02 1.417e-02 1.972 0.048580
## lat:factor(waterfront)1 8.342e-01 1.282e-01 6.508 7.77e-11
##
## (Intercept) ***
## log(sqft_living) ***
## factor(renovated)TRUE
## log(sqft_lot) ***
## bedrooms ***
## floors ***
## bathrooms ***
## condition ***
## factor(view)1 ***
## factor(view)2 ***
## factor(view)3 ***
## factor(view)4 ***
## grade ***
## yr_built ***
## lat ***
## factor(waterfront)1 ***
## I(lat^2) ***
## long ***
## factor(zipcode)98002
## factor(zipcode)98003
## factor(zipcode)98004 ***
## factor(zipcode)98005 ***
## factor(zipcode)98006 ***
## factor(zipcode)98007 ***
## factor(zipcode)98008 ***
## factor(zipcode)98010 ***
## factor(zipcode)98011 ***
## factor(zipcode)98014 ***
## factor(zipcode)98019 ***
## factor(zipcode)98022 ***
## factor(zipcode)98023 ***
## factor(zipcode)98024 ***
## factor(zipcode)98027 ***
## factor(zipcode)98028 ***
## factor(zipcode)98029 ***
## factor(zipcode)98030
## factor(zipcode)98031
## factor(zipcode)98032 ***
## factor(zipcode)98033 ***
## factor(zipcode)98034 ***
## factor(zipcode)98038 ***
## factor(zipcode)98039 ***
## factor(zipcode)98040 ***
## factor(zipcode)98042 **
## factor(zipcode)98045 ***
## factor(zipcode)98052 ***
## factor(zipcode)98053 ***
## factor(zipcode)98055
## factor(zipcode)98056 ***
## factor(zipcode)98058 *
## factor(zipcode)98059 ***
## factor(zipcode)98065 ***
## factor(zipcode)98070 *
## factor(zipcode)98072 ***
## factor(zipcode)98074 ***
## factor(zipcode)98075 ***
## factor(zipcode)98077 ***
## factor(zipcode)98092 ***
## factor(zipcode)98102 ***
## factor(zipcode)98103 ***
## factor(zipcode)98105 ***
## factor(zipcode)98106 ***
## factor(zipcode)98107 ***
## factor(zipcode)98108 ***
## factor(zipcode)98109 ***
## factor(zipcode)98112 ***
## factor(zipcode)98115 ***
## factor(zipcode)98116 ***
## factor(zipcode)98117 ***
## factor(zipcode)98118 ***
## factor(zipcode)98119 ***
## factor(zipcode)98122 ***
## factor(zipcode)98125 ***
## factor(zipcode)98126 ***
## factor(zipcode)98133 ***
## factor(zipcode)98136 ***
## factor(zipcode)98144 ***
## factor(zipcode)98146
## factor(zipcode)98148
## factor(zipcode)98155 ***
## factor(zipcode)98166 ***
## factor(zipcode)98168 ***
## factor(zipcode)98177 ***
## factor(zipcode)98178 *
## factor(zipcode)98188 ***
## factor(zipcode)98198 ***
## factor(zipcode)98199 ***
## log(sqft_living):factor(renovated)TRUE *
## lat:factor(waterfront)1 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1827 on 21524 degrees of freedom
## Multiple R-squared: 0.8801, Adjusted R-squared: 0.8796
## F-statistic: 1795 on 88 and 21524 DF, p-value: < 2.2e-16
cat(paste0("AIC: ", AIC(model_ref), " R²_adj: ", summary(model_ref)$adj.r.squared))
## AIC: -12043.342504192 R²_adj: 0.879607577946144
El AIC para el modelo de referencia fue de \(-12045,34\) y el \(R^2_{adj}\) fue de \(0,8796\). Expandamos el modelo haciendo lo siguiente:
A continuación se muestran las tablas de salida. Compare el ajuste y el AIC de estos modelos entre sí y con el modelo anterior. ¿Cuál es el mejor modelo?
Aquí está la tabla para el modelo con \(\beta_{17}(yr{\_}built^2)\) adicional:
# Se añade el término cuadrático para yr_built
formula9 <- update(formula_ref, . ~ . + I(yr_built^2))
model9 <- lm(formula9, data = df)
summary(model9)
##
## Call:
## lm(formula = formula9, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.26457 -0.09625 0.00683 0.10076 1.00008
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6.013e+03 5.165e+02 -11.642 < 2e-16
## log(sqft_living) 4.116e-01 6.263e-03 65.718 < 2e-16
## factor(renovated)TRUE -3.768e-01 1.070e-01 -3.521 0.000431
## log(sqft_lot) 8.526e-02 2.116e-03 40.296 < 2e-16
## bedrooms -1.039e-02 1.781e-03 -5.833 5.52e-09
## floors -1.211e-02 3.393e-03 -3.569 0.000359
## bathrooms 2.501e-02 2.906e-03 8.608 < 2e-16
## condition 5.392e-02 2.171e-03 24.837 < 2e-16
## factor(view)1 1.278e-01 1.017e-02 12.563 < 2e-16
## factor(view)2 1.187e-01 6.188e-03 19.179 < 2e-16
## factor(view)3 1.911e-01 8.439e-03 22.649 < 2e-16
## factor(view)4 3.004e-01 1.301e-02 23.090 < 2e-16
## grade 1.081e-01 1.884e-03 57.358 < 2e-16
## yr_built -1.904e-01 7.213e-03 -26.398 < 2e-16
## lat 2.583e+02 2.175e+01 11.875 < 2e-16
## factor(waterfront)1 -3.975e+01 5.998e+00 -6.628 3.49e-11
## I(lat^2) -2.712e+00 2.289e-01 -11.849 < 2e-16
## long -4.591e-01 5.130e-02 -8.948 < 2e-16
## factor(zipcode)98002 2.289e-02 1.623e-02 1.410 0.158424
## factor(zipcode)98003 7.152e-03 1.450e-02 0.493 0.621893
## factor(zipcode)98004 9.255e-01 2.761e-02 33.521 < 2e-16
## factor(zipcode)98005 5.504e-01 2.942e-02 18.705 < 2e-16
## factor(zipcode)98006 4.796e-01 2.521e-02 19.025 < 2e-16
## factor(zipcode)98007 4.816e-01 3.036e-02 15.864 < 2e-16
## factor(zipcode)98008 4.907e-01 2.897e-02 16.937 < 2e-16
## factor(zipcode)98010 3.003e-01 2.486e-02 12.078 < 2e-16
## factor(zipcode)98011 2.842e-01 3.591e-02 7.913 2.63e-15
## factor(zipcode)98014 2.018e-01 3.983e-02 5.066 4.09e-07
## factor(zipcode)98019 2.216e-01 3.885e-02 5.704 1.19e-08
## factor(zipcode)98022 3.436e-01 2.403e-02 14.300 < 2e-16
## factor(zipcode)98023 -4.711e-02 1.332e-02 -3.536 0.000408
## factor(zipcode)98024 3.108e-01 3.623e-02 8.579 < 2e-16
## factor(zipcode)98027 3.860e-01 2.595e-02 14.877 < 2e-16
## factor(zipcode)98028 2.199e-01 3.489e-02 6.302 2.99e-10
## factor(zipcode)98029 4.917e-01 2.910e-02 16.897 < 2e-16
## factor(zipcode)98030 4.541e-03 1.682e-02 0.270 0.787129
## factor(zipcode)98031 -9.648e-03 1.821e-02 -0.530 0.596238
## factor(zipcode)98032 -1.094e-01 2.000e-02 -5.471 4.52e-08
## factor(zipcode)98033 5.861e-01 3.026e-02 19.369 < 2e-16
## factor(zipcode)98034 3.511e-01 3.207e-02 10.948 < 2e-16
## factor(zipcode)98038 1.902e-01 1.884e-02 10.091 < 2e-16
## factor(zipcode)98039 1.093e+00 3.641e-02 30.025 < 2e-16
## factor(zipcode)98040 6.889e-01 2.534e-02 27.185 < 2e-16
## factor(zipcode)98042 5.733e-02 1.614e-02 3.552 0.000384
## factor(zipcode)98045 3.307e-01 3.489e-02 9.478 < 2e-16
## factor(zipcode)98052 4.752e-01 3.088e-02 15.387 < 2e-16
## factor(zipcode)98053 4.428e-01 3.308e-02 13.386 < 2e-16
## factor(zipcode)98055 2.922e-03 2.085e-02 0.140 0.888528
## factor(zipcode)98056 1.486e-01 2.271e-02 6.544 6.13e-11
## factor(zipcode)98058 5.756e-02 1.986e-02 2.898 0.003763
## factor(zipcode)98059 2.032e-01 2.233e-02 9.101 < 2e-16
## factor(zipcode)98065 3.725e-01 3.262e-02 11.419 < 2e-16
## factor(zipcode)98070 2.707e-02 2.459e-02 1.101 0.270925
## factor(zipcode)98072 3.254e-01 3.570e-02 9.117 < 2e-16
## factor(zipcode)98074 4.170e-01 3.011e-02 13.848 < 2e-16
## factor(zipcode)98075 4.449e-01 2.950e-02 15.084 < 2e-16
## factor(zipcode)98077 3.149e-01 3.712e-02 8.484 < 2e-16
## factor(zipcode)98092 8.501e-02 1.447e-02 5.876 4.27e-09
## factor(zipcode)98102 6.989e-01 3.162e-02 22.101 < 2e-16
## factor(zipcode)98103 5.366e-01 2.924e-02 18.349 < 2e-16
## factor(zipcode)98105 7.024e-01 3.018e-02 23.275 < 2e-16
## factor(zipcode)98106 7.163e-02 2.365e-02 3.029 0.002455
## factor(zipcode)98107 5.423e-01 3.019e-02 17.963 < 2e-16
## factor(zipcode)98108 9.577e-02 2.569e-02 3.728 0.000193
## factor(zipcode)98109 7.049e-01 3.150e-02 22.376 < 2e-16
## factor(zipcode)98112 7.964e-01 2.826e-02 28.187 < 2e-16
## factor(zipcode)98115 5.667e-01 2.963e-02 19.125 < 2e-16
## factor(zipcode)98116 4.464e-01 2.564e-02 17.409 < 2e-16
## factor(zipcode)98117 5.189e-01 2.995e-02 17.327 < 2e-16
## factor(zipcode)98118 2.234e-01 2.324e-02 9.614 < 2e-16
## factor(zipcode)98119 6.693e-01 2.977e-02 22.480 < 2e-16
## factor(zipcode)98122 5.282e-01 2.723e-02 19.394 < 2e-16
## factor(zipcode)98125 3.278e-01 3.174e-02 10.329 < 2e-16
## factor(zipcode)98126 2.655e-01 2.405e-02 11.043 < 2e-16
## factor(zipcode)98133 2.136e-01 3.273e-02 6.525 6.95e-11
## factor(zipcode)98136 3.883e-01 2.459e-02 15.791 < 2e-16
## factor(zipcode)98144 4.058e-01 2.581e-02 15.723 < 2e-16
## factor(zipcode)98146 2.771e-02 2.246e-02 1.234 0.217392
## factor(zipcode)98148 -1.330e-02 2.866e-02 -0.464 0.642485
## factor(zipcode)98155 2.101e-01 3.413e-02 6.157 7.57e-10
## factor(zipcode)98166 9.659e-02 2.055e-02 4.700 2.62e-06
## factor(zipcode)98168 -1.457e-01 2.185e-02 -6.667 2.67e-11
## factor(zipcode)98177 3.463e-01 3.421e-02 10.122 < 2e-16
## factor(zipcode)98178 -4.145e-02 2.259e-02 -1.835 0.066505
## factor(zipcode)98188 -7.429e-02 2.253e-02 -3.298 0.000975
## factor(zipcode)98198 -5.372e-02 1.689e-02 -3.181 0.001471
## factor(zipcode)98199 5.682e-01 2.891e-02 19.656 < 2e-16
## I(yr_built^2) 4.854e-05 1.842e-06 26.350 < 2e-16
## log(sqft_living):factor(renovated)TRUE 5.844e-02 1.400e-02 4.175 2.99e-05
## lat:factor(waterfront)1 8.452e-01 1.262e-01 6.699 2.15e-11
##
## (Intercept) ***
## log(sqft_living) ***
## factor(renovated)TRUE ***
## log(sqft_lot) ***
## bedrooms ***
## floors ***
## bathrooms ***
## condition ***
## factor(view)1 ***
## factor(view)2 ***
## factor(view)3 ***
## factor(view)4 ***
## grade ***
## yr_built ***
## lat ***
## factor(waterfront)1 ***
## I(lat^2) ***
## long ***
## factor(zipcode)98002
## factor(zipcode)98003
## factor(zipcode)98004 ***
## factor(zipcode)98005 ***
## factor(zipcode)98006 ***
## factor(zipcode)98007 ***
## factor(zipcode)98008 ***
## factor(zipcode)98010 ***
## factor(zipcode)98011 ***
## factor(zipcode)98014 ***
## factor(zipcode)98019 ***
## factor(zipcode)98022 ***
## factor(zipcode)98023 ***
## factor(zipcode)98024 ***
## factor(zipcode)98027 ***
## factor(zipcode)98028 ***
## factor(zipcode)98029 ***
## factor(zipcode)98030
## factor(zipcode)98031
## factor(zipcode)98032 ***
## factor(zipcode)98033 ***
## factor(zipcode)98034 ***
## factor(zipcode)98038 ***
## factor(zipcode)98039 ***
## factor(zipcode)98040 ***
## factor(zipcode)98042 ***
## factor(zipcode)98045 ***
## factor(zipcode)98052 ***
## factor(zipcode)98053 ***
## factor(zipcode)98055
## factor(zipcode)98056 ***
## factor(zipcode)98058 **
## factor(zipcode)98059 ***
## factor(zipcode)98065 ***
## factor(zipcode)98070
## factor(zipcode)98072 ***
## factor(zipcode)98074 ***
## factor(zipcode)98075 ***
## factor(zipcode)98077 ***
## factor(zipcode)98092 ***
## factor(zipcode)98102 ***
## factor(zipcode)98103 ***
## factor(zipcode)98105 ***
## factor(zipcode)98106 **
## factor(zipcode)98107 ***
## factor(zipcode)98108 ***
## factor(zipcode)98109 ***
## factor(zipcode)98112 ***
## factor(zipcode)98115 ***
## factor(zipcode)98116 ***
## factor(zipcode)98117 ***
## factor(zipcode)98118 ***
## factor(zipcode)98119 ***
## factor(zipcode)98122 ***
## factor(zipcode)98125 ***
## factor(zipcode)98126 ***
## factor(zipcode)98133 ***
## factor(zipcode)98136 ***
## factor(zipcode)98144 ***
## factor(zipcode)98146
## factor(zipcode)98148
## factor(zipcode)98155 ***
## factor(zipcode)98166 ***
## factor(zipcode)98168 ***
## factor(zipcode)98177 ***
## factor(zipcode)98178 .
## factor(zipcode)98188 ***
## factor(zipcode)98198 **
## factor(zipcode)98199 ***
## I(yr_built^2) ***
## log(sqft_living):factor(renovated)TRUE ***
## lat:factor(waterfront)1 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1799 on 21523 degrees of freedom
## Multiple R-squared: 0.8838, Adjusted R-squared: 0.8834
## F-statistic: 1840 on 89 and 21523 DF, p-value: < 2.2e-16
Tabla con un \(\beta_{17}\) adicional (has_basement×long) (sin el término de año al cuadrado):
# Se crea la variable has_basement
df <- df %>%
mutate(has_basement = as.factor(ifelse(sqft_basement > 0, 1, 0)))
# Se añade el término de interacción
formula10 <- update(formula_ref, . ~ . + has_basement * long)
model10 <- lm(formula10, data = df)
summary(model10)
##
## Call:
## lm(formula = formula10, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.25108 -0.09727 0.00582 0.10381 1.01650
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6.311e+03 5.228e+02 -12.073 < 2e-16
## log(sqft_living) 4.512e-01 6.713e-03 67.209 < 2e-16
## factor(renovated)TRUE -1.974e-01 1.079e-01 -1.829 0.067376
## log(sqft_lot) 6.694e-02 2.096e-03 31.931 < 2e-16
## bedrooms -1.542e-02 1.797e-03 -8.582 < 2e-16
## floors -5.882e-03 3.617e-03 -1.626 0.103872
## bathrooms 4.034e-02 2.940e-03 13.717 < 2e-16
## condition 4.611e-02 2.170e-03 21.248 < 2e-16
## factor(view)1 1.259e-01 1.029e-02 12.235 < 2e-16
## factor(view)2 1.162e-01 6.258e-03 18.563 < 2e-16
## factor(view)3 1.904e-01 8.537e-03 22.301 < 2e-16
## factor(view)4 2.938e-01 1.315e-02 22.347 < 2e-16
## grade 1.069e-01 1.925e-03 55.518 < 2e-16
## yr_built -2.613e-04 7.488e-05 -3.490 0.000484
## lat 2.634e+02 2.201e+01 11.963 < 2e-16
## factor(waterfront)1 -3.908e+01 6.065e+00 -6.443 1.20e-10
## I(lat^2) -2.765e+00 2.316e-01 -11.938 < 2e-16
## long -4.035e-01 5.193e-02 -7.769 8.25e-15
## factor(zipcode)98002 1.583e-02 1.640e-02 0.965 0.334467
## factor(zipcode)98003 -9.422e-03 1.464e-02 -0.643 0.519941
## factor(zipcode)98004 9.125e-01 2.793e-02 32.676 < 2e-16
## factor(zipcode)98005 5.267e-01 2.976e-02 17.701 < 2e-16
## factor(zipcode)98006 4.645e-01 2.551e-02 18.205 < 2e-16
## factor(zipcode)98007 4.501e-01 3.069e-02 14.666 < 2e-16
## factor(zipcode)98008 4.616e-01 2.931e-02 15.747 < 2e-16
## factor(zipcode)98010 3.090e-01 2.513e-02 12.295 < 2e-16
## factor(zipcode)98011 2.829e-01 3.634e-02 7.785 7.29e-15
## factor(zipcode)98014 2.056e-01 4.026e-02 5.108 3.29e-07
## factor(zipcode)98019 2.307e-01 3.929e-02 5.872 4.38e-09
## factor(zipcode)98022 3.447e-01 2.429e-02 14.194 < 2e-16
## factor(zipcode)98023 -5.900e-02 1.347e-02 -4.380 1.20e-05
## factor(zipcode)98024 3.186e-01 3.663e-02 8.700 < 2e-16
## factor(zipcode)98027 3.927e-01 2.630e-02 14.931 < 2e-16
## factor(zipcode)98028 2.228e-01 3.529e-02 6.313 2.79e-10
## factor(zipcode)98029 4.774e-01 2.942e-02 16.225 < 2e-16
## factor(zipcode)98030 7.894e-04 1.700e-02 0.046 0.962971
## factor(zipcode)98031 -2.349e-02 1.840e-02 -1.276 0.201863
## factor(zipcode)98032 -1.237e-01 2.021e-02 -6.118 9.61e-10
## factor(zipcode)98033 5.816e-01 3.061e-02 19.000 < 2e-16
## factor(zipcode)98034 3.412e-01 3.244e-02 10.517 < 2e-16
## factor(zipcode)98038 1.859e-01 1.905e-02 9.758 < 2e-16
## factor(zipcode)98039 1.074e+00 3.682e-02 29.164 < 2e-16
## factor(zipcode)98040 6.653e-01 2.561e-02 25.976 < 2e-16
## factor(zipcode)98042 4.778e-02 1.632e-02 2.928 0.003419
## factor(zipcode)98045 3.166e-01 3.527e-02 8.975 < 2e-16
## factor(zipcode)98052 4.657e-01 3.125e-02 14.900 < 2e-16
## factor(zipcode)98053 4.487e-01 3.345e-02 13.415 < 2e-16
## factor(zipcode)98055 -4.129e-03 2.108e-02 -0.196 0.844692
## factor(zipcode)98056 1.421e-01 2.297e-02 6.187 6.24e-10
## factor(zipcode)98058 3.920e-02 2.008e-02 1.952 0.050915
## factor(zipcode)98059 1.976e-01 2.259e-02 8.749 < 2e-16
## factor(zipcode)98065 3.690e-01 3.298e-02 11.188 < 2e-16
## factor(zipcode)98070 5.861e-02 2.482e-02 2.361 0.018237
## factor(zipcode)98072 3.261e-01 3.613e-02 9.027 < 2e-16
## factor(zipcode)98074 4.012e-01 3.046e-02 13.173 < 2e-16
## factor(zipcode)98075 4.311e-01 2.984e-02 14.450 < 2e-16
## factor(zipcode)98077 3.101e-01 3.755e-02 8.258 < 2e-16
## factor(zipcode)98092 8.135e-02 1.462e-02 5.563 2.69e-08
## factor(zipcode)98102 7.386e-01 3.201e-02 23.071 < 2e-16
## factor(zipcode)98103 5.724e-01 2.958e-02 19.353 < 2e-16
## factor(zipcode)98105 7.246e-01 3.054e-02 23.729 < 2e-16
## factor(zipcode)98106 9.178e-02 2.391e-02 3.838 0.000124
## factor(zipcode)98107 5.827e-01 3.054e-02 19.079 < 2e-16
## factor(zipcode)98108 1.200e-01 2.597e-02 4.620 3.86e-06
## factor(zipcode)98109 7.430e-01 3.186e-02 23.320 < 2e-16
## factor(zipcode)98112 8.251e-01 2.859e-02 28.857 < 2e-16
## factor(zipcode)98115 5.806e-01 2.998e-02 19.366 < 2e-16
## factor(zipcode)98116 4.713e-01 2.595e-02 18.162 < 2e-16
## factor(zipcode)98117 5.437e-01 3.029e-02 17.949 < 2e-16
## factor(zipcode)98118 2.447e-01 2.349e-02 10.416 < 2e-16
## factor(zipcode)98119 7.156e-01 3.012e-02 23.757 < 2e-16
## factor(zipcode)98122 5.752e-01 2.753e-02 20.890 < 2e-16
## factor(zipcode)98125 3.242e-01 3.209e-02 10.104 < 2e-16
## factor(zipcode)98126 2.842e-01 2.431e-02 11.689 < 2e-16
## factor(zipcode)98133 2.187e-01 3.310e-02 6.606 4.05e-11
## factor(zipcode)98136 4.113e-01 2.488e-02 16.529 < 2e-16
## factor(zipcode)98144 4.455e-01 2.610e-02 17.072 < 2e-16
## factor(zipcode)98146 2.400e-02 2.270e-02 1.057 0.290352
## factor(zipcode)98148 -3.260e-02 2.896e-02 -1.125 0.260396
## factor(zipcode)98155 2.058e-01 3.451e-02 5.964 2.50e-09
## factor(zipcode)98166 8.743e-02 2.078e-02 4.209 2.58e-05
## factor(zipcode)98168 -1.487e-01 2.209e-02 -6.731 1.73e-11
## factor(zipcode)98177 3.406e-01 3.458e-02 9.849 < 2e-16
## factor(zipcode)98178 -5.133e-02 2.283e-02 -2.249 0.024547
## factor(zipcode)98188 -8.794e-02 2.276e-02 -3.863 0.000112
## factor(zipcode)98198 -6.887e-02 1.706e-02 -4.036 5.46e-05
## factor(zipcode)98199 5.758e-01 2.927e-02 19.672 < 2e-16
## has_basement1 -7.245e+00 2.607e+00 -2.779 0.005463
## log(sqft_living):factor(renovated)TRUE 3.350e-02 1.411e-02 2.375 0.017569
## lat:factor(waterfront)1 8.311e-01 1.276e-01 6.515 7.45e-11
## long:has_basement1 -5.887e-02 2.133e-02 -2.760 0.005787
##
## (Intercept) ***
## log(sqft_living) ***
## factor(renovated)TRUE .
## log(sqft_lot) ***
## bedrooms ***
## floors
## bathrooms ***
## condition ***
## factor(view)1 ***
## factor(view)2 ***
## factor(view)3 ***
## factor(view)4 ***
## grade ***
## yr_built ***
## lat ***
## factor(waterfront)1 ***
## I(lat^2) ***
## long ***
## factor(zipcode)98002
## factor(zipcode)98003
## factor(zipcode)98004 ***
## factor(zipcode)98005 ***
## factor(zipcode)98006 ***
## factor(zipcode)98007 ***
## factor(zipcode)98008 ***
## factor(zipcode)98010 ***
## factor(zipcode)98011 ***
## factor(zipcode)98014 ***
## factor(zipcode)98019 ***
## factor(zipcode)98022 ***
## factor(zipcode)98023 ***
## factor(zipcode)98024 ***
## factor(zipcode)98027 ***
## factor(zipcode)98028 ***
## factor(zipcode)98029 ***
## factor(zipcode)98030
## factor(zipcode)98031
## factor(zipcode)98032 ***
## factor(zipcode)98033 ***
## factor(zipcode)98034 ***
## factor(zipcode)98038 ***
## factor(zipcode)98039 ***
## factor(zipcode)98040 ***
## factor(zipcode)98042 **
## factor(zipcode)98045 ***
## factor(zipcode)98052 ***
## factor(zipcode)98053 ***
## factor(zipcode)98055
## factor(zipcode)98056 ***
## factor(zipcode)98058 .
## factor(zipcode)98059 ***
## factor(zipcode)98065 ***
## factor(zipcode)98070 *
## factor(zipcode)98072 ***
## factor(zipcode)98074 ***
## factor(zipcode)98075 ***
## factor(zipcode)98077 ***
## factor(zipcode)98092 ***
## factor(zipcode)98102 ***
## factor(zipcode)98103 ***
## factor(zipcode)98105 ***
## factor(zipcode)98106 ***
## factor(zipcode)98107 ***
## factor(zipcode)98108 ***
## factor(zipcode)98109 ***
## factor(zipcode)98112 ***
## factor(zipcode)98115 ***
## factor(zipcode)98116 ***
## factor(zipcode)98117 ***
## factor(zipcode)98118 ***
## factor(zipcode)98119 ***
## factor(zipcode)98122 ***
## factor(zipcode)98125 ***
## factor(zipcode)98126 ***
## factor(zipcode)98133 ***
## factor(zipcode)98136 ***
## factor(zipcode)98144 ***
## factor(zipcode)98146
## factor(zipcode)98148
## factor(zipcode)98155 ***
## factor(zipcode)98166 ***
## factor(zipcode)98168 ***
## factor(zipcode)98177 ***
## factor(zipcode)98178 *
## factor(zipcode)98188 ***
## factor(zipcode)98198 ***
## factor(zipcode)98199 ***
## has_basement1 **
## log(sqft_living):factor(renovated)TRUE *
## lat:factor(waterfront)1 ***
## long:has_basement1 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1818 on 21522 degrees of freedom
## Multiple R-squared: 0.8813, Adjusted R-squared: 0.8808
## F-statistic: 1776 on 90 and 21522 DF, p-value: < 2.2e-16
Respuesta.
Los efectos son significativos en ambos casos. Ambos modelos mejoran el ajuste de nuestro modelo de referencia, pero la adición de un término cuadrático para el año de construcción conduce a un AIC más bajo y un R-cuadrado más alto (\(R^2_{adj}=0.883, AIC=-12729.6\)) en comparación con la interacción entre sótano y longitud (\(R^2_{adj}=0.881, AIC=-12266.4\)). Esto indica que el mejor modelo en comparación es el que tiene el término año al cuadrado agregado.
cat(paste0("Modelo de referencia: > AIC: ", AIC(model_ref), "\n"))
## Modelo de referencia: > AIC: -12043.342504192
cat(paste0("Modelo 9 > AIC: ", AIC(model9), "\n"))
## Modelo 9 > AIC: -12727.5814519068
cat(paste0("Modelo 10 > AIC: ", AIC(model10), "\n"))
## Modelo 10 > AIC: -12264.4305313688
En esta lectura, aplicamos varios tipos de transformaciones a las variables independientes y dependientes para mejorar la calidad de nuestro modelo lineal. En particular, encontramos que ajustar el logaritmo de los precios de la vivienda nos permitió obtener mejores resultados. Usando nuestra comprensión de las transformaciones, pudimos modelar efectivamente relaciones no lineales, como la relación cuadrática entre la latitud y el logaritmo del precio. Finalmente, integramos nuestra comprensión de los efectos de interacción de vistos en el EDA para modelar y cuantificar directamente las interacciones de la renovación y el waterfront en la relación entre los pies cuadrados y el precio.
Las transformaciones de variables son una técnica poderosa para mejorar la calidad de nuestros modelos lineales. En particular:
AIC Score
para ayudarnos a decidir si las variables
agregadas benefician nuestro modelo.“House Sales in King County, USA”, August 25, 2016, harlfoxem, CC0 Public Domain, https://www.kaggle.com/harlfoxem/housesalesprediction ```