Importancia de la limpieza de datos en proyectos de predicción
En los proyectos de predicción de precios de viviendas, la limpieza de datos es una etapa fundamental. Define la precisión del modelo y afecta directamente la confiabilidad de los análisis posteriores. Este artículo utiliza el conjunto de datos de precios de viviendas de Boston como ejemplo, explicando en detalle todo el proceso de limpieza mediante herramientas como Pandas y Matplotlib en Python, y genera un informe de limpieza y visualizaciones. Es adecuado para principiantes y se recomienda practicar en un Jupyter Notebook.
Preparación del entorno e importación de datos
Asegúrate de tener instaladas las siguientes bibliotecas de Python:
pip install pandas matplotlib seaborn numpy
Para cargar los datos, puedes utilizar un archivo CSV o el conjnuto de datos integrado en sklearn:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Cargar datos desde un archivo CSV local
df = pd.read_csv('ruta/al/archivo/viviendas_boston.csv')
# Alternativa: usar el dataset integrado en sklearn (requiere procesamiento adicional)
# from sklearn.datasets import load_boston
# data = load_boston()
# df = pd.DataFrame(data.data, columns=data.feature_names)
# df['precio'] = data.target
Inspección inicial del conjunto de datos
Primero, revisa la estructura general y las estadísticas básicas del dataframe:
print(df.head(10))
print(df.info())
print(df.describe())
Verifica los tipos de datos de cada columna. Si alguna columna categórica está codificada como numérica, conviértela al tipo adecuado:
df['chas'] = df['chas'].astype('category')
Detección y manejo de valores faltantes
Identifica las columnas con valores faltantes:
missing_counts = df.isnull().sum()
cols_with_missing = missing_counts[missing_counts > 0]
print(cols_with_missing)
Aplica estrateigas de imputación según el tipo de dato. Para columans numéricas, se puede usar la mediana:
col_name = 'zn' # Ejemplo de columna con valores faltantes
if col_name in cols_with_missing.index:
median_val = df[col_name].median()
df[col_name].fillna(median_val, inplace=True)
Para columnas categóricas, utiliza la moda:
cat_col = 'rad'
if df[cat_col].isnull().any():
mode_val = df[cat_col].mode()[0]
df[cat_col].fillna(mode_val, inplace=True)
Identificación y tratamiento de valores atípicos
Emplea el método del rango intercuartílico (IQR) para detectar outliers en columnas numéricas:
def remove_outliers_iqr(dataframe, column):
q25 = dataframe[column].quantile(0.25)
q75 = dataframe[column].quantile(0.75)
iqr = q75 - q25
lower_bound = q25 - 1.5 * iqr
upper_bound = q75 + 1.5 * iqr
mask = (dataframe[column] >= lower_bound) & (dataframe[column] <= upper_bound)
return dataframe[mask]
# Aplicar a una columna específica, por ejemplo 'crim'
df_clean = remove_outliers_iqr(df, 'crim')
Alternativamente, puedes utilizar el principio de las tres sigmas para datos con distribución normal.
Ingeniería de características y análisis de correlación
Calcula la matriz de correlación y visualízala para identificar relaciones lineales entre las variables:
corr_matrix = df_clean.corr()
print(corr_matrix['precio'].sort_values(ascending=False))
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, fmt=".2f", cmap='viridis')
plt.title('Matriz de Correlación entre Variables')
plt.tight_layout()
plt.show()
Selecciona las características más relevantes basándote en su correlación con la variable objetivo ('precio').
Análisis visual de la distribución de datos
Visualiza la distribución de la variable objetivo y otras variables clave:
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# Distribución de precios
sns.histplot(df_clean['precio'], kde=True, ax=axes[0, 0], color='skyblue')
axes[0, 0].set_title('Distribución de Precios de Viviendas')
axes[0, 0].set_xlabel('Precio (miles de dólares)')
# Boxplot de una variable numérica
sns.boxplot(x=df_clean['rm'], ax=axes[0, 1], color='lightgreen')
axes[0, 1].set_title('Distribución de Número Promedio de Habitaciones (rm)')
# Gráfico de barras para variable categórica
if 'chas' in df_clean.columns:
sns.countplot(x=df_clean['chas'], ax=axes[1, 0], palette='pastel')
axes[1, 0].set_title('Frecuencia de Variable Categórica (chas)')
# Relación entre dos variables numéricas
sns.scatterplot(data=df_clean, x='lstat', y='precio', ax=axes[1, 1], alpha=0.6)
axes[1, 1].set_title('Relación entre LSTAT y Precio')
axes[1, 1].set_xlabel('LSTAT (%)')
axes[1, 1].set_ylabel('Precio')
plt.tight_layout()
plt.show()
Generación de un informe de limpieza
Documenta todas las acciones realizadas durante el proceso. Un informe básico puede incluir:
- Dimensiones del conjunto de datos original y limpio.
- Cantidad y ubicación de los valores faltantes imputados.
- Número de valores atípicos eliminados por columna.
- Resumen estadístico de las principales variables.
- Conclusiones clave del análisis de correlación y visualización.
Se pueden utilizar herramientas como Pandas Profiling para generar un informe interactivo de manera automática:
from pandas_profiling import ProfileReport
profile = ProfileReport(df_clean, title="Informe de Perfil de Datos de Viviendas", explorative=True)
profile.to_widgets()
Código completo del proceso
A continuación, un script integrado que ejecuta los pasos principales:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 1. Carga de datos
data_path = 'viviendas_boston.csv'
df = pd.read_csv(data_path)
# 2. Inspección inicial
print("Forma del dataset:", df.shape)
print("\nTipos de datos:")
print(df.dtypes)
print("\nEstadísticas descriptivas:")
print(df.describe())
# 3. Manejo de valores faltantes
print("\nValores faltantes por columna:")
print(df.isnull().sum())
# Imputación ejemplo (ajustar según necesidad)
df['zn'].fillna(df['zn'].median(), inplace=True)
# 4. Eliminación de outliers (ejemplo en 'crim')
q_low = df['crim'].quantile(0.01)
q_high = df['crim'].quantile(0.99)
df_filtered = df[(df['crim'] > q_low) & (df['crim'] < q_high)]
# 5. Correlación y selección de características
corr = df_filtered.corr()
top_features = corr['precio'].abs().sort_values(ascending=False).index[1:6]
print("\nCaracterísticas más correlacionadas con el precio:")
print(top_features.tolist())
# 6. Visualización final
plt.figure(figsize=(8, 6))
sns.regplot(data=df_filtered, x='rm', y='precio', scatter_kws={'alpha':0.4})
plt.title('Relación entre Habitaciones y Precio')
plt.xlabel('Número promedio de habitaciones')
plt.ylabel('Precio')
plt.grid(True, linestyle='--', alpha=0.7)
plt.show()
# 7. Guardar datos limpios
df_filtered.to_csv('viviendas_boston_limpio.csv', index=False)
print("\n¡Proceso de limpieza completado y datos guardados!")