Predicción de Precios de Vivienda en Boston con Modelos de Regresión Lineal

Conjunto de Datos de Viviendas de Boston

El conjunto de datos de viviendas de Boston contiene infomración sobre precios medios de viviendas en los suburbios de Boston de mediados de la década de 1970. Incluye 13 características diferentes y 506 registros, con el objetivo de identificar las relaciones entre estas características y los precios de la vivienda.

A continuación se describen las variables del conjunto de datos:

  • CRIM: Tasa de criminalidad per cápita por ciudad
  • ZN: Proporción de suelo residencial zonificado para lotes de más de 25,000 pies cuadrados
  • INDUS: Proporción de acres de negocios no minoristas por ciudad
  • CHAS: Variable ficticia que indica si elimita el río Charles (1 si limita, 0 si no)
  • NOX: Concentración de óxidos de nitrógeno (partes por 10 millones)
  • RM: Número promedio de habitaciones por vivienda
  • AGE: Proporción de unidades ocupadas por sus propietarios construidas antes de 1940
  • DIS: Distancias ponderadas a cinco centros de empleo de Boston
  • RAD: Índice de accesibilidad a autopistas radiales
  • TAX: Tasa de impuesto sobre la propiedad valorada en 10,000 dólares
  • PTRATIO: Relación alumno-profesor por ciudad
  • B: 1000(Bk - 0.63)² donde Bk es la proporción de personas de raza negra por ciudad
  • LSTAT: Porcentaje de población de estatus socioeconómico bajo
  • MEDV: Valor mediano de las viviendas ocupadas por sus propietarios en 1000s de dólares

Proceso de Análisis

1. Carga y Exploración de Datos

Primero, importamos las bibliotecas necesarias y cargamos el conjunto de datos:


import pandas as pd
import numpy as np
from sklearn.datasets import fetch_california_housing
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator

# Cargar el conjunto de datos (usando California housing como alternativa)
datos = fetch_california_housing()
print(datos.feature_names)  # Ver los nombres de las características
print(datos.data.shape)    # Analizar el número total de muestras y características
df_datos = pd.DataFrame(datos.data)  # Crear DataFrame con los datos
print(df_datos.head(5))     # Ver las primeras 5 filas

2. Análisis Visual y Preprocesamiento

Realizamos un análisis visual de las características para identificar patrones y valores atípicos:


# Variables independientes y dependiente
x = datos.data  # Características
y = datos.target  # Precios de las viviendas

# Nombres de las características
nombres = datos.feature_names

# Crear gráficos de dispersión para cada característica
for i in range(len(nombres)):
    plt.figure(figsize=(10, 7))
    plt.grid()
    plt.scatter(x[:, i], y, s=5)  # Ejes y tamaño de puntos
    plt.title(nombres[i])
    coef_corr = np.corrcoef(x[:, i], y)[0, 1]
    print(f"Coeficiente de correlación para {nombres[i]}: {coef_corr:.4f}")
    plt.show()

Identificamos y eliminamos valores atípicos en los precios de las viviendas:


# Visualizar distribución de precios
plt.figure(figsize=(20, 15))
eje_y = MultipleLocator(5)  # Intervalo de 5 en el eje Y
eje = plt.gca()
eje.yaxis.set_major_locator(eje_y)
plt.ylim(0, max(y) + 1)
plt.grid()
for i in range(len(y)):
    plt.scatter(i, y[i], s=20)
plt.title("Distribución de Precios de Viviendas")
plt.xlabel("Índice de Muestra")
plt.ylabel("Precio (en 100,000s)")
plt.show()

3. Implementación del Modelo de Regresión Lineal

Después del análisis visual, preparamos los datos y construimos el modelo de regresión lineal:


import numpy as np
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housing
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

# Cargar datos
datos = fetch_california_housing()
x = datos.data  # Características
y = datos.target  # Precios

# Selección de características basada en correlación
nombres = datos.feature_names
caracteristicas_relevantes = []

for i in range(len(nombres)):
    coef_corr = np.corrcoef(x[:, i], y)[0, 1]
    if abs(coef_corr) > 0.3:  # Umbral de correlación
        caracteristicas_relevantes.append(i)

x_filtrado = x[:, caracteristicas_relevantes]

# Eliminar valores atípicos
indices_atipicos = np.where(y > 5)[0]  # Umbral para valores atípicos
x_filtrado = np.delete(x_filtrado, indices_atipicos, axis=0)
y_filtrado = np.delete(y, indices_atipicos, axis=0)

# Dividir datos en conjuntos de entrenamiento y prueba
x_entrenamiento, x_prueba, y_entrenamiento, y_prueba = train_test_split(
    x_filtrado, y_filtrado, test_size=0.3, random_state=42
)

# Crear y entrenar el modelo de regresión lineal
modelo_regresion = LinearRegression()
modelo_regresion.fit(x_entrenamiento, y_entrenamiento)

