Capítulo 9: Proyectos Prácticos
9.1 Proyecto 1: Predicción de Precios de Viviendas con Regresión
En este capítulo, exploraremos aplicaciones prácticas de técnicas de machine learning para resolver problemas del mundo real. Nuestro recorrido nos llevará a través de una serie de proyectos que demuestran el poder y la versatilidad de los algoritmos de machine learning en diversos dominios.
Cada proyecto en este capítulo está diseñado para proporcionarte experiencia práctica en la aplicación de conceptos de machine learning, desde la preprocesamiento de datos y la selección de modelos hasta la evaluación e interpretación de resultados. Al trabajar en estos proyectos, obtendrás conocimientos valiosos sobre todo el flujo de trabajo de machine learning y desarrollarás las habilidades necesarias para abordar desafíos complejos basados en datos.
Comenzamos con un problema clásico en el campo de los bienes raíces: la predicción de precios de viviendas. Este proyecto servirá como una introducción completa a las técnicas de regresión, la ingeniería de características y la evaluación de modelos. A medida que avancemos en el capítulo, nos encontraremos con proyectos cada vez más sofisticados que se basan en estas habilidades fundamentales, explorando temas como la clasificación, el clustering y las técnicas avanzadas de regresión.
Al final de este capítulo, tendrás un conjunto sólido de habilidades prácticas en machine learning, lo que te permitirá abordar una amplia gama de problemas en ciencia de datos con confianza. ¡Vamos a sumergirnos y comenzar a construir poderosos modelos predictivos!
La predicción de precios de viviendas es un desafío clásico de machine learning con profundas implicaciones para la industria inmobiliaria. Este problema complejo implica analizar una multitud de factores que influyen en el valor de las propiedades, que van desde la ubicación y el tamaño de la propiedad hasta los indicadores económicos locales y las tendencias del mercado. En el dinámico mundo de los bienes raíces, la capacidad de predecir con precisión los precios de las viviendas es una herramienta poderosa para diversas partes interesadas.
Los compradores pueden tomar decisiones de compra más informadas, identificando potencialmente propiedades infravaloradas o evitando aquellas sobrevaloradas. Los vendedores, armados con estimaciones precisas de valoración, pueden fijar estratégicamente el precio de sus propiedades para maximizar sus retornos mientras aseguran su competitividad en el mercado. Los inversores se benefician de estas predicciones al identificar oportunidades lucrativas y optimizar sus estrategias de gestión de cartera.
Este proyecto se adentra en la aplicación de técnicas avanzadas de machine learning, con un enfoque particular en metodologías de regresión, para desarrollar un modelo robusto que prediga los precios de las viviendas. Aprovechando un conjunto diverso de características y empleando algoritmos sofisticados, buscamos crear un marco predictivo capaz de navegar las complejidades del mercado inmobiliario y proporcionar valiosos conocimientos tanto a profesionales de la industria como a consumidores.
9.1.1 Declaración del Problema y Conjunto de Datos
Para este proyecto, utilizaremos el conjunto de datos de viviendas de Boston, una colección completa de información sobre diversas propiedades residenciales en el área metropolitana de Boston. Este conjunto de datos abarca una amplia gama de características que pueden influir en los precios de las viviendas, como las tasas de criminalidad en el vecindario, el número promedio de habitaciones por vivienda y la proximidad de la propiedad a los centros de empleo.
Nuestro objetivo principal es desarrollar un modelo predictivo sofisticado y preciso que pueda estimar los precios de las viviendas basándose en estos diversos atributos. Al analizar factores como las estadísticas locales de criminalidad, las características de las viviendas y las consideraciones geográficas como la accesibilidad a las autopistas, buscamos crear un algoritmo robusto capaz de proporcionar predicciones fiables de precios en el dinámico mercado inmobiliario de Boston.
Cargando y Explorando el Conjunto de Datos
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
# Load the California Housing dataset
california = fetch_california_housing(as_frame=True)
data = california.frame # Directly use the DataFrame
# Rename target column for clarity
data.rename(columns={'MedHouseVal': 'PRICE'}, inplace=True)
# Display the first few rows and summary statistics
print(data.head())
print(data.describe())
# Visualize correlations
plt.figure(figsize=(12, 10))
sns.heatmap(data.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Matrix of California Housing Data')
plt.show()
# Check for missing values
missing_values = data.isnull().sum().sum()
print(f"Total missing values: {missing_values}")
Aquí te explico lo que hace el código:
- Importa las bibliotecas necesarias para manipulación de datos (
pandas
,numpy
), visualización (seaborn
,matplotlib
), y aprendizaje automático (scikit-learn
). - Carga el conjunto de datos de viviendas de California utilizando la función
fetch_california_housing(as_frame=True)
de scikit-learn. - Crea un DataFrame de pandas a partir del conjunto de datos, utilizando
california.frame
y renombrando la variable objetivo aPRICE
para mayor claridad. - Muestra las primeras filas y estadísticas resumidas usando
print(data.head())
yprint(data.describe())
. - Visualiza la matriz de correlación entre características usando un mapa de calor con
seaborn.heatmap()
. - Verifica los valores faltantes en el conjunto de datos e imprime el conteo total.
Este código sirve como el paso inicial en el proceso de análisis de datos, proporcionando una comprensión fundamental de la estructura del conjunto de datos, las relaciones entre características y los posibles problemas de calidad de datos antes de proceder con el preprocesamiento avanzado y la construcción del modelo.
9.1.2 Preprocesamiento de Datos
Antes de poder construir nuestro modelo predictivo, es esencial realizar un preprocesamiento de datos exhaustivo. Este paso crucial abarca varias tareas importantes que preparan nuestro conjunto de datos para un análisis óptimo. Primero, debemos abordar cualquier valor faltante en nuestro conjunto de datos, empleando técnicas apropiadas como la imputación o eliminación, según la naturaleza y magnitud de los datos faltantes.
Luego, necesitamos identificar y manejar cuidadosamente los valores atípicos, que podrían sesgar nuestros resultados si no se corrigen. Esto puede involucrar métodos estadísticos para detectar anomalías y tomar decisiones informadas sobre si transformar, limitar o excluir los valores extremos. Finalmente, escalaremos nuestras características para asegurarnos de que estén en un rango numérico comparable, lo cual es especialmente importante para que muchos algoritmos de machine learning funcionen de manera efectiva.
Este proceso de escalado típicamente implica técnicas como la estandarización o normalización, que ajustan las características a una escala común sin distorsionar las diferencias en los rangos de valores ni perder información.
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Handle outliers (example for 'AveRooms' feature)
Q1 = data['AveRooms'].quantile(0.25)
Q3 = data['AveRooms'].quantile(0.75)
IQR = Q3 - Q1
# Filtering outliers using the IQR method
data = data[(data['AveRooms'] >= Q1 - 1.5 * IQR) & (data['AveRooms'] <= Q3 + 1.5 * IQR)]
# Split the dataset
X = data.drop('PRICE', axis=1)
y = data['PRICE']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Scale the features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Aquí te explico lo que hace el código:
- Manejo de valores atípicos:
- Se centra en la característica 'AveRooms' (promedio de habitaciones por vivienda), ya que 'RM' no existe en el conjunto de datos de Viviendas de California.
- Calcula el Rango Intercuartil (IQR) para esta característica.
- Elimina los puntos de datos que caen fuera de 1.5 veces el IQR por debajo de Q1 o por encima de Q3, que es un método común para eliminar valores atípicos.
- División del conjunto de datos:
- Separa las características (
X
) de la variable objetivo (y
, que es'PRICE'
). - Utiliza
train_test_split
para dividir los datos en conjuntos de entrenamiento y prueba, con un 20% de los datos reservados para pruebas.
- Separa las características (
- Escalado de características:
- Aplica
StandardScaler
para normalizar los valores de las características. - Ajusta el escalador con los datos de entrenamiento y transforma tanto los datos de entrenamiento como los de prueba para asegurar un escalado consistente.
- Aplica
9.1.3 Construcción y Evaluación del Modelo de Regresión Lineal
Comenzaremos nuestro análisis implementando un modelo de regresión lineal fundamental como nuestro enfoque base. Esta técnica, sencilla pero poderosa, nos permitirá establecer una base sólida para nuestro marco predictivo. Una vez construido el modelo, realizaremos una evaluación integral de su rendimiento utilizando una diversa gama de métricas.
Estas métricas proporcionarán información valiosa sobre la precisión del modelo, su capacidad predictiva y su efectividad general para estimar los precios de las viviendas en función de las características dadas. Al comenzar con este modelo simple, podemos obtener una comprensión clara de las relaciones subyacentes en nuestros datos y establecer un punto de referencia con el cual comparar modelos más complejos en etapas posteriores de nuestro análisis.
# Create and train the Linear Regression model
model = LinearRegression()
model.fit(X_train_scaled, y_train)
# Make predictions
y_pred = model.predict(X_test_scaled)
# Evaluate the model
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Root Mean Squared Error: {rmse}")
print(f"Mean Absolute Error: {mae}")
print(f"R-squared: {r2}")
# Perform cross-validation
cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5, scoring='neg_mean_squared_error')
print(f"Cross-validation scores: {-cv_scores}")
print(f"Average CV score: {-cv_scores.mean()}")
Aquí tienes un desglose de lo que hace el código:
- Crea y entrena un modelo de Regresión Lineal utilizando los datos de entrenamiento escalados.
- Realiza predicciones en los datos de prueba escalados.
- Evalúa el rendimiento del modelo utilizando varias métricas:
- Error Cuadrático Medio (MSE)
- Raíz del Error Cuadrático Medio (RMSE)
- Error Absoluto Medio (MAE)
- Puntuación R-cuadrado (R2)
- Realiza validación cruzada para evaluar el rendimiento del modelo en diferentes subconjuntos de los datos de entrenamiento.
El paso imprime estas métricas de evaluación, proporcionando información sobre qué tan bien está funcionando el modelo en la predicción de los precios de las viviendas. Los puntajes de la validación cruzada brindan una indicación de la consistencia del modelo en diferentes subconjuntos de los datos.
9.1.4 Interpretación de los Coeficientes del Modelo
Entender los coeficientes de nuestro modelo de regresión lineal es crucial, ya que proporciona información valiosa sobre la importancia relativa de diferentes características en la determinación de los precios de las viviendas. Al examinar estos coeficientes, podemos identificar qué atributos tienen el impacto más significativo en los valores de las propiedades en el mercado inmobiliario de Boston. Este análisis no solo nos ayuda a interpretar el proceso de toma de decisiones del modelo, sino que también ofrece ideas prácticas para profesionales inmobiliarios, inversionistas y responsables de políticas públicas.
La magnitud de cada coeficiente indica la fuerza de la influencia de su característica correspondiente en los precios de las viviendas, mientras que el signo (positivo o negativo) revela si la característica tiende a aumentar o disminuir los valores de las propiedades.
Por ejemplo, un coeficiente positivo grande para la característica "número de habitaciones" sugeriría que las casas con más habitaciones generalmente tienen precios más altos, manteniendo todo lo demás constante. Por el contrario, un coeficiente negativo para una característica como "tasa de criminalidad" indicaría que mayores tasas de criminalidad en un área están asociadas con precios más bajos de las viviendas.
# Store and sort coefficients by absolute value
coefficients = pd.DataFrame(model.coef_, index=X.columns, columns=['Coefficient'])
coefficients = coefficients.sort_values(by='Coefficient', key=lambda x: x.abs(), ascending=False)
# Print sorted coefficients
print(coefficients)
# Plot feature coefficients
plt.figure(figsize=(12, 8))
coefficients.plot(kind='bar', legend=False)
plt.title('Feature Coefficients in Linear Regression')
plt.xlabel('Features')
plt.ylabel('Coefficient Value')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()
Aquí te explico lo que hace:
- Crea un DataFrame llamado
coefficients
que almacena los coeficientes del modelo junto con sus nombres de características correspondientes. - Ordena los coeficientes por sus valores absolutos en orden descendente, facilitando la identificación de las características más influyentes que afectan los precios de las viviendas.
- Imprime los coeficientes ordenados, permitiéndonos analizar el impacto numérico de cada característica en los precios de las viviendas.
- Genera un gráfico de barras para visualizar los coeficientes:
- Asegura una clara visibilidad al establecer un tamaño de figura apropiado (12x8 pulgadas).
- Grafica los coeficientes como barras, distinguiendo las influencias positivas y negativas.
- Añade un título, etiqueta del eje x, y etiqueta del eje y para proporcionar contexto.
- Rota las etiquetas del eje x en 45 grados para mejorar la legibilidad, asegurando que los nombres de las características no se superpongan.
- Ajusta el diseño usando
plt.tight_layout()
para que todos los elementos encajen adecuadamente dentro de la figura.
9.1.5 Mejorando el Modelo con Regresión Ridge
Para mejorar el rendimiento de nuestro modelo y mitigar el riesgo de sobreajuste, implementaremos la Regresión Ridge, una técnica poderosa que introduce un término de regularización en la ecuación estándar de la regresión lineal.
Este enfoque, también conocido como regularización de Tikhonov, añade un término de penalización a la función de pérdida, reduciendo efectivamente los coeficientes de las características menos importantes hacia cero. Al hacerlo, la Regresión Ridge ayuda a reducir la sensibilidad del modelo a puntos de datos individuales y promueve una solución más estable y generalizable. Esto es especialmente útil cuando se trabaja con conjuntos de datos que tienen multicolinealidad entre las características o cuando el número de predictores es grande en relación con el número de observaciones.
El término de regularización en la Regresión Ridge está controlado por un hiperparámetro, alfa, que determina la fuerza de la penalización. Usaremos validación cruzada para encontrar el valor óptimo de este hiperparámetro, asegurando que nuestro modelo logre el equilibrio adecuado entre sesgo y varianza.
# Create a Ridge Regression model with hyperparameter tuning
from sklearn.model_selection import GridSearchCV
param_grid = {'alpha': [0.1, 1, 10, 100]}
ridge = Ridge()
grid_search = GridSearchCV(ridge, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train_scaled, y_train)
best_ridge = grid_search.best_estimator_
y_pred_ridge = best_ridge.predict(X_test_scaled)
mse_ridge = mean_squared_error(y_test, y_pred_ridge)
r2_ridge = r2_score(y_test, y_pred_ridge)
print(f"Best alpha: {grid_search.best_params_['alpha']}")
print(f"Ridge Regression Mean Squared Error: {mse_ridge}")
print(f"Ridge Regression R-squared: {r2_ridge}")
Aquí tienes un desglose de lo que hace:
- Importa
GridSearchCV
de scikit-learn, que se utiliza para la afinación de hiperparámetros. - Configura una cuadrícula de parámetros para el hiperparámetro 'alpha' de la Regresión Ridge, con valores [0.1, 1, 10, 100].
- Crea un modelo de Regresión Ridge y utiliza
GridSearchCV
para encontrar el mejor valor de 'alpha' mediante validación cruzada de 5 pliegues. - El mejor modelo se utiliza para hacer predicciones en el conjunto de prueba.
- Finalmente, calcula e imprime el Error Cuadrático Medio y el puntaje R-cuadrado para el modelo de Regresión Ridge.
Este enfoque ayuda a prevenir el sobreajuste al añadir un término de penalización a la función de pérdida, controlado por el parámetro 'alpha'. Este paso automatiza el proceso de encontrar el valor óptimo de 'alpha', equilibrando la complejidad y el rendimiento del modelo.
9.1.6 Supuestos y Diagnósticos del Modelo
Asegurar la validez de los supuestos de la regresión lineal es un paso crítico en nuestro proceso de modelado. Realizaremos un examen exhaustivo de tres supuestos clave:
- Linealidad
- Normalidad de los residuos
- Homocedasticidad (varianza constante de los residuos)
Estos supuestos forman la base de la regresión lineal y, cuando se cumplen, contribuyen a la fiabilidad e interpretabilidad de los resultados de nuestro modelo.
- Linealidad:
- Asume una relación lineal entre las variables predictoras y la variable de respuesta.
- Evaluaremos esto mediante gráficos de residuos vs. valores predichos, buscando una dispersión aleatoria (sin patrones).
- Normalidad de los Residuos:
- Asume que los errores siguen una distribución normal.
- Lo evaluaremos utilizando histogramas, gráficos Q-Q y pruebas estadísticas.
- Homocedasticidad:
- Asegura que la dispersión de los residuos permanece constante a través de los valores predichos.
- Esto es crucial porque la heterocedasticidad puede llevar a errores estándar e intervalos de confianza poco fiables.
Mediante la comprobación rigurosa de estos supuestos, podemos identificar posibles violaciones que podrían comprometer la validez de nuestro modelo. Si se detectan violaciones, podemos explorar medidas correctivas, como:
- Transformaciones logarítmicas o potenciales de las variables predictoras
- Modelos de regresión ponderada
- Técnicas alternativas de modelado (por ejemplo, modelos basados en árboles)
import matplotlib.pyplot as plt
import scipy.stats as stats
# Compute residuals
residuals = y_test - y_pred_ridge # Ensure correct y_pred usage
# Create subplots for assumption diagnostics
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# 1. Residuals vs. Predicted values (Linearity & Homoscedasticity)
axes[0].scatter(y_pred_ridge, residuals, alpha=0.5)
axes[0].axhline(y=0, color='r', linestyle='--', linewidth=1) # Reference line at y=0
axes[0].set_xlabel('Predicted Values')
axes[0].set_ylabel('Residuals')
axes[0].set_title('Residuals vs Predicted')
# 2. Histogram of residuals (Normality)
axes[1].hist(residuals, bins=30, edgecolor='black', alpha=0.7)
axes[1].set_xlabel('Residuals')
axes[1].set_ylabel('Frequency')
axes[1].set_title('Histogram of Residuals')
# 3. Q-Q plot (Normality Check)
stats.probplot(residuals, dist="norm", plot=axes[2])
axes[2].set_title('Q-Q Plot')
plt.tight_layout()
plt.show()
Aquí una explicacion de lo que hace:
- Calcula los residuos restando los valores predichos de los valores reales de prueba.
- Crea una figura con tres subgráficos para el diagnóstico de supuestos:
- Residuos vs. Valores Predichos (gráfico izquierdo)
- Verifica la linealidad y homocedasticidad.
- Si los puntos muestran un patrón claro, se viola la linealidad.
- Si los residuos muestran una dispersión creciente o decreciente, puede haber heterocedasticidad.
- Histograma de Residuos (gráfico central)
- Evalúa la normalidad de los residuos.
- Si el histograma es simétrico y en forma de campana, se cumple el supuesto de normalidad.
- Gráfico Q-Q (gráfico derecho)
- Compara los residuos con una distribución normal teórica.
- Si los puntos siguen de cerca la línea diagonal, el supuesto de normalidad es válido.
- Residuos vs. Valores Predichos (gráfico izquierdo)
9.1.7 Análisis de la Importancia de las Características
Para obtener una comprensión más completa de la importancia de las características en nuestro modelo de predicción de precios de viviendas, utilizaremos un Random Forest Regressor. Este potente método de aprendizaje de conjunto no solo ofrece una perspectiva alternativa sobre la importancia de las características, sino que también presenta varias ventajas sobre los modelos lineales tradicionales.
Los Random Forests son especialmente hábiles para capturar relaciones no lineales e interacciones entre las características, que pueden no ser evidentes en nuestros análisis previos. Al agregar las puntuaciones de importancia a lo largo de múltiples árboles de decisión, podemos obtener una clasificación robusta y confiable de la importancia de las características.
Este enfoque nos ayudará a identificar cuáles factores tienen el impacto más significativo en los precios de las viviendas, revelando potencialmente conocimientos que no eran evidentes en nuestro modelo de regresión lineal.
from sklearn.ensemble import RandomForestRegressor
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X_train_scaled, y_train)
feature_importance = pd.DataFrame({'feature': X.columns, 'importance': rf_model.feature_importances_})
feature_importance = feature_importance.sort_values('importance', ascending=False)
plt.figure(figsize=(10, 6))
sns.barplot(x='importance', y='feature', data=feature_importance)
plt.title('Feature Importance (Random Forest)')
plt.tight_layout()
plt.show()
Aquí tienes un desglose de lo que hace:
- Importa el
RandomForestRegressor
de scikit-learn. - Crea un modelo de Random Forest con 100 árboles y un estado aleatorio fijo para asegurar la reproducibilidad.
- Ajusta el modelo a los datos de entrenamiento escalados (
X_train_scaled
yy_train
). - Crea un DataFrame con dos columnas: 'feature' (nombres de las características) e 'importance' (puntuaciones de importancia del modelo de Random Forest).
- Ordena las características por importancia en orden descendente.
- Configura un gráfico usando matplotlib y seaborn:
- Crea una figura de 10x6 pulgadas.
- Usa el
barplot
de seaborn para visualizar la importancia de las características. - Establece el título como "Feature Importance (Random Forest)".
- Ajusta el diseño para una mejor visibilidad.
- Muestra el gráfico.
Esta visualización ayuda a identificar qué características tienen el mayor impacto en los precios de las viviendas según el modelo de Random Forest, revelando potencialmente ideas que no eran evidentes en el modelo de regresión lineal.
9.1.8 Posibles Mejoras y Trabajo Futuro
Aunque nuestro modelo actual proporciona valiosos conocimientos, existen varias formas en las que podríamos mejorar su rendimiento:
- Ingeniería de características: Crear nuevas características o transformar las existentes para capturar relaciones más complejas.
- Probar otros algoritmos: Experimentar con algoritmos más avanzados como el Gradient Boosting (por ejemplo, XGBoost) o la Regresión por Vectores de Soporte.
- Métodos de ensamble: Combinar predicciones de múltiples modelos para crear una predicción más robusta.
- Recoger más datos: Si es posible, recolectar datos más recientes y diversos para mejorar la generalización del modelo.
- Abordar la no linealidad: Si existen relaciones no lineales fuertes, considerar el uso de características polinomiales o modelos más flexibles.
9.1.9 Conclusión
Este proyecto demuestra la aplicación integral de técnicas de regresión para predecir los precios de las viviendas en el dinámico mercado inmobiliario. Hemos cubierto meticulosamente varios aspectos cruciales del flujo de trabajo de ciencia de datos, incluyendo el análisis exploratorio de datos, el preprocesamiento riguroso, la construcción de modelos sofisticados, la evaluación exhaustiva y la interpretación detallada de los resultados. A través de nuestro análisis cuidadoso de varias características y su impacto en los precios de las viviendas, hemos desarrollado un modelo que ofrece valiosos conocimientos basados en datos para una amplia gama de interesados en la industria inmobiliaria.
Los profesionales inmobiliarios pueden aprovechar este modelo para tomar decisiones más informadas sobre la valoración de propiedades y las tendencias del mercado. Los propietarios de viviendas podrían encontrar útil comprender los factores que influyen en el valor de su propiedad con el tiempo. Los inversionistas pueden utilizar estos conocimientos para identificar propiedades potencialmente infravaloradas o oportunidades emergentes en el mercado. Sin embargo, es crucial recordar que, aunque nuestro modelo proporciona una base sólida para entender la dinámica de los precios de las viviendas, el mercado inmobiliario en el mundo real es inherentemente complejo y está influido por una multitud de factores, muchos de los cuales pueden no estar reflejados en nuestro conjunto de datos actual.
Factores como las condiciones económicas locales, cambios en las leyes de zonificación, variaciones en los patrones demográficos e incluso las tendencias económicas globales pueden desempeñar roles significativos en la configuración de los mercados de viviendas. Estos elementos a menudo interactúan de manera intrincada y pueden ser difíciles de modelar con precisión. Por lo tanto, aunque nuestro modelo predictivo ofrece valiosos conocimientos, debe considerarse como una herramienta entre muchas en el contexto más amplio del análisis inmobiliario y la toma de decisiones.
9.1 Proyecto 1: Predicción de Precios de Viviendas con Regresión
En este capítulo, exploraremos aplicaciones prácticas de técnicas de machine learning para resolver problemas del mundo real. Nuestro recorrido nos llevará a través de una serie de proyectos que demuestran el poder y la versatilidad de los algoritmos de machine learning en diversos dominios.
Cada proyecto en este capítulo está diseñado para proporcionarte experiencia práctica en la aplicación de conceptos de machine learning, desde la preprocesamiento de datos y la selección de modelos hasta la evaluación e interpretación de resultados. Al trabajar en estos proyectos, obtendrás conocimientos valiosos sobre todo el flujo de trabajo de machine learning y desarrollarás las habilidades necesarias para abordar desafíos complejos basados en datos.
Comenzamos con un problema clásico en el campo de los bienes raíces: la predicción de precios de viviendas. Este proyecto servirá como una introducción completa a las técnicas de regresión, la ingeniería de características y la evaluación de modelos. A medida que avancemos en el capítulo, nos encontraremos con proyectos cada vez más sofisticados que se basan en estas habilidades fundamentales, explorando temas como la clasificación, el clustering y las técnicas avanzadas de regresión.
Al final de este capítulo, tendrás un conjunto sólido de habilidades prácticas en machine learning, lo que te permitirá abordar una amplia gama de problemas en ciencia de datos con confianza. ¡Vamos a sumergirnos y comenzar a construir poderosos modelos predictivos!
La predicción de precios de viviendas es un desafío clásico de machine learning con profundas implicaciones para la industria inmobiliaria. Este problema complejo implica analizar una multitud de factores que influyen en el valor de las propiedades, que van desde la ubicación y el tamaño de la propiedad hasta los indicadores económicos locales y las tendencias del mercado. En el dinámico mundo de los bienes raíces, la capacidad de predecir con precisión los precios de las viviendas es una herramienta poderosa para diversas partes interesadas.
Los compradores pueden tomar decisiones de compra más informadas, identificando potencialmente propiedades infravaloradas o evitando aquellas sobrevaloradas. Los vendedores, armados con estimaciones precisas de valoración, pueden fijar estratégicamente el precio de sus propiedades para maximizar sus retornos mientras aseguran su competitividad en el mercado. Los inversores se benefician de estas predicciones al identificar oportunidades lucrativas y optimizar sus estrategias de gestión de cartera.
Este proyecto se adentra en la aplicación de técnicas avanzadas de machine learning, con un enfoque particular en metodologías de regresión, para desarrollar un modelo robusto que prediga los precios de las viviendas. Aprovechando un conjunto diverso de características y empleando algoritmos sofisticados, buscamos crear un marco predictivo capaz de navegar las complejidades del mercado inmobiliario y proporcionar valiosos conocimientos tanto a profesionales de la industria como a consumidores.
9.1.1 Declaración del Problema y Conjunto de Datos
Para este proyecto, utilizaremos el conjunto de datos de viviendas de Boston, una colección completa de información sobre diversas propiedades residenciales en el área metropolitana de Boston. Este conjunto de datos abarca una amplia gama de características que pueden influir en los precios de las viviendas, como las tasas de criminalidad en el vecindario, el número promedio de habitaciones por vivienda y la proximidad de la propiedad a los centros de empleo.
Nuestro objetivo principal es desarrollar un modelo predictivo sofisticado y preciso que pueda estimar los precios de las viviendas basándose en estos diversos atributos. Al analizar factores como las estadísticas locales de criminalidad, las características de las viviendas y las consideraciones geográficas como la accesibilidad a las autopistas, buscamos crear un algoritmo robusto capaz de proporcionar predicciones fiables de precios en el dinámico mercado inmobiliario de Boston.
Cargando y Explorando el Conjunto de Datos
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
# Load the California Housing dataset
california = fetch_california_housing(as_frame=True)
data = california.frame # Directly use the DataFrame
# Rename target column for clarity
data.rename(columns={'MedHouseVal': 'PRICE'}, inplace=True)
# Display the first few rows and summary statistics
print(data.head())
print(data.describe())
# Visualize correlations
plt.figure(figsize=(12, 10))
sns.heatmap(data.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Matrix of California Housing Data')
plt.show()
# Check for missing values
missing_values = data.isnull().sum().sum()
print(f"Total missing values: {missing_values}")
Aquí te explico lo que hace el código:
- Importa las bibliotecas necesarias para manipulación de datos (
pandas
,numpy
), visualización (seaborn
,matplotlib
), y aprendizaje automático (scikit-learn
). - Carga el conjunto de datos de viviendas de California utilizando la función
fetch_california_housing(as_frame=True)
de scikit-learn. - Crea un DataFrame de pandas a partir del conjunto de datos, utilizando
california.frame
y renombrando la variable objetivo aPRICE
para mayor claridad. - Muestra las primeras filas y estadísticas resumidas usando
print(data.head())
yprint(data.describe())
. - Visualiza la matriz de correlación entre características usando un mapa de calor con
seaborn.heatmap()
. - Verifica los valores faltantes en el conjunto de datos e imprime el conteo total.
Este código sirve como el paso inicial en el proceso de análisis de datos, proporcionando una comprensión fundamental de la estructura del conjunto de datos, las relaciones entre características y los posibles problemas de calidad de datos antes de proceder con el preprocesamiento avanzado y la construcción del modelo.
9.1.2 Preprocesamiento de Datos
Antes de poder construir nuestro modelo predictivo, es esencial realizar un preprocesamiento de datos exhaustivo. Este paso crucial abarca varias tareas importantes que preparan nuestro conjunto de datos para un análisis óptimo. Primero, debemos abordar cualquier valor faltante en nuestro conjunto de datos, empleando técnicas apropiadas como la imputación o eliminación, según la naturaleza y magnitud de los datos faltantes.
Luego, necesitamos identificar y manejar cuidadosamente los valores atípicos, que podrían sesgar nuestros resultados si no se corrigen. Esto puede involucrar métodos estadísticos para detectar anomalías y tomar decisiones informadas sobre si transformar, limitar o excluir los valores extremos. Finalmente, escalaremos nuestras características para asegurarnos de que estén en un rango numérico comparable, lo cual es especialmente importante para que muchos algoritmos de machine learning funcionen de manera efectiva.
Este proceso de escalado típicamente implica técnicas como la estandarización o normalización, que ajustan las características a una escala común sin distorsionar las diferencias en los rangos de valores ni perder información.
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Handle outliers (example for 'AveRooms' feature)
Q1 = data['AveRooms'].quantile(0.25)
Q3 = data['AveRooms'].quantile(0.75)
IQR = Q3 - Q1
# Filtering outliers using the IQR method
data = data[(data['AveRooms'] >= Q1 - 1.5 * IQR) & (data['AveRooms'] <= Q3 + 1.5 * IQR)]
# Split the dataset
X = data.drop('PRICE', axis=1)
y = data['PRICE']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Scale the features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Aquí te explico lo que hace el código:
- Manejo de valores atípicos:
- Se centra en la característica 'AveRooms' (promedio de habitaciones por vivienda), ya que 'RM' no existe en el conjunto de datos de Viviendas de California.
- Calcula el Rango Intercuartil (IQR) para esta característica.
- Elimina los puntos de datos que caen fuera de 1.5 veces el IQR por debajo de Q1 o por encima de Q3, que es un método común para eliminar valores atípicos.
- División del conjunto de datos:
- Separa las características (
X
) de la variable objetivo (y
, que es'PRICE'
). - Utiliza
train_test_split
para dividir los datos en conjuntos de entrenamiento y prueba, con un 20% de los datos reservados para pruebas.
- Separa las características (
- Escalado de características:
- Aplica
StandardScaler
para normalizar los valores de las características. - Ajusta el escalador con los datos de entrenamiento y transforma tanto los datos de entrenamiento como los de prueba para asegurar un escalado consistente.
- Aplica
9.1.3 Construcción y Evaluación del Modelo de Regresión Lineal
Comenzaremos nuestro análisis implementando un modelo de regresión lineal fundamental como nuestro enfoque base. Esta técnica, sencilla pero poderosa, nos permitirá establecer una base sólida para nuestro marco predictivo. Una vez construido el modelo, realizaremos una evaluación integral de su rendimiento utilizando una diversa gama de métricas.
Estas métricas proporcionarán información valiosa sobre la precisión del modelo, su capacidad predictiva y su efectividad general para estimar los precios de las viviendas en función de las características dadas. Al comenzar con este modelo simple, podemos obtener una comprensión clara de las relaciones subyacentes en nuestros datos y establecer un punto de referencia con el cual comparar modelos más complejos en etapas posteriores de nuestro análisis.
# Create and train the Linear Regression model
model = LinearRegression()
model.fit(X_train_scaled, y_train)
# Make predictions
y_pred = model.predict(X_test_scaled)
# Evaluate the model
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Root Mean Squared Error: {rmse}")
print(f"Mean Absolute Error: {mae}")
print(f"R-squared: {r2}")
# Perform cross-validation
cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5, scoring='neg_mean_squared_error')
print(f"Cross-validation scores: {-cv_scores}")
print(f"Average CV score: {-cv_scores.mean()}")
Aquí tienes un desglose de lo que hace el código:
- Crea y entrena un modelo de Regresión Lineal utilizando los datos de entrenamiento escalados.
- Realiza predicciones en los datos de prueba escalados.
- Evalúa el rendimiento del modelo utilizando varias métricas:
- Error Cuadrático Medio (MSE)
- Raíz del Error Cuadrático Medio (RMSE)
- Error Absoluto Medio (MAE)
- Puntuación R-cuadrado (R2)
- Realiza validación cruzada para evaluar el rendimiento del modelo en diferentes subconjuntos de los datos de entrenamiento.
El paso imprime estas métricas de evaluación, proporcionando información sobre qué tan bien está funcionando el modelo en la predicción de los precios de las viviendas. Los puntajes de la validación cruzada brindan una indicación de la consistencia del modelo en diferentes subconjuntos de los datos.
9.1.4 Interpretación de los Coeficientes del Modelo
Entender los coeficientes de nuestro modelo de regresión lineal es crucial, ya que proporciona información valiosa sobre la importancia relativa de diferentes características en la determinación de los precios de las viviendas. Al examinar estos coeficientes, podemos identificar qué atributos tienen el impacto más significativo en los valores de las propiedades en el mercado inmobiliario de Boston. Este análisis no solo nos ayuda a interpretar el proceso de toma de decisiones del modelo, sino que también ofrece ideas prácticas para profesionales inmobiliarios, inversionistas y responsables de políticas públicas.
La magnitud de cada coeficiente indica la fuerza de la influencia de su característica correspondiente en los precios de las viviendas, mientras que el signo (positivo o negativo) revela si la característica tiende a aumentar o disminuir los valores de las propiedades.
Por ejemplo, un coeficiente positivo grande para la característica "número de habitaciones" sugeriría que las casas con más habitaciones generalmente tienen precios más altos, manteniendo todo lo demás constante. Por el contrario, un coeficiente negativo para una característica como "tasa de criminalidad" indicaría que mayores tasas de criminalidad en un área están asociadas con precios más bajos de las viviendas.
# Store and sort coefficients by absolute value
coefficients = pd.DataFrame(model.coef_, index=X.columns, columns=['Coefficient'])
coefficients = coefficients.sort_values(by='Coefficient', key=lambda x: x.abs(), ascending=False)
# Print sorted coefficients
print(coefficients)
# Plot feature coefficients
plt.figure(figsize=(12, 8))
coefficients.plot(kind='bar', legend=False)
plt.title('Feature Coefficients in Linear Regression')
plt.xlabel('Features')
plt.ylabel('Coefficient Value')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()
Aquí te explico lo que hace:
- Crea un DataFrame llamado
coefficients
que almacena los coeficientes del modelo junto con sus nombres de características correspondientes. - Ordena los coeficientes por sus valores absolutos en orden descendente, facilitando la identificación de las características más influyentes que afectan los precios de las viviendas.
- Imprime los coeficientes ordenados, permitiéndonos analizar el impacto numérico de cada característica en los precios de las viviendas.
- Genera un gráfico de barras para visualizar los coeficientes:
- Asegura una clara visibilidad al establecer un tamaño de figura apropiado (12x8 pulgadas).
- Grafica los coeficientes como barras, distinguiendo las influencias positivas y negativas.
- Añade un título, etiqueta del eje x, y etiqueta del eje y para proporcionar contexto.
- Rota las etiquetas del eje x en 45 grados para mejorar la legibilidad, asegurando que los nombres de las características no se superpongan.
- Ajusta el diseño usando
plt.tight_layout()
para que todos los elementos encajen adecuadamente dentro de la figura.
9.1.5 Mejorando el Modelo con Regresión Ridge
Para mejorar el rendimiento de nuestro modelo y mitigar el riesgo de sobreajuste, implementaremos la Regresión Ridge, una técnica poderosa que introduce un término de regularización en la ecuación estándar de la regresión lineal.
Este enfoque, también conocido como regularización de Tikhonov, añade un término de penalización a la función de pérdida, reduciendo efectivamente los coeficientes de las características menos importantes hacia cero. Al hacerlo, la Regresión Ridge ayuda a reducir la sensibilidad del modelo a puntos de datos individuales y promueve una solución más estable y generalizable. Esto es especialmente útil cuando se trabaja con conjuntos de datos que tienen multicolinealidad entre las características o cuando el número de predictores es grande en relación con el número de observaciones.
El término de regularización en la Regresión Ridge está controlado por un hiperparámetro, alfa, que determina la fuerza de la penalización. Usaremos validación cruzada para encontrar el valor óptimo de este hiperparámetro, asegurando que nuestro modelo logre el equilibrio adecuado entre sesgo y varianza.
# Create a Ridge Regression model with hyperparameter tuning
from sklearn.model_selection import GridSearchCV
param_grid = {'alpha': [0.1, 1, 10, 100]}
ridge = Ridge()
grid_search = GridSearchCV(ridge, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train_scaled, y_train)
best_ridge = grid_search.best_estimator_
y_pred_ridge = best_ridge.predict(X_test_scaled)
mse_ridge = mean_squared_error(y_test, y_pred_ridge)
r2_ridge = r2_score(y_test, y_pred_ridge)
print(f"Best alpha: {grid_search.best_params_['alpha']}")
print(f"Ridge Regression Mean Squared Error: {mse_ridge}")
print(f"Ridge Regression R-squared: {r2_ridge}")
Aquí tienes un desglose de lo que hace:
- Importa
GridSearchCV
de scikit-learn, que se utiliza para la afinación de hiperparámetros. - Configura una cuadrícula de parámetros para el hiperparámetro 'alpha' de la Regresión Ridge, con valores [0.1, 1, 10, 100].
- Crea un modelo de Regresión Ridge y utiliza
GridSearchCV
para encontrar el mejor valor de 'alpha' mediante validación cruzada de 5 pliegues. - El mejor modelo se utiliza para hacer predicciones en el conjunto de prueba.
- Finalmente, calcula e imprime el Error Cuadrático Medio y el puntaje R-cuadrado para el modelo de Regresión Ridge.
Este enfoque ayuda a prevenir el sobreajuste al añadir un término de penalización a la función de pérdida, controlado por el parámetro 'alpha'. Este paso automatiza el proceso de encontrar el valor óptimo de 'alpha', equilibrando la complejidad y el rendimiento del modelo.
9.1.6 Supuestos y Diagnósticos del Modelo
Asegurar la validez de los supuestos de la regresión lineal es un paso crítico en nuestro proceso de modelado. Realizaremos un examen exhaustivo de tres supuestos clave:
- Linealidad
- Normalidad de los residuos
- Homocedasticidad (varianza constante de los residuos)
Estos supuestos forman la base de la regresión lineal y, cuando se cumplen, contribuyen a la fiabilidad e interpretabilidad de los resultados de nuestro modelo.
- Linealidad:
- Asume una relación lineal entre las variables predictoras y la variable de respuesta.
- Evaluaremos esto mediante gráficos de residuos vs. valores predichos, buscando una dispersión aleatoria (sin patrones).
- Normalidad de los Residuos:
- Asume que los errores siguen una distribución normal.
- Lo evaluaremos utilizando histogramas, gráficos Q-Q y pruebas estadísticas.
- Homocedasticidad:
- Asegura que la dispersión de los residuos permanece constante a través de los valores predichos.
- Esto es crucial porque la heterocedasticidad puede llevar a errores estándar e intervalos de confianza poco fiables.
Mediante la comprobación rigurosa de estos supuestos, podemos identificar posibles violaciones que podrían comprometer la validez de nuestro modelo. Si se detectan violaciones, podemos explorar medidas correctivas, como:
- Transformaciones logarítmicas o potenciales de las variables predictoras
- Modelos de regresión ponderada
- Técnicas alternativas de modelado (por ejemplo, modelos basados en árboles)
import matplotlib.pyplot as plt
import scipy.stats as stats
# Compute residuals
residuals = y_test - y_pred_ridge # Ensure correct y_pred usage
# Create subplots for assumption diagnostics
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# 1. Residuals vs. Predicted values (Linearity & Homoscedasticity)
axes[0].scatter(y_pred_ridge, residuals, alpha=0.5)
axes[0].axhline(y=0, color='r', linestyle='--', linewidth=1) # Reference line at y=0
axes[0].set_xlabel('Predicted Values')
axes[0].set_ylabel('Residuals')
axes[0].set_title('Residuals vs Predicted')
# 2. Histogram of residuals (Normality)
axes[1].hist(residuals, bins=30, edgecolor='black', alpha=0.7)
axes[1].set_xlabel('Residuals')
axes[1].set_ylabel('Frequency')
axes[1].set_title('Histogram of Residuals')
# 3. Q-Q plot (Normality Check)
stats.probplot(residuals, dist="norm", plot=axes[2])
axes[2].set_title('Q-Q Plot')
plt.tight_layout()
plt.show()
Aquí una explicacion de lo que hace:
- Calcula los residuos restando los valores predichos de los valores reales de prueba.
- Crea una figura con tres subgráficos para el diagnóstico de supuestos:
- Residuos vs. Valores Predichos (gráfico izquierdo)
- Verifica la linealidad y homocedasticidad.
- Si los puntos muestran un patrón claro, se viola la linealidad.
- Si los residuos muestran una dispersión creciente o decreciente, puede haber heterocedasticidad.
- Histograma de Residuos (gráfico central)
- Evalúa la normalidad de los residuos.
- Si el histograma es simétrico y en forma de campana, se cumple el supuesto de normalidad.
- Gráfico Q-Q (gráfico derecho)
- Compara los residuos con una distribución normal teórica.
- Si los puntos siguen de cerca la línea diagonal, el supuesto de normalidad es válido.
- Residuos vs. Valores Predichos (gráfico izquierdo)
9.1.7 Análisis de la Importancia de las Características
Para obtener una comprensión más completa de la importancia de las características en nuestro modelo de predicción de precios de viviendas, utilizaremos un Random Forest Regressor. Este potente método de aprendizaje de conjunto no solo ofrece una perspectiva alternativa sobre la importancia de las características, sino que también presenta varias ventajas sobre los modelos lineales tradicionales.
Los Random Forests son especialmente hábiles para capturar relaciones no lineales e interacciones entre las características, que pueden no ser evidentes en nuestros análisis previos. Al agregar las puntuaciones de importancia a lo largo de múltiples árboles de decisión, podemos obtener una clasificación robusta y confiable de la importancia de las características.
Este enfoque nos ayudará a identificar cuáles factores tienen el impacto más significativo en los precios de las viviendas, revelando potencialmente conocimientos que no eran evidentes en nuestro modelo de regresión lineal.
from sklearn.ensemble import RandomForestRegressor
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X_train_scaled, y_train)
feature_importance = pd.DataFrame({'feature': X.columns, 'importance': rf_model.feature_importances_})
feature_importance = feature_importance.sort_values('importance', ascending=False)
plt.figure(figsize=(10, 6))
sns.barplot(x='importance', y='feature', data=feature_importance)
plt.title('Feature Importance (Random Forest)')
plt.tight_layout()
plt.show()
Aquí tienes un desglose de lo que hace:
- Importa el
RandomForestRegressor
de scikit-learn. - Crea un modelo de Random Forest con 100 árboles y un estado aleatorio fijo para asegurar la reproducibilidad.
- Ajusta el modelo a los datos de entrenamiento escalados (
X_train_scaled
yy_train
). - Crea un DataFrame con dos columnas: 'feature' (nombres de las características) e 'importance' (puntuaciones de importancia del modelo de Random Forest).
- Ordena las características por importancia en orden descendente.
- Configura un gráfico usando matplotlib y seaborn:
- Crea una figura de 10x6 pulgadas.
- Usa el
barplot
de seaborn para visualizar la importancia de las características. - Establece el título como "Feature Importance (Random Forest)".
- Ajusta el diseño para una mejor visibilidad.
- Muestra el gráfico.
Esta visualización ayuda a identificar qué características tienen el mayor impacto en los precios de las viviendas según el modelo de Random Forest, revelando potencialmente ideas que no eran evidentes en el modelo de regresión lineal.
9.1.8 Posibles Mejoras y Trabajo Futuro
Aunque nuestro modelo actual proporciona valiosos conocimientos, existen varias formas en las que podríamos mejorar su rendimiento:
- Ingeniería de características: Crear nuevas características o transformar las existentes para capturar relaciones más complejas.
- Probar otros algoritmos: Experimentar con algoritmos más avanzados como el Gradient Boosting (por ejemplo, XGBoost) o la Regresión por Vectores de Soporte.
- Métodos de ensamble: Combinar predicciones de múltiples modelos para crear una predicción más robusta.
- Recoger más datos: Si es posible, recolectar datos más recientes y diversos para mejorar la generalización del modelo.
- Abordar la no linealidad: Si existen relaciones no lineales fuertes, considerar el uso de características polinomiales o modelos más flexibles.
9.1.9 Conclusión
Este proyecto demuestra la aplicación integral de técnicas de regresión para predecir los precios de las viviendas en el dinámico mercado inmobiliario. Hemos cubierto meticulosamente varios aspectos cruciales del flujo de trabajo de ciencia de datos, incluyendo el análisis exploratorio de datos, el preprocesamiento riguroso, la construcción de modelos sofisticados, la evaluación exhaustiva y la interpretación detallada de los resultados. A través de nuestro análisis cuidadoso de varias características y su impacto en los precios de las viviendas, hemos desarrollado un modelo que ofrece valiosos conocimientos basados en datos para una amplia gama de interesados en la industria inmobiliaria.
Los profesionales inmobiliarios pueden aprovechar este modelo para tomar decisiones más informadas sobre la valoración de propiedades y las tendencias del mercado. Los propietarios de viviendas podrían encontrar útil comprender los factores que influyen en el valor de su propiedad con el tiempo. Los inversionistas pueden utilizar estos conocimientos para identificar propiedades potencialmente infravaloradas o oportunidades emergentes en el mercado. Sin embargo, es crucial recordar que, aunque nuestro modelo proporciona una base sólida para entender la dinámica de los precios de las viviendas, el mercado inmobiliario en el mundo real es inherentemente complejo y está influido por una multitud de factores, muchos de los cuales pueden no estar reflejados en nuestro conjunto de datos actual.
Factores como las condiciones económicas locales, cambios en las leyes de zonificación, variaciones en los patrones demográficos e incluso las tendencias económicas globales pueden desempeñar roles significativos en la configuración de los mercados de viviendas. Estos elementos a menudo interactúan de manera intrincada y pueden ser difíciles de modelar con precisión. Por lo tanto, aunque nuestro modelo predictivo ofrece valiosos conocimientos, debe considerarse como una herramienta entre muchas en el contexto más amplio del análisis inmobiliario y la toma de decisiones.
9.1 Proyecto 1: Predicción de Precios de Viviendas con Regresión
En este capítulo, exploraremos aplicaciones prácticas de técnicas de machine learning para resolver problemas del mundo real. Nuestro recorrido nos llevará a través de una serie de proyectos que demuestran el poder y la versatilidad de los algoritmos de machine learning en diversos dominios.
Cada proyecto en este capítulo está diseñado para proporcionarte experiencia práctica en la aplicación de conceptos de machine learning, desde la preprocesamiento de datos y la selección de modelos hasta la evaluación e interpretación de resultados. Al trabajar en estos proyectos, obtendrás conocimientos valiosos sobre todo el flujo de trabajo de machine learning y desarrollarás las habilidades necesarias para abordar desafíos complejos basados en datos.
Comenzamos con un problema clásico en el campo de los bienes raíces: la predicción de precios de viviendas. Este proyecto servirá como una introducción completa a las técnicas de regresión, la ingeniería de características y la evaluación de modelos. A medida que avancemos en el capítulo, nos encontraremos con proyectos cada vez más sofisticados que se basan en estas habilidades fundamentales, explorando temas como la clasificación, el clustering y las técnicas avanzadas de regresión.
Al final de este capítulo, tendrás un conjunto sólido de habilidades prácticas en machine learning, lo que te permitirá abordar una amplia gama de problemas en ciencia de datos con confianza. ¡Vamos a sumergirnos y comenzar a construir poderosos modelos predictivos!
La predicción de precios de viviendas es un desafío clásico de machine learning con profundas implicaciones para la industria inmobiliaria. Este problema complejo implica analizar una multitud de factores que influyen en el valor de las propiedades, que van desde la ubicación y el tamaño de la propiedad hasta los indicadores económicos locales y las tendencias del mercado. En el dinámico mundo de los bienes raíces, la capacidad de predecir con precisión los precios de las viviendas es una herramienta poderosa para diversas partes interesadas.
Los compradores pueden tomar decisiones de compra más informadas, identificando potencialmente propiedades infravaloradas o evitando aquellas sobrevaloradas. Los vendedores, armados con estimaciones precisas de valoración, pueden fijar estratégicamente el precio de sus propiedades para maximizar sus retornos mientras aseguran su competitividad en el mercado. Los inversores se benefician de estas predicciones al identificar oportunidades lucrativas y optimizar sus estrategias de gestión de cartera.
Este proyecto se adentra en la aplicación de técnicas avanzadas de machine learning, con un enfoque particular en metodologías de regresión, para desarrollar un modelo robusto que prediga los precios de las viviendas. Aprovechando un conjunto diverso de características y empleando algoritmos sofisticados, buscamos crear un marco predictivo capaz de navegar las complejidades del mercado inmobiliario y proporcionar valiosos conocimientos tanto a profesionales de la industria como a consumidores.
9.1.1 Declaración del Problema y Conjunto de Datos
Para este proyecto, utilizaremos el conjunto de datos de viviendas de Boston, una colección completa de información sobre diversas propiedades residenciales en el área metropolitana de Boston. Este conjunto de datos abarca una amplia gama de características que pueden influir en los precios de las viviendas, como las tasas de criminalidad en el vecindario, el número promedio de habitaciones por vivienda y la proximidad de la propiedad a los centros de empleo.
Nuestro objetivo principal es desarrollar un modelo predictivo sofisticado y preciso que pueda estimar los precios de las viviendas basándose en estos diversos atributos. Al analizar factores como las estadísticas locales de criminalidad, las características de las viviendas y las consideraciones geográficas como la accesibilidad a las autopistas, buscamos crear un algoritmo robusto capaz de proporcionar predicciones fiables de precios en el dinámico mercado inmobiliario de Boston.
Cargando y Explorando el Conjunto de Datos
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
# Load the California Housing dataset
california = fetch_california_housing(as_frame=True)
data = california.frame # Directly use the DataFrame
# Rename target column for clarity
data.rename(columns={'MedHouseVal': 'PRICE'}, inplace=True)
# Display the first few rows and summary statistics
print(data.head())
print(data.describe())
# Visualize correlations
plt.figure(figsize=(12, 10))
sns.heatmap(data.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Matrix of California Housing Data')
plt.show()
# Check for missing values
missing_values = data.isnull().sum().sum()
print(f"Total missing values: {missing_values}")
Aquí te explico lo que hace el código:
- Importa las bibliotecas necesarias para manipulación de datos (
pandas
,numpy
), visualización (seaborn
,matplotlib
), y aprendizaje automático (scikit-learn
). - Carga el conjunto de datos de viviendas de California utilizando la función
fetch_california_housing(as_frame=True)
de scikit-learn. - Crea un DataFrame de pandas a partir del conjunto de datos, utilizando
california.frame
y renombrando la variable objetivo aPRICE
para mayor claridad. - Muestra las primeras filas y estadísticas resumidas usando
print(data.head())
yprint(data.describe())
. - Visualiza la matriz de correlación entre características usando un mapa de calor con
seaborn.heatmap()
. - Verifica los valores faltantes en el conjunto de datos e imprime el conteo total.
Este código sirve como el paso inicial en el proceso de análisis de datos, proporcionando una comprensión fundamental de la estructura del conjunto de datos, las relaciones entre características y los posibles problemas de calidad de datos antes de proceder con el preprocesamiento avanzado y la construcción del modelo.
9.1.2 Preprocesamiento de Datos
Antes de poder construir nuestro modelo predictivo, es esencial realizar un preprocesamiento de datos exhaustivo. Este paso crucial abarca varias tareas importantes que preparan nuestro conjunto de datos para un análisis óptimo. Primero, debemos abordar cualquier valor faltante en nuestro conjunto de datos, empleando técnicas apropiadas como la imputación o eliminación, según la naturaleza y magnitud de los datos faltantes.
Luego, necesitamos identificar y manejar cuidadosamente los valores atípicos, que podrían sesgar nuestros resultados si no se corrigen. Esto puede involucrar métodos estadísticos para detectar anomalías y tomar decisiones informadas sobre si transformar, limitar o excluir los valores extremos. Finalmente, escalaremos nuestras características para asegurarnos de que estén en un rango numérico comparable, lo cual es especialmente importante para que muchos algoritmos de machine learning funcionen de manera efectiva.
Este proceso de escalado típicamente implica técnicas como la estandarización o normalización, que ajustan las características a una escala común sin distorsionar las diferencias en los rangos de valores ni perder información.
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Handle outliers (example for 'AveRooms' feature)
Q1 = data['AveRooms'].quantile(0.25)
Q3 = data['AveRooms'].quantile(0.75)
IQR = Q3 - Q1
# Filtering outliers using the IQR method
data = data[(data['AveRooms'] >= Q1 - 1.5 * IQR) & (data['AveRooms'] <= Q3 + 1.5 * IQR)]
# Split the dataset
X = data.drop('PRICE', axis=1)
y = data['PRICE']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Scale the features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Aquí te explico lo que hace el código:
- Manejo de valores atípicos:
- Se centra en la característica 'AveRooms' (promedio de habitaciones por vivienda), ya que 'RM' no existe en el conjunto de datos de Viviendas de California.
- Calcula el Rango Intercuartil (IQR) para esta característica.
- Elimina los puntos de datos que caen fuera de 1.5 veces el IQR por debajo de Q1 o por encima de Q3, que es un método común para eliminar valores atípicos.
- División del conjunto de datos:
- Separa las características (
X
) de la variable objetivo (y
, que es'PRICE'
). - Utiliza
train_test_split
para dividir los datos en conjuntos de entrenamiento y prueba, con un 20% de los datos reservados para pruebas.
- Separa las características (
- Escalado de características:
- Aplica
StandardScaler
para normalizar los valores de las características. - Ajusta el escalador con los datos de entrenamiento y transforma tanto los datos de entrenamiento como los de prueba para asegurar un escalado consistente.
- Aplica
9.1.3 Construcción y Evaluación del Modelo de Regresión Lineal
Comenzaremos nuestro análisis implementando un modelo de regresión lineal fundamental como nuestro enfoque base. Esta técnica, sencilla pero poderosa, nos permitirá establecer una base sólida para nuestro marco predictivo. Una vez construido el modelo, realizaremos una evaluación integral de su rendimiento utilizando una diversa gama de métricas.
Estas métricas proporcionarán información valiosa sobre la precisión del modelo, su capacidad predictiva y su efectividad general para estimar los precios de las viviendas en función de las características dadas. Al comenzar con este modelo simple, podemos obtener una comprensión clara de las relaciones subyacentes en nuestros datos y establecer un punto de referencia con el cual comparar modelos más complejos en etapas posteriores de nuestro análisis.
# Create and train the Linear Regression model
model = LinearRegression()
model.fit(X_train_scaled, y_train)
# Make predictions
y_pred = model.predict(X_test_scaled)
# Evaluate the model
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Root Mean Squared Error: {rmse}")
print(f"Mean Absolute Error: {mae}")
print(f"R-squared: {r2}")
# Perform cross-validation
cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5, scoring='neg_mean_squared_error')
print(f"Cross-validation scores: {-cv_scores}")
print(f"Average CV score: {-cv_scores.mean()}")
Aquí tienes un desglose de lo que hace el código:
- Crea y entrena un modelo de Regresión Lineal utilizando los datos de entrenamiento escalados.
- Realiza predicciones en los datos de prueba escalados.
- Evalúa el rendimiento del modelo utilizando varias métricas:
- Error Cuadrático Medio (MSE)
- Raíz del Error Cuadrático Medio (RMSE)
- Error Absoluto Medio (MAE)
- Puntuación R-cuadrado (R2)
- Realiza validación cruzada para evaluar el rendimiento del modelo en diferentes subconjuntos de los datos de entrenamiento.
El paso imprime estas métricas de evaluación, proporcionando información sobre qué tan bien está funcionando el modelo en la predicción de los precios de las viviendas. Los puntajes de la validación cruzada brindan una indicación de la consistencia del modelo en diferentes subconjuntos de los datos.
9.1.4 Interpretación de los Coeficientes del Modelo
Entender los coeficientes de nuestro modelo de regresión lineal es crucial, ya que proporciona información valiosa sobre la importancia relativa de diferentes características en la determinación de los precios de las viviendas. Al examinar estos coeficientes, podemos identificar qué atributos tienen el impacto más significativo en los valores de las propiedades en el mercado inmobiliario de Boston. Este análisis no solo nos ayuda a interpretar el proceso de toma de decisiones del modelo, sino que también ofrece ideas prácticas para profesionales inmobiliarios, inversionistas y responsables de políticas públicas.
La magnitud de cada coeficiente indica la fuerza de la influencia de su característica correspondiente en los precios de las viviendas, mientras que el signo (positivo o negativo) revela si la característica tiende a aumentar o disminuir los valores de las propiedades.
Por ejemplo, un coeficiente positivo grande para la característica "número de habitaciones" sugeriría que las casas con más habitaciones generalmente tienen precios más altos, manteniendo todo lo demás constante. Por el contrario, un coeficiente negativo para una característica como "tasa de criminalidad" indicaría que mayores tasas de criminalidad en un área están asociadas con precios más bajos de las viviendas.
# Store and sort coefficients by absolute value
coefficients = pd.DataFrame(model.coef_, index=X.columns, columns=['Coefficient'])
coefficients = coefficients.sort_values(by='Coefficient', key=lambda x: x.abs(), ascending=False)
# Print sorted coefficients
print(coefficients)
# Plot feature coefficients
plt.figure(figsize=(12, 8))
coefficients.plot(kind='bar', legend=False)
plt.title('Feature Coefficients in Linear Regression')
plt.xlabel('Features')
plt.ylabel('Coefficient Value')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()
Aquí te explico lo que hace:
- Crea un DataFrame llamado
coefficients
que almacena los coeficientes del modelo junto con sus nombres de características correspondientes. - Ordena los coeficientes por sus valores absolutos en orden descendente, facilitando la identificación de las características más influyentes que afectan los precios de las viviendas.
- Imprime los coeficientes ordenados, permitiéndonos analizar el impacto numérico de cada característica en los precios de las viviendas.
- Genera un gráfico de barras para visualizar los coeficientes:
- Asegura una clara visibilidad al establecer un tamaño de figura apropiado (12x8 pulgadas).
- Grafica los coeficientes como barras, distinguiendo las influencias positivas y negativas.
- Añade un título, etiqueta del eje x, y etiqueta del eje y para proporcionar contexto.
- Rota las etiquetas del eje x en 45 grados para mejorar la legibilidad, asegurando que los nombres de las características no se superpongan.
- Ajusta el diseño usando
plt.tight_layout()
para que todos los elementos encajen adecuadamente dentro de la figura.
9.1.5 Mejorando el Modelo con Regresión Ridge
Para mejorar el rendimiento de nuestro modelo y mitigar el riesgo de sobreajuste, implementaremos la Regresión Ridge, una técnica poderosa que introduce un término de regularización en la ecuación estándar de la regresión lineal.
Este enfoque, también conocido como regularización de Tikhonov, añade un término de penalización a la función de pérdida, reduciendo efectivamente los coeficientes de las características menos importantes hacia cero. Al hacerlo, la Regresión Ridge ayuda a reducir la sensibilidad del modelo a puntos de datos individuales y promueve una solución más estable y generalizable. Esto es especialmente útil cuando se trabaja con conjuntos de datos que tienen multicolinealidad entre las características o cuando el número de predictores es grande en relación con el número de observaciones.
El término de regularización en la Regresión Ridge está controlado por un hiperparámetro, alfa, que determina la fuerza de la penalización. Usaremos validación cruzada para encontrar el valor óptimo de este hiperparámetro, asegurando que nuestro modelo logre el equilibrio adecuado entre sesgo y varianza.
# Create a Ridge Regression model with hyperparameter tuning
from sklearn.model_selection import GridSearchCV
param_grid = {'alpha': [0.1, 1, 10, 100]}
ridge = Ridge()
grid_search = GridSearchCV(ridge, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train_scaled, y_train)
best_ridge = grid_search.best_estimator_
y_pred_ridge = best_ridge.predict(X_test_scaled)
mse_ridge = mean_squared_error(y_test, y_pred_ridge)
r2_ridge = r2_score(y_test, y_pred_ridge)
print(f"Best alpha: {grid_search.best_params_['alpha']}")
print(f"Ridge Regression Mean Squared Error: {mse_ridge}")
print(f"Ridge Regression R-squared: {r2_ridge}")
Aquí tienes un desglose de lo que hace:
- Importa
GridSearchCV
de scikit-learn, que se utiliza para la afinación de hiperparámetros. - Configura una cuadrícula de parámetros para el hiperparámetro 'alpha' de la Regresión Ridge, con valores [0.1, 1, 10, 100].
- Crea un modelo de Regresión Ridge y utiliza
GridSearchCV
para encontrar el mejor valor de 'alpha' mediante validación cruzada de 5 pliegues. - El mejor modelo se utiliza para hacer predicciones en el conjunto de prueba.
- Finalmente, calcula e imprime el Error Cuadrático Medio y el puntaje R-cuadrado para el modelo de Regresión Ridge.
Este enfoque ayuda a prevenir el sobreajuste al añadir un término de penalización a la función de pérdida, controlado por el parámetro 'alpha'. Este paso automatiza el proceso de encontrar el valor óptimo de 'alpha', equilibrando la complejidad y el rendimiento del modelo.
9.1.6 Supuestos y Diagnósticos del Modelo
Asegurar la validez de los supuestos de la regresión lineal es un paso crítico en nuestro proceso de modelado. Realizaremos un examen exhaustivo de tres supuestos clave:
- Linealidad
- Normalidad de los residuos
- Homocedasticidad (varianza constante de los residuos)
Estos supuestos forman la base de la regresión lineal y, cuando se cumplen, contribuyen a la fiabilidad e interpretabilidad de los resultados de nuestro modelo.
- Linealidad:
- Asume una relación lineal entre las variables predictoras y la variable de respuesta.
- Evaluaremos esto mediante gráficos de residuos vs. valores predichos, buscando una dispersión aleatoria (sin patrones).
- Normalidad de los Residuos:
- Asume que los errores siguen una distribución normal.
- Lo evaluaremos utilizando histogramas, gráficos Q-Q y pruebas estadísticas.
- Homocedasticidad:
- Asegura que la dispersión de los residuos permanece constante a través de los valores predichos.
- Esto es crucial porque la heterocedasticidad puede llevar a errores estándar e intervalos de confianza poco fiables.
Mediante la comprobación rigurosa de estos supuestos, podemos identificar posibles violaciones que podrían comprometer la validez de nuestro modelo. Si se detectan violaciones, podemos explorar medidas correctivas, como:
- Transformaciones logarítmicas o potenciales de las variables predictoras
- Modelos de regresión ponderada
- Técnicas alternativas de modelado (por ejemplo, modelos basados en árboles)
import matplotlib.pyplot as plt
import scipy.stats as stats
# Compute residuals
residuals = y_test - y_pred_ridge # Ensure correct y_pred usage
# Create subplots for assumption diagnostics
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# 1. Residuals vs. Predicted values (Linearity & Homoscedasticity)
axes[0].scatter(y_pred_ridge, residuals, alpha=0.5)
axes[0].axhline(y=0, color='r', linestyle='--', linewidth=1) # Reference line at y=0
axes[0].set_xlabel('Predicted Values')
axes[0].set_ylabel('Residuals')
axes[0].set_title('Residuals vs Predicted')
# 2. Histogram of residuals (Normality)
axes[1].hist(residuals, bins=30, edgecolor='black', alpha=0.7)
axes[1].set_xlabel('Residuals')
axes[1].set_ylabel('Frequency')
axes[1].set_title('Histogram of Residuals')
# 3. Q-Q plot (Normality Check)
stats.probplot(residuals, dist="norm", plot=axes[2])
axes[2].set_title('Q-Q Plot')
plt.tight_layout()
plt.show()
Aquí una explicacion de lo que hace:
- Calcula los residuos restando los valores predichos de los valores reales de prueba.
- Crea una figura con tres subgráficos para el diagnóstico de supuestos:
- Residuos vs. Valores Predichos (gráfico izquierdo)
- Verifica la linealidad y homocedasticidad.
- Si los puntos muestran un patrón claro, se viola la linealidad.
- Si los residuos muestran una dispersión creciente o decreciente, puede haber heterocedasticidad.
- Histograma de Residuos (gráfico central)
- Evalúa la normalidad de los residuos.
- Si el histograma es simétrico y en forma de campana, se cumple el supuesto de normalidad.
- Gráfico Q-Q (gráfico derecho)
- Compara los residuos con una distribución normal teórica.
- Si los puntos siguen de cerca la línea diagonal, el supuesto de normalidad es válido.
- Residuos vs. Valores Predichos (gráfico izquierdo)
9.1.7 Análisis de la Importancia de las Características
Para obtener una comprensión más completa de la importancia de las características en nuestro modelo de predicción de precios de viviendas, utilizaremos un Random Forest Regressor. Este potente método de aprendizaje de conjunto no solo ofrece una perspectiva alternativa sobre la importancia de las características, sino que también presenta varias ventajas sobre los modelos lineales tradicionales.
Los Random Forests son especialmente hábiles para capturar relaciones no lineales e interacciones entre las características, que pueden no ser evidentes en nuestros análisis previos. Al agregar las puntuaciones de importancia a lo largo de múltiples árboles de decisión, podemos obtener una clasificación robusta y confiable de la importancia de las características.
Este enfoque nos ayudará a identificar cuáles factores tienen el impacto más significativo en los precios de las viviendas, revelando potencialmente conocimientos que no eran evidentes en nuestro modelo de regresión lineal.
from sklearn.ensemble import RandomForestRegressor
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X_train_scaled, y_train)
feature_importance = pd.DataFrame({'feature': X.columns, 'importance': rf_model.feature_importances_})
feature_importance = feature_importance.sort_values('importance', ascending=False)
plt.figure(figsize=(10, 6))
sns.barplot(x='importance', y='feature', data=feature_importance)
plt.title('Feature Importance (Random Forest)')
plt.tight_layout()
plt.show()
Aquí tienes un desglose de lo que hace:
- Importa el
RandomForestRegressor
de scikit-learn. - Crea un modelo de Random Forest con 100 árboles y un estado aleatorio fijo para asegurar la reproducibilidad.
- Ajusta el modelo a los datos de entrenamiento escalados (
X_train_scaled
yy_train
). - Crea un DataFrame con dos columnas: 'feature' (nombres de las características) e 'importance' (puntuaciones de importancia del modelo de Random Forest).
- Ordena las características por importancia en orden descendente.
- Configura un gráfico usando matplotlib y seaborn:
- Crea una figura de 10x6 pulgadas.
- Usa el
barplot
de seaborn para visualizar la importancia de las características. - Establece el título como "Feature Importance (Random Forest)".
- Ajusta el diseño para una mejor visibilidad.
- Muestra el gráfico.
Esta visualización ayuda a identificar qué características tienen el mayor impacto en los precios de las viviendas según el modelo de Random Forest, revelando potencialmente ideas que no eran evidentes en el modelo de regresión lineal.
9.1.8 Posibles Mejoras y Trabajo Futuro
Aunque nuestro modelo actual proporciona valiosos conocimientos, existen varias formas en las que podríamos mejorar su rendimiento:
- Ingeniería de características: Crear nuevas características o transformar las existentes para capturar relaciones más complejas.
- Probar otros algoritmos: Experimentar con algoritmos más avanzados como el Gradient Boosting (por ejemplo, XGBoost) o la Regresión por Vectores de Soporte.
- Métodos de ensamble: Combinar predicciones de múltiples modelos para crear una predicción más robusta.
- Recoger más datos: Si es posible, recolectar datos más recientes y diversos para mejorar la generalización del modelo.
- Abordar la no linealidad: Si existen relaciones no lineales fuertes, considerar el uso de características polinomiales o modelos más flexibles.
9.1.9 Conclusión
Este proyecto demuestra la aplicación integral de técnicas de regresión para predecir los precios de las viviendas en el dinámico mercado inmobiliario. Hemos cubierto meticulosamente varios aspectos cruciales del flujo de trabajo de ciencia de datos, incluyendo el análisis exploratorio de datos, el preprocesamiento riguroso, la construcción de modelos sofisticados, la evaluación exhaustiva y la interpretación detallada de los resultados. A través de nuestro análisis cuidadoso de varias características y su impacto en los precios de las viviendas, hemos desarrollado un modelo que ofrece valiosos conocimientos basados en datos para una amplia gama de interesados en la industria inmobiliaria.
Los profesionales inmobiliarios pueden aprovechar este modelo para tomar decisiones más informadas sobre la valoración de propiedades y las tendencias del mercado. Los propietarios de viviendas podrían encontrar útil comprender los factores que influyen en el valor de su propiedad con el tiempo. Los inversionistas pueden utilizar estos conocimientos para identificar propiedades potencialmente infravaloradas o oportunidades emergentes en el mercado. Sin embargo, es crucial recordar que, aunque nuestro modelo proporciona una base sólida para entender la dinámica de los precios de las viviendas, el mercado inmobiliario en el mundo real es inherentemente complejo y está influido por una multitud de factores, muchos de los cuales pueden no estar reflejados en nuestro conjunto de datos actual.
Factores como las condiciones económicas locales, cambios en las leyes de zonificación, variaciones en los patrones demográficos e incluso las tendencias económicas globales pueden desempeñar roles significativos en la configuración de los mercados de viviendas. Estos elementos a menudo interactúan de manera intrincada y pueden ser difíciles de modelar con precisión. Por lo tanto, aunque nuestro modelo predictivo ofrece valiosos conocimientos, debe considerarse como una herramienta entre muchas en el contexto más amplio del análisis inmobiliario y la toma de decisiones.
9.1 Proyecto 1: Predicción de Precios de Viviendas con Regresión
En este capítulo, exploraremos aplicaciones prácticas de técnicas de machine learning para resolver problemas del mundo real. Nuestro recorrido nos llevará a través de una serie de proyectos que demuestran el poder y la versatilidad de los algoritmos de machine learning en diversos dominios.
Cada proyecto en este capítulo está diseñado para proporcionarte experiencia práctica en la aplicación de conceptos de machine learning, desde la preprocesamiento de datos y la selección de modelos hasta la evaluación e interpretación de resultados. Al trabajar en estos proyectos, obtendrás conocimientos valiosos sobre todo el flujo de trabajo de machine learning y desarrollarás las habilidades necesarias para abordar desafíos complejos basados en datos.
Comenzamos con un problema clásico en el campo de los bienes raíces: la predicción de precios de viviendas. Este proyecto servirá como una introducción completa a las técnicas de regresión, la ingeniería de características y la evaluación de modelos. A medida que avancemos en el capítulo, nos encontraremos con proyectos cada vez más sofisticados que se basan en estas habilidades fundamentales, explorando temas como la clasificación, el clustering y las técnicas avanzadas de regresión.
Al final de este capítulo, tendrás un conjunto sólido de habilidades prácticas en machine learning, lo que te permitirá abordar una amplia gama de problemas en ciencia de datos con confianza. ¡Vamos a sumergirnos y comenzar a construir poderosos modelos predictivos!
La predicción de precios de viviendas es un desafío clásico de machine learning con profundas implicaciones para la industria inmobiliaria. Este problema complejo implica analizar una multitud de factores que influyen en el valor de las propiedades, que van desde la ubicación y el tamaño de la propiedad hasta los indicadores económicos locales y las tendencias del mercado. En el dinámico mundo de los bienes raíces, la capacidad de predecir con precisión los precios de las viviendas es una herramienta poderosa para diversas partes interesadas.
Los compradores pueden tomar decisiones de compra más informadas, identificando potencialmente propiedades infravaloradas o evitando aquellas sobrevaloradas. Los vendedores, armados con estimaciones precisas de valoración, pueden fijar estratégicamente el precio de sus propiedades para maximizar sus retornos mientras aseguran su competitividad en el mercado. Los inversores se benefician de estas predicciones al identificar oportunidades lucrativas y optimizar sus estrategias de gestión de cartera.
Este proyecto se adentra en la aplicación de técnicas avanzadas de machine learning, con un enfoque particular en metodologías de regresión, para desarrollar un modelo robusto que prediga los precios de las viviendas. Aprovechando un conjunto diverso de características y empleando algoritmos sofisticados, buscamos crear un marco predictivo capaz de navegar las complejidades del mercado inmobiliario y proporcionar valiosos conocimientos tanto a profesionales de la industria como a consumidores.
9.1.1 Declaración del Problema y Conjunto de Datos
Para este proyecto, utilizaremos el conjunto de datos de viviendas de Boston, una colección completa de información sobre diversas propiedades residenciales en el área metropolitana de Boston. Este conjunto de datos abarca una amplia gama de características que pueden influir en los precios de las viviendas, como las tasas de criminalidad en el vecindario, el número promedio de habitaciones por vivienda y la proximidad de la propiedad a los centros de empleo.
Nuestro objetivo principal es desarrollar un modelo predictivo sofisticado y preciso que pueda estimar los precios de las viviendas basándose en estos diversos atributos. Al analizar factores como las estadísticas locales de criminalidad, las características de las viviendas y las consideraciones geográficas como la accesibilidad a las autopistas, buscamos crear un algoritmo robusto capaz de proporcionar predicciones fiables de precios en el dinámico mercado inmobiliario de Boston.
Cargando y Explorando el Conjunto de Datos
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
# Load the California Housing dataset
california = fetch_california_housing(as_frame=True)
data = california.frame # Directly use the DataFrame
# Rename target column for clarity
data.rename(columns={'MedHouseVal': 'PRICE'}, inplace=True)
# Display the first few rows and summary statistics
print(data.head())
print(data.describe())
# Visualize correlations
plt.figure(figsize=(12, 10))
sns.heatmap(data.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Matrix of California Housing Data')
plt.show()
# Check for missing values
missing_values = data.isnull().sum().sum()
print(f"Total missing values: {missing_values}")
Aquí te explico lo que hace el código:
- Importa las bibliotecas necesarias para manipulación de datos (
pandas
,numpy
), visualización (seaborn
,matplotlib
), y aprendizaje automático (scikit-learn
). - Carga el conjunto de datos de viviendas de California utilizando la función
fetch_california_housing(as_frame=True)
de scikit-learn. - Crea un DataFrame de pandas a partir del conjunto de datos, utilizando
california.frame
y renombrando la variable objetivo aPRICE
para mayor claridad. - Muestra las primeras filas y estadísticas resumidas usando
print(data.head())
yprint(data.describe())
. - Visualiza la matriz de correlación entre características usando un mapa de calor con
seaborn.heatmap()
. - Verifica los valores faltantes en el conjunto de datos e imprime el conteo total.
Este código sirve como el paso inicial en el proceso de análisis de datos, proporcionando una comprensión fundamental de la estructura del conjunto de datos, las relaciones entre características y los posibles problemas de calidad de datos antes de proceder con el preprocesamiento avanzado y la construcción del modelo.
9.1.2 Preprocesamiento de Datos
Antes de poder construir nuestro modelo predictivo, es esencial realizar un preprocesamiento de datos exhaustivo. Este paso crucial abarca varias tareas importantes que preparan nuestro conjunto de datos para un análisis óptimo. Primero, debemos abordar cualquier valor faltante en nuestro conjunto de datos, empleando técnicas apropiadas como la imputación o eliminación, según la naturaleza y magnitud de los datos faltantes.
Luego, necesitamos identificar y manejar cuidadosamente los valores atípicos, que podrían sesgar nuestros resultados si no se corrigen. Esto puede involucrar métodos estadísticos para detectar anomalías y tomar decisiones informadas sobre si transformar, limitar o excluir los valores extremos. Finalmente, escalaremos nuestras características para asegurarnos de que estén en un rango numérico comparable, lo cual es especialmente importante para que muchos algoritmos de machine learning funcionen de manera efectiva.
Este proceso de escalado típicamente implica técnicas como la estandarización o normalización, que ajustan las características a una escala común sin distorsionar las diferencias en los rangos de valores ni perder información.
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Handle outliers (example for 'AveRooms' feature)
Q1 = data['AveRooms'].quantile(0.25)
Q3 = data['AveRooms'].quantile(0.75)
IQR = Q3 - Q1
# Filtering outliers using the IQR method
data = data[(data['AveRooms'] >= Q1 - 1.5 * IQR) & (data['AveRooms'] <= Q3 + 1.5 * IQR)]
# Split the dataset
X = data.drop('PRICE', axis=1)
y = data['PRICE']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Scale the features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Aquí te explico lo que hace el código:
- Manejo de valores atípicos:
- Se centra en la característica 'AveRooms' (promedio de habitaciones por vivienda), ya que 'RM' no existe en el conjunto de datos de Viviendas de California.
- Calcula el Rango Intercuartil (IQR) para esta característica.
- Elimina los puntos de datos que caen fuera de 1.5 veces el IQR por debajo de Q1 o por encima de Q3, que es un método común para eliminar valores atípicos.
- División del conjunto de datos:
- Separa las características (
X
) de la variable objetivo (y
, que es'PRICE'
). - Utiliza
train_test_split
para dividir los datos en conjuntos de entrenamiento y prueba, con un 20% de los datos reservados para pruebas.
- Separa las características (
- Escalado de características:
- Aplica
StandardScaler
para normalizar los valores de las características. - Ajusta el escalador con los datos de entrenamiento y transforma tanto los datos de entrenamiento como los de prueba para asegurar un escalado consistente.
- Aplica
9.1.3 Construcción y Evaluación del Modelo de Regresión Lineal
Comenzaremos nuestro análisis implementando un modelo de regresión lineal fundamental como nuestro enfoque base. Esta técnica, sencilla pero poderosa, nos permitirá establecer una base sólida para nuestro marco predictivo. Una vez construido el modelo, realizaremos una evaluación integral de su rendimiento utilizando una diversa gama de métricas.
Estas métricas proporcionarán información valiosa sobre la precisión del modelo, su capacidad predictiva y su efectividad general para estimar los precios de las viviendas en función de las características dadas. Al comenzar con este modelo simple, podemos obtener una comprensión clara de las relaciones subyacentes en nuestros datos y establecer un punto de referencia con el cual comparar modelos más complejos en etapas posteriores de nuestro análisis.
# Create and train the Linear Regression model
model = LinearRegression()
model.fit(X_train_scaled, y_train)
# Make predictions
y_pred = model.predict(X_test_scaled)
# Evaluate the model
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Root Mean Squared Error: {rmse}")
print(f"Mean Absolute Error: {mae}")
print(f"R-squared: {r2}")
# Perform cross-validation
cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5, scoring='neg_mean_squared_error')
print(f"Cross-validation scores: {-cv_scores}")
print(f"Average CV score: {-cv_scores.mean()}")
Aquí tienes un desglose de lo que hace el código:
- Crea y entrena un modelo de Regresión Lineal utilizando los datos de entrenamiento escalados.
- Realiza predicciones en los datos de prueba escalados.
- Evalúa el rendimiento del modelo utilizando varias métricas:
- Error Cuadrático Medio (MSE)
- Raíz del Error Cuadrático Medio (RMSE)
- Error Absoluto Medio (MAE)
- Puntuación R-cuadrado (R2)
- Realiza validación cruzada para evaluar el rendimiento del modelo en diferentes subconjuntos de los datos de entrenamiento.
El paso imprime estas métricas de evaluación, proporcionando información sobre qué tan bien está funcionando el modelo en la predicción de los precios de las viviendas. Los puntajes de la validación cruzada brindan una indicación de la consistencia del modelo en diferentes subconjuntos de los datos.
9.1.4 Interpretación de los Coeficientes del Modelo
Entender los coeficientes de nuestro modelo de regresión lineal es crucial, ya que proporciona información valiosa sobre la importancia relativa de diferentes características en la determinación de los precios de las viviendas. Al examinar estos coeficientes, podemos identificar qué atributos tienen el impacto más significativo en los valores de las propiedades en el mercado inmobiliario de Boston. Este análisis no solo nos ayuda a interpretar el proceso de toma de decisiones del modelo, sino que también ofrece ideas prácticas para profesionales inmobiliarios, inversionistas y responsables de políticas públicas.
La magnitud de cada coeficiente indica la fuerza de la influencia de su característica correspondiente en los precios de las viviendas, mientras que el signo (positivo o negativo) revela si la característica tiende a aumentar o disminuir los valores de las propiedades.
Por ejemplo, un coeficiente positivo grande para la característica "número de habitaciones" sugeriría que las casas con más habitaciones generalmente tienen precios más altos, manteniendo todo lo demás constante. Por el contrario, un coeficiente negativo para una característica como "tasa de criminalidad" indicaría que mayores tasas de criminalidad en un área están asociadas con precios más bajos de las viviendas.
# Store and sort coefficients by absolute value
coefficients = pd.DataFrame(model.coef_, index=X.columns, columns=['Coefficient'])
coefficients = coefficients.sort_values(by='Coefficient', key=lambda x: x.abs(), ascending=False)
# Print sorted coefficients
print(coefficients)
# Plot feature coefficients
plt.figure(figsize=(12, 8))
coefficients.plot(kind='bar', legend=False)
plt.title('Feature Coefficients in Linear Regression')
plt.xlabel('Features')
plt.ylabel('Coefficient Value')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()
Aquí te explico lo que hace:
- Crea un DataFrame llamado
coefficients
que almacena los coeficientes del modelo junto con sus nombres de características correspondientes. - Ordena los coeficientes por sus valores absolutos en orden descendente, facilitando la identificación de las características más influyentes que afectan los precios de las viviendas.
- Imprime los coeficientes ordenados, permitiéndonos analizar el impacto numérico de cada característica en los precios de las viviendas.
- Genera un gráfico de barras para visualizar los coeficientes:
- Asegura una clara visibilidad al establecer un tamaño de figura apropiado (12x8 pulgadas).
- Grafica los coeficientes como barras, distinguiendo las influencias positivas y negativas.
- Añade un título, etiqueta del eje x, y etiqueta del eje y para proporcionar contexto.
- Rota las etiquetas del eje x en 45 grados para mejorar la legibilidad, asegurando que los nombres de las características no se superpongan.
- Ajusta el diseño usando
plt.tight_layout()
para que todos los elementos encajen adecuadamente dentro de la figura.
9.1.5 Mejorando el Modelo con Regresión Ridge
Para mejorar el rendimiento de nuestro modelo y mitigar el riesgo de sobreajuste, implementaremos la Regresión Ridge, una técnica poderosa que introduce un término de regularización en la ecuación estándar de la regresión lineal.
Este enfoque, también conocido como regularización de Tikhonov, añade un término de penalización a la función de pérdida, reduciendo efectivamente los coeficientes de las características menos importantes hacia cero. Al hacerlo, la Regresión Ridge ayuda a reducir la sensibilidad del modelo a puntos de datos individuales y promueve una solución más estable y generalizable. Esto es especialmente útil cuando se trabaja con conjuntos de datos que tienen multicolinealidad entre las características o cuando el número de predictores es grande en relación con el número de observaciones.
El término de regularización en la Regresión Ridge está controlado por un hiperparámetro, alfa, que determina la fuerza de la penalización. Usaremos validación cruzada para encontrar el valor óptimo de este hiperparámetro, asegurando que nuestro modelo logre el equilibrio adecuado entre sesgo y varianza.
# Create a Ridge Regression model with hyperparameter tuning
from sklearn.model_selection import GridSearchCV
param_grid = {'alpha': [0.1, 1, 10, 100]}
ridge = Ridge()
grid_search = GridSearchCV(ridge, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train_scaled, y_train)
best_ridge = grid_search.best_estimator_
y_pred_ridge = best_ridge.predict(X_test_scaled)
mse_ridge = mean_squared_error(y_test, y_pred_ridge)
r2_ridge = r2_score(y_test, y_pred_ridge)
print(f"Best alpha: {grid_search.best_params_['alpha']}")
print(f"Ridge Regression Mean Squared Error: {mse_ridge}")
print(f"Ridge Regression R-squared: {r2_ridge}")
Aquí tienes un desglose de lo que hace:
- Importa
GridSearchCV
de scikit-learn, que se utiliza para la afinación de hiperparámetros. - Configura una cuadrícula de parámetros para el hiperparámetro 'alpha' de la Regresión Ridge, con valores [0.1, 1, 10, 100].
- Crea un modelo de Regresión Ridge y utiliza
GridSearchCV
para encontrar el mejor valor de 'alpha' mediante validación cruzada de 5 pliegues. - El mejor modelo se utiliza para hacer predicciones en el conjunto de prueba.
- Finalmente, calcula e imprime el Error Cuadrático Medio y el puntaje R-cuadrado para el modelo de Regresión Ridge.
Este enfoque ayuda a prevenir el sobreajuste al añadir un término de penalización a la función de pérdida, controlado por el parámetro 'alpha'. Este paso automatiza el proceso de encontrar el valor óptimo de 'alpha', equilibrando la complejidad y el rendimiento del modelo.
9.1.6 Supuestos y Diagnósticos del Modelo
Asegurar la validez de los supuestos de la regresión lineal es un paso crítico en nuestro proceso de modelado. Realizaremos un examen exhaustivo de tres supuestos clave:
- Linealidad
- Normalidad de los residuos
- Homocedasticidad (varianza constante de los residuos)
Estos supuestos forman la base de la regresión lineal y, cuando se cumplen, contribuyen a la fiabilidad e interpretabilidad de los resultados de nuestro modelo.
- Linealidad:
- Asume una relación lineal entre las variables predictoras y la variable de respuesta.
- Evaluaremos esto mediante gráficos de residuos vs. valores predichos, buscando una dispersión aleatoria (sin patrones).
- Normalidad de los Residuos:
- Asume que los errores siguen una distribución normal.
- Lo evaluaremos utilizando histogramas, gráficos Q-Q y pruebas estadísticas.
- Homocedasticidad:
- Asegura que la dispersión de los residuos permanece constante a través de los valores predichos.
- Esto es crucial porque la heterocedasticidad puede llevar a errores estándar e intervalos de confianza poco fiables.
Mediante la comprobación rigurosa de estos supuestos, podemos identificar posibles violaciones que podrían comprometer la validez de nuestro modelo. Si se detectan violaciones, podemos explorar medidas correctivas, como:
- Transformaciones logarítmicas o potenciales de las variables predictoras
- Modelos de regresión ponderada
- Técnicas alternativas de modelado (por ejemplo, modelos basados en árboles)
import matplotlib.pyplot as plt
import scipy.stats as stats
# Compute residuals
residuals = y_test - y_pred_ridge # Ensure correct y_pred usage
# Create subplots for assumption diagnostics
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# 1. Residuals vs. Predicted values (Linearity & Homoscedasticity)
axes[0].scatter(y_pred_ridge, residuals, alpha=0.5)
axes[0].axhline(y=0, color='r', linestyle='--', linewidth=1) # Reference line at y=0
axes[0].set_xlabel('Predicted Values')
axes[0].set_ylabel('Residuals')
axes[0].set_title('Residuals vs Predicted')
# 2. Histogram of residuals (Normality)
axes[1].hist(residuals, bins=30, edgecolor='black', alpha=0.7)
axes[1].set_xlabel('Residuals')
axes[1].set_ylabel('Frequency')
axes[1].set_title('Histogram of Residuals')
# 3. Q-Q plot (Normality Check)
stats.probplot(residuals, dist="norm", plot=axes[2])
axes[2].set_title('Q-Q Plot')
plt.tight_layout()
plt.show()
Aquí una explicacion de lo que hace:
- Calcula los residuos restando los valores predichos de los valores reales de prueba.
- Crea una figura con tres subgráficos para el diagnóstico de supuestos:
- Residuos vs. Valores Predichos (gráfico izquierdo)
- Verifica la linealidad y homocedasticidad.
- Si los puntos muestran un patrón claro, se viola la linealidad.
- Si los residuos muestran una dispersión creciente o decreciente, puede haber heterocedasticidad.
- Histograma de Residuos (gráfico central)
- Evalúa la normalidad de los residuos.
- Si el histograma es simétrico y en forma de campana, se cumple el supuesto de normalidad.
- Gráfico Q-Q (gráfico derecho)
- Compara los residuos con una distribución normal teórica.
- Si los puntos siguen de cerca la línea diagonal, el supuesto de normalidad es válido.
- Residuos vs. Valores Predichos (gráfico izquierdo)
9.1.7 Análisis de la Importancia de las Características
Para obtener una comprensión más completa de la importancia de las características en nuestro modelo de predicción de precios de viviendas, utilizaremos un Random Forest Regressor. Este potente método de aprendizaje de conjunto no solo ofrece una perspectiva alternativa sobre la importancia de las características, sino que también presenta varias ventajas sobre los modelos lineales tradicionales.
Los Random Forests son especialmente hábiles para capturar relaciones no lineales e interacciones entre las características, que pueden no ser evidentes en nuestros análisis previos. Al agregar las puntuaciones de importancia a lo largo de múltiples árboles de decisión, podemos obtener una clasificación robusta y confiable de la importancia de las características.
Este enfoque nos ayudará a identificar cuáles factores tienen el impacto más significativo en los precios de las viviendas, revelando potencialmente conocimientos que no eran evidentes en nuestro modelo de regresión lineal.
from sklearn.ensemble import RandomForestRegressor
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X_train_scaled, y_train)
feature_importance = pd.DataFrame({'feature': X.columns, 'importance': rf_model.feature_importances_})
feature_importance = feature_importance.sort_values('importance', ascending=False)
plt.figure(figsize=(10, 6))
sns.barplot(x='importance', y='feature', data=feature_importance)
plt.title('Feature Importance (Random Forest)')
plt.tight_layout()
plt.show()
Aquí tienes un desglose de lo que hace:
- Importa el
RandomForestRegressor
de scikit-learn. - Crea un modelo de Random Forest con 100 árboles y un estado aleatorio fijo para asegurar la reproducibilidad.
- Ajusta el modelo a los datos de entrenamiento escalados (
X_train_scaled
yy_train
). - Crea un DataFrame con dos columnas: 'feature' (nombres de las características) e 'importance' (puntuaciones de importancia del modelo de Random Forest).
- Ordena las características por importancia en orden descendente.
- Configura un gráfico usando matplotlib y seaborn:
- Crea una figura de 10x6 pulgadas.
- Usa el
barplot
de seaborn para visualizar la importancia de las características. - Establece el título como "Feature Importance (Random Forest)".
- Ajusta el diseño para una mejor visibilidad.
- Muestra el gráfico.
Esta visualización ayuda a identificar qué características tienen el mayor impacto en los precios de las viviendas según el modelo de Random Forest, revelando potencialmente ideas que no eran evidentes en el modelo de regresión lineal.
9.1.8 Posibles Mejoras y Trabajo Futuro
Aunque nuestro modelo actual proporciona valiosos conocimientos, existen varias formas en las que podríamos mejorar su rendimiento:
- Ingeniería de características: Crear nuevas características o transformar las existentes para capturar relaciones más complejas.
- Probar otros algoritmos: Experimentar con algoritmos más avanzados como el Gradient Boosting (por ejemplo, XGBoost) o la Regresión por Vectores de Soporte.
- Métodos de ensamble: Combinar predicciones de múltiples modelos para crear una predicción más robusta.
- Recoger más datos: Si es posible, recolectar datos más recientes y diversos para mejorar la generalización del modelo.
- Abordar la no linealidad: Si existen relaciones no lineales fuertes, considerar el uso de características polinomiales o modelos más flexibles.
9.1.9 Conclusión
Este proyecto demuestra la aplicación integral de técnicas de regresión para predecir los precios de las viviendas en el dinámico mercado inmobiliario. Hemos cubierto meticulosamente varios aspectos cruciales del flujo de trabajo de ciencia de datos, incluyendo el análisis exploratorio de datos, el preprocesamiento riguroso, la construcción de modelos sofisticados, la evaluación exhaustiva y la interpretación detallada de los resultados. A través de nuestro análisis cuidadoso de varias características y su impacto en los precios de las viviendas, hemos desarrollado un modelo que ofrece valiosos conocimientos basados en datos para una amplia gama de interesados en la industria inmobiliaria.
Los profesionales inmobiliarios pueden aprovechar este modelo para tomar decisiones más informadas sobre la valoración de propiedades y las tendencias del mercado. Los propietarios de viviendas podrían encontrar útil comprender los factores que influyen en el valor de su propiedad con el tiempo. Los inversionistas pueden utilizar estos conocimientos para identificar propiedades potencialmente infravaloradas o oportunidades emergentes en el mercado. Sin embargo, es crucial recordar que, aunque nuestro modelo proporciona una base sólida para entender la dinámica de los precios de las viviendas, el mercado inmobiliario en el mundo real es inherentemente complejo y está influido por una multitud de factores, muchos de los cuales pueden no estar reflejados en nuestro conjunto de datos actual.
Factores como las condiciones económicas locales, cambios en las leyes de zonificación, variaciones en los patrones demográficos e incluso las tendencias económicas globales pueden desempeñar roles significativos en la configuración de los mercados de viviendas. Estos elementos a menudo interactúan de manera intrincada y pueden ser difíciles de modelar con precisión. Por lo tanto, aunque nuestro modelo predictivo ofrece valiosos conocimientos, debe considerarse como una herramienta entre muchas en el contexto más amplio del análisis inmobiliario y la toma de decisiones.