# Realizar predicciones
predicciones = modelo_regresion.predict(x_prueba)

# Evaluar el modelo
error_cuadratico = mean_squared_error(y_prueba, predicciones).round(5)
puntuacion_r2 = r2_score(y_prueba, predicciones).round(5)

4. Evaluación y Visualización de Resultados

Evaluamos el rendimiento del modelo y visualizamos los resultados:


# Gráfico de valores reales vs predichos
fig = plt.figure(figsize=(13, 7))
plt.rcParams['font.family'] = "sans-serif"
plt.rcParams['font.sans-serif'] = "SimHei"
plt.rcParams['axes.unicode_minus'] = False

plt.plot(range(len(y_prueba)), y_prueba, color='red', linewidth=1, linestyle='-')
plt.plot(range(len(y_prueba)), predicciones, color='blue', linewidth=1, linestyle='dashdot')
plt.legend(['Valores Reales', 'Predicciones'])
plt.title("Comparación de Valores Reales y Predichos", fontsize=20)
texto_error = f"Error cuadrático medio={error_cuadratico}\nR²={puntuacion_r2}"
plt.xlabel(texto_error, size=18, color="black")
plt.grid()
plt.show()

# Gráfico de dispersión de valores reales vs predichos
plt.figure(figsize=(10, 10))
plt.scatter(y_prueba, predicciones, color='red', alpha=0.5)
plt.plot([min(y_prueba), max(y_prueba)], [min(y_prueba), max(y_prueba)], 'k--', lw=2)
plt.xlabel("Valores Reales")
plt.ylabel("Predicciones")
plt.title("Dispersión: Valores Reales vs Predicciones")
plt.grid()
plt.show()

Implementación con Datos Locales

Para usar un conjunto de datos local, podemos modificar el código de la siguiente manera:


import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt

# 1. Cargar el conjunto de datos local
# Asegúrate de reemplazar 'ruta/del/archivo.csv' con la ruta correcta
datos = pd.read_csv("ruta/del/archivo.csv")

# 2. Calcular coeficientes de correlación y filtrar variables
matriz_correlacion = datos.corr()
correlaciones_medv = matriz_correlacion["MEDV"]
variables_significativas = correlaciones_medv[correlaciones_medv.abs() > 0.4].index.tolist()
if "MEDV" in variables_significativas:
    variables_significativas.remove("MEDV")

print("Variables con mayor correlación con el precio (abs > 0.4):")
print(variables_significativas)

# 3. Visualizar distribución de precios
plt.figure(figsize=(10, 6))
plt.rcParams['font.family'] = "sans-serif"
plt.rcParams['font.sans-serif'] = "SimHei"
plt.rcParams['axes.unicode_minus'] = False
plt.scatter(datos.index, datos['MEDV'], alpha=0.5)
plt.xlabel('Índice de Muestra')
plt.ylabel('Precio Mediano (MEDV)')
plt.title('Distribución de Precios de Viviendas')
plt.grid(True)
plt.show()

# 4. Filtrar valores atípicos
datos_filtrados = datos[datos["MEDV"] < 50]  # Excluir precios atípicos

# 5. Preparar datos para el modelo
X = datos_filtrados[variables_significativas]
y = datos_filtrados["MEDV"]

# 6. Dividir en conjuntos de entrenamiento y prueba
X_entrenamiento, X_prueba, y_entrenamiento, y_prueba = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 7. Entrenar el modelo
modelo = LinearRegression()
modelo.fit(X_entrenamiento, y_entrenamiento)

# 8. Realizar predicciones y evaluar
y_predicho = modelo.predict(X_prueba)
mse = mean_squared_error(y_prueba, y_predicho)
r2 = r2_score(y_prueba, y_predicho)

print("Resultados del modelo de regresión lineal:")
print(f"Error cuadrático medio (MSE): {mse:.2f}")
print(f"Coeficiente de determinación (R²): {r2:.2f}")

# 9. Visualizar resultados
plt.figure(figsize=(12, 6))
plt.plot(y_prueba.values, label='Valores Reales', color='red')
plt.plot(y_predicho, label='Predicciones', color='blue', linestyle='--')
plt.legend()
plt.title("Comparación: Valores Reales vs Predicciones")
plt.xlabel("Índice de Muestra")
plt.ylabel("Precio")
plt.grid(True)
plt.show()

plt.figure(figsize=(8, 8))
plt.scatter(y_prueba, y_predicho, color='red', alpha=0.5)
plt.plot([min(y_prueba), max(y_prueba)], [min(y_prueba), max(y_prueba)], 'k--', lw=2)
plt.xlabel("Valores Reales")
plt.ylabel("Predicciones")
plt.title("Gráfico de Dispersión: Valores Reales vs Predicciones")
plt.grid(True)
plt.show()

Etiquetas: regresión lineal machine learning Aprendizaje Automático predicción de precios análisis de datos

Publicado el 7-20 02:11