Capítulo 7: Creación de Características y Términos de Interacción
7.1 Creación de Nuevas Características a partir de Datos Existentes
La creación de nuevas características es una de las técnicas más poderosas para mejorar los modelos de Machine Learning. Este proceso, conocido como ingeniería de características, implica derivar nuevas variables a partir de datos existentes para capturar relaciones complejas, patrones e información que pueden no ser evidentes de inmediato en el conjunto de datos original. Al hacerlo, los científicos de datos pueden mejorar significativamente la precisión, robustez e interpretabilidad de los modelos.
La creación de características puede tomar muchas formas, incluyendo:
- Transformaciones matemáticas (por ejemplo, logarítmica, polinómica)
- Agregaciones (por ejemplo, media, mediana, suma de múltiples características)
- Binning o discretización de variables continuas
- Codificación de variables categóricas
- Creación de características específicas de dominio basadas en el conocimiento experto
En este capítulo, profundizaremos en el proceso de creación de características y exploraremos varias técnicas para combinar características existentes de manera significativa. Comenzaremos examinando métodos para derivar nuevas características a partir de datos existentes, como la extracción de fecha/hora, el análisis de texto y el procesamiento de información geográfica. Luego, avanzaremos hacia conceptos más avanzados, incluyendo los términos de interacción, que capturan los efectos combinados de múltiples características.
Al dominar estas técnicas, podrás extraer más valor de tus datos, descubriendo potencialmente patrones y relaciones ocultas que pueden dar a tus modelos una ventaja significativa en rendimiento predictivo y capacidad de generalización.
La creación de características es un paso crítico en el flujo de trabajo de la ciencia de datos, que implica la generación de nuevas características informativas a partir de datos existentes. Este proceso requiere no solo habilidades técnicas, sino también una comprensión profunda del dominio y del problema específico que se está abordando. Al crear nuevas características, los científicos de datos pueden descubrir patrones ocultos, simplificar relaciones complejas y reducir el ruido en el conjunto de datos, mejorando en última instancia el rendimiento y la interpretabilidad de los modelos de Machine Learning.
El arte de la creación de características a menudo implica pensamiento creativo y experimentación. Puede incluir técnicas tales como:
- Aplicar funciones matemáticas a características existentes
- Extraer información de tipos de datos complejos como fechas, texto o coordenadas geográficas
- Combinar múltiples características para crear representaciones más informativas
- Codificar variables categóricas de formas que capturen sus propiedades inherentes
- Aprovechar la experiencia del dominio para crear características que reflejen relaciones del mundo real
En esta sección, profundizaremos en varios métodos para la creación de características, comenzando con transformaciones matemáticas básicas y avanzando hacia técnicas más avanzadas. Exploraremos cómo extraer información significativa de datos de fecha y hora, lo cual puede ser crucial para capturar patrones temporales y estacionalidad. Además, discutiremos estrategias para combinar características y crear predictores más poderosos, incluyendo la creación de términos de interacción que capturen la interacción entre diferentes variables.
Al dominar estas técnicas, estarás mejor equipado para extraer el máximo valor de tus datos, descubriendo potencialmente ideas que no eran evidentes en el conjunto de datos original. Esto puede conducir a predicciones más precisas, mejor toma de decisiones y una comprensión más profunda de los patrones subyacentes en tus datos.
7.1.1 Transformaciones Matemáticas
Una de las técnicas fundamentales para crear nuevas características es aplicar transformaciones matemáticas a las características numéricas existentes. Estas transformaciones pueden mejorar significativamente la calidad y utilidad de tus datos para los modelos de Machine Learning. Las transformaciones comunes incluyen:
Transformación logarítmica
Esta técnica poderosa es particularmente efectiva para manejar distribuciones sesgadas hacia la derecha y comprimir amplios rangos de valores. Al aplicar la función logarítmica a los datos, podemos:
- Linearizar relaciones exponenciales, haciéndolas más fáciles de interpretar para los modelos
- Reducir el impacto de los valores atípicos, especialmente en conjuntos de datos con valores extremos
- Normalizar datos que abarcan varios órdenes de magnitud
- Mejorar el rendimiento de modelos que asumen datos distribuidos normalmente
Las transformaciones logarítmicas se aplican comúnmente en varios campos:
- Finanzas: Para analizar precios de acciones, rendimientos y otros métricas financieras
- Economía: Al tratar con PIB, crecimiento poblacional o tasas de inflación
- Biología: En el estudio del crecimiento bacteriano o cinética enzimática
- Física: Para analizar fenómenos como la intensidad del sonido o la magnitud de terremotos
Al aplicar transformaciones logarítmicas, es importante considerar:
- La base del logaritmo (logaritmo natural, base 10, etc.) y su impacto en la interpretación
- Manejo de valores cero o negativos, que pueden requerir agregar una constante antes de la transformación
- El efecto en la interpretabilidad del modelo y la necesidad de revertir la transformación de las predicciones
Ejemplo: Transformación Logarítmica para Crear una Nueva Característica
Supongamos que tenemos un conjunto de datos que contiene precios de casas, y sospechamos que la distribución de los precios está sesgada. Para reducir el sesgo y hacer la distribución más normal, podemos crear una nueva característica aplicando una transformación logarítmica a los precios originales.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'HousePrice': [50000, 120000, 250000, 500000, 1200000, 2500000]}
df = pd.DataFrame(data)
# Create a new feature by applying a logarithmic transformation
df['LogHousePrice'] = np.log(df['HousePrice'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(df['HousePrice'], kde=True, ax=ax1)
ax1.set_title('Distribution of Original House Prices')
ax1.set_xlabel('House Price')
sns.histplot(df['LogHousePrice'], kde=True, ax=ax2)
ax2.set_title('Distribution of Log-Transformed House Prices')
ax2.set_xlabel('Log(House Price)')
plt.tight_layout()
plt.show()
# Compare skewness
original_skew = df['HousePrice'].skew()
log_skew = df['LogHousePrice'].skew()
print(f"\nSkewness of original prices: {original_skew:.2f}")
print(f"Skewness of log-transformed prices: {log_skew:.2f}")
Este ejemplo de código demuestra el proceso de aplicar una transformación logarítmica a datos de precios de viviendas y analizar sus efectos.
Aquí tienes un desglose completo del código y su propósito:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización de datos estadísticos
- Crear datos de muestra:
- Un diccionario con una sola clave "HousePrice" y una lista de precios de viviendas como valores
- Convertir el diccionario en un DataFrame de pandas
- Aplicar transformación logarítmica:
- Crear una nueva columna "LogHousePrice" aplicando np.log() a la columna "HousePrice"
- Esta transformación ayuda a reducir la asimetría de los datos y a comprimir el rango de valores
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los precios originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas como la cantidad, media, desviación estándar, mínimo, máximo y cuartiles para ambas columnas
- Visualizar las distribuciones:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para los precios originales y transformados
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos utilizando plt.show()
- Comparar asimetría:
- Calcular la asimetría de las distribuciones de precios originales y transformados usando el método skew()
- Imprimir los valores de asimetría
Este ejemplo completo no solo aplica la transformación logarítmica, sino que también proporciona evidencia visual y estadística de sus efectos. Al comparar las distribuciones originales y transformadas, podemos observar cómo la transformación logarítmica ayuda a normalizar los datos, lo que potencialmente los hace más adecuados para diversos análisis estadísticos y modelos de Machine Learning.
Transformación de raíz cuadrada
Esta transformación es menos extrema que la logarítmica, pero aún es efectiva para reducir la asimetría hacia la derecha. Es particularmente útil para datos de conteo o cuando se enfrenta a una asimetría moderada hacia la derecha. La función de raíz cuadrada comprime el extremo superior de la distribución mientras expande el extremo inferior, lo que la hace ideal para datos que no requieren un cambio tan drástico como la transformación logarítmica.
Los principales beneficios de la transformación de raíz cuadrada incluyen:
- Reducir el impacto de los valores atípicos sin eliminarlos completamente
- Mejorar la normalidad de distribuciones con asimetría positiva
- Estabilizar la varianza en datos de conteo, especialmente cuando la varianza aumenta con la media
- Mantener una relación más intuitiva con los datos originales en comparación con la transformación logarítmica
Al aplicar transformaciones de raíz cuadrada, considera:
- La necesidad de manejar valores cero, lo que puede requerir agregar una pequeña constante antes de la transformación
- El efecto en valores negativos, que puede requerir tratamiento especial o transformaciones alternativas
- El impacto en la interpretabilidad del modelo y la posible necesidad de revertir la transformación de las predicciones
Las transformaciones de raíz cuadrada se utilizan comúnmente en varios campos, incluyendo:
- Ecología: Para analizar datos de abundancia de especies
- Psicología: Al trabajar con datos de tiempo de reacción
- Control de calidad: Para analizar el conteo de defectos en procesos de fabricación
Ejemplo: Transformación de raíz cuadrada para crear una nueva característica
Consideremos un conjunto de datos que contiene el número de defectos encontrados en productos manufacturados. Aplicaremos una transformación de raíz cuadrada a estos datos para reducir la asimetría hacia la derecha y estabilizar la varianza.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'DefectCount': [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]}
df = pd.DataFrame(data)
# Create a new feature by applying a square root transformation
df['SqrtDefectCount'] = np.sqrt(df['DefectCount'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(df['DefectCount'], kde=True, ax=ax1)
ax1.set_title('Distribution of Original Defect Counts')
ax1.set_xlabel('Defect Count')
sns.histplot(df['SqrtDefectCount'], kde=True, ax=ax2)
ax2.set_title('Distribution of Square Root Transformed Defect Counts')
ax2.set_xlabel('Square Root of Defect Count')
plt.tight_layout()
plt.show()
# Compare skewness
original_skew = df['DefectCount'].skew()
sqrt_skew = df['SqrtDefectCount'].skew()
print(f"\nSkewness of original counts: {original_skew:.2f}")
print(f"Skewness of square root transformed counts: {sqrt_skew:.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Un diccionario con una sola clave "DefectCount" y una lista de conteos de defectos como valores
- Convertir el diccionario en un DataFrame de pandas
- Aplicar la transformación de raíz cuadrada:
- Crear una nueva columna "SqrtDefectCount" aplicando np.sqrt() a la columna "DefectCount"
- Esta transformación ayuda a reducir la asimetría de los datos y a estabilizar la varianza
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los conteos de defectos originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas como cantidad, media, desviación estándar, mínimo, máximo y cuartiles para ambas columnas
- Visualizar las distribuciones:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para los conteos de defectos originales y transformados por raíz cuadrada
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos usando plt.show()
- Comparar la asimetría:
- Calcular la asimetría de las distribuciones de conteo de defectos originales y transformados por raíz cuadrada usando el método skew()
- Imprimir los valores de asimetría
Este ejemplo muestra cómo aplicar una transformación de raíz cuadrada a un conjunto de datos, visualizar los resultados y comparar la asimetría de los datos originales y transformados. La transformación de raíz cuadrada puede ser particularmente efectiva para datos de conteo, ayudando a estabilizar la varianza y reducir la asimetría hacia la derecha.
Transformación exponencial:
Esta técnica poderosa puede usarse para amplificar diferencias entre valores o para manejar distribuciones con asimetría hacia la izquierda. A diferencia de las transformaciones logarítmicas, que comprimen valores grandes, las transformaciones exponenciales los expanden, lo que hace que este método sea particularmente útil cuando:
- Quieres enfatizar las diferencias entre valores más altos en tu conjunto de datos
- Tus datos muestran una distribución con asimetría hacia la izquierda (negativa) que necesita ser equilibrada
- Estás trabajando con variables donde los cambios pequeños en valores altos son más significativos que en valores bajos
Aplicaciones comunes de las transformaciones exponenciales incluyen:
- Modelado financiero: Para calcular interés compuesto o tasas de crecimiento
- Dinámica de poblaciones: Al modelar patrones de crecimiento exponencial
- Procesamiento de señales: Para amplificar ciertos componentes de frecuencia
Al aplicar transformaciones exponenciales, es crucial considerar:
- La base de la función exponencial y su impacto en la escala de la transformación
- La posibilidad de crear valores atípicos extremos, lo cual puede requerir manejo adicional
- El efecto en la interpretabilidad del modelo y la necesidad de una cuidadosa transformación inversa de las predicciones
Ejemplo: Transformación Exponencial para Crear una Nueva Característica
Consideremos un conjunto de datos que contiene valores que queremos enfatizar o amplificar. Aplicaremos una transformación exponencial a estos datos para crear una nueva característica que resalte las diferencias entre valores más altos.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'Value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
df = pd.DataFrame(data)
# Create a new feature by applying an exponential transformation
df['ExpValue'] = np.exp(df['Value'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.scatterplot(x='Value', y='ExpValue', data=df, ax=ax1)
ax1.set_title('Original vs Exponential Values')
ax1.set_xlabel('Original Value')
ax1.set_ylabel('Exponential Value')
sns.lineplot(x='Value', y='Value', data=df, ax=ax2, label='Original')
sns.lineplot(x='Value', y='ExpValue', data=df, ax=ax2, label='Exponential')
ax2.set_title('Comparison of Original and Exponential Values')
ax2.set_xlabel('Value')
ax2.set_ylabel('Transformed Value')
ax2.legend()
plt.tight_layout()
plt.show()
# Compare ranges
original_range = df['Value'].max() - df['Value'].min()
exp_range = df['ExpValue'].max() - df['ExpValue'].min()
print(f"\nRange of original values: {original_range:.2f}")
print(f"Range of exponential transformed values: {exp_range:.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Un diccionario con una sola clave "Value" y una lista de valores del 1 al 10
- Convertir el diccionario en un DataFrame de pandas
- Aplicar la transformación exponencial:
- Crear una nueva columna "ExpValue" aplicando np.exp() a la columna "Value"
- Esta transformación amplifica exponencialmente los valores originales
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los valores originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas para ambas columnas
- Visualizar los datos:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar scatterplot() de seaborn para mostrar la relación entre los valores originales y exponenciales
- Usar lineplot() de seaborn para comparar el crecimiento de los valores originales y exponenciales
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos usando plt.show()
- Comparar los rangos:
- Calcular el rango (máximo - mínimo) para ambos valores, originales y transformados exponencialmente
- Imprimir los rangos para mostrar cómo la transformación exponencial ha amplificado las diferencias
Transformaciones de potencia
Incluyen cuadrado, cubo o potencias más altas. Estas transformaciones pueden ser particularmente efectivas para enfatizar valores mayores o capturar relaciones no lineales en tus datos. Aquí tienes una visión más detallada de las transformaciones de potencia:
- Transformación cuadrada (x²): Puede ser útil cuando deseas enfatizar diferencias entre valores grandes mientras comprimes las diferencias entre valores pequeños. A menudo se usa en análisis estadísticos y modelos de Machine Learning para capturar relaciones cuadráticas.
- Transformación cúbica (x³): Esta transformación amplifica aún más las diferencias que la cuadrada. Puede ser especialmente útil al tratar con variables donde pequeños cambios en valores altos son mucho más significativos que en valores bajos.
- Potencias más altas (x⁴, x⁵, etc.): Estas pueden usarse para capturar relaciones no lineales cada vez más complejas. Sin embargo, ten precaución al usar potencias muy altas, ya que pueden llevar a inestabilidad numérica y sobreajuste.
- Potencias fraccionarias (√x, ³√x, etc.): Son menos comunes, pero pueden ser valiosas en ciertos escenarios. Por ejemplo, una transformación de raíz cúbica puede ser útil para manejar valores atípicos extremos mientras mantiene parte de la escala original.
Al aplicar transformaciones de potencia, considera lo siguiente:
- La naturaleza de tus datos y el problema específico que estás intentando resolver. Diferentes transformaciones de potencia pueden ser más o menos apropiadas según tu conjunto de datos y objetivos.
- La posibilidad de crear o agravar valores atípicos, especialmente con potencias altas. Puede ser necesario manejar cuidadosamente los valores extremos.
- El impacto en la interpretabilidad del modelo. Las transformaciones de potencia pueden dificultar la interpretación directa de los coeficientes del modelo.
- La necesidad de escalar las características después de aplicar transformaciones de potencia, ya que pueden cambiar significativamente la escala de tus datos.
Al aplicar transformaciones de potencia de manera reflexiva, puedes a menudo descubrir patrones ocultos en tus datos y mejorar el rendimiento de tus modelos de Machine Learning, especialmente cuando tratas con relaciones complejas y no lineales entre variables.
Ejemplo: Transformación de potencia para crear nuevas características
Demostraremos cómo aplicar transformaciones de potencia a un conjunto de datos, incluyendo transformaciones cuadrada, cúbica y de raíz cuadrada. Visualizaremos los resultados y compararemos las distribuciones de los datos originales y transformados.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'Value': np.random.uniform(1, 100, 1000)}
df = pd.DataFrame(data)
# Apply power transformations
df['Square'] = df['Value'] ** 2
df['Cube'] = df['Value'] ** 3
df['SquareRoot'] = np.sqrt(df['Value'])
# Visualize the distributions
fig, axs = plt.subplots(2, 2, figsize=(15, 15))
sns.histplot(df['Value'], kde=True, ax=axs[0, 0])
axs[0, 0].set_title('Original Distribution')
sns.histplot(df['Square'], kde=True, ax=axs[0, 1])
axs[0, 1].set_title('Square Transformation')
sns.histplot(df['Cube'], kde=True, ax=axs[1, 0])
axs[1, 0].set_title('Cube Transformation')
sns.histplot(df['SquareRoot'], kde=True, ax=axs[1, 1])
axs[1, 1].set_title('Square Root Transformation')
plt.tight_layout()
plt.show()
# Compare skewness
print("Skewness:")
print(f"Original: {df['Value'].skew():.2f}")
print(f"Square: {df['Square'].skew():.2f}")
print(f"Cube: {df['Cube'].skew():.2f}")
print(f"Square Root: {df['SquareRoot'].skew():.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas y generación de números aleatorios
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Generar 1000 valores aleatorios entre 1 y 100 usando np.random.uniform()
- Almacenar los datos en un DataFrame de pandas
- Aplicar transformaciones de potencia:
- Transformación cuadrada:
df['Value'] ** 2
- Transformación cúbica:
df['Value'] ** 3
- Transformación de raíz cuadrada:
np.sqrt(df['Value'])
- Transformación cuadrada:
- Visualizar las distribuciones:
- Crear una cuadrícula de subgráficos de 2x2
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para cada distribución
- Establecer títulos apropiados para cada subgráfico
- Comparar asimetría:
- Calcular e imprimir la asimetría de cada distribución usando el método skew()
Este ejemplo muestra cómo las diferentes transformaciones de potencia afectan la distribución de los datos. Las transformaciones cuadrada y cúbica tienden a enfatizar valores más grandes y pueden aumentar la asimetría hacia la derecha, mientras que la transformación de raíz cuadrada puede ayudar a reducir la asimetría hacia la derecha y comprimir el rango de los valores más grandes.
Transformación de Box-Cox
Una familia versátil de transformaciones de potencia que incluye el logaritmo como caso especial. Esta transformación es particularmente útil para estabilizar la varianza y hacer que las distribuciones de datos se parezcan más a una normal. La transformación de Box-Cox se define por un parámetro λ (lambda), que determina el tipo específico de transformación aplicada a los datos. Cuando λ = 0, se vuelve equivalente a la transformación logarítmica natural.
Características clave de la transformación de Box-Cox incluyen:
- Flexibilidad: Al ajustar el parámetro λ, puede manejar una amplia gama de distribuciones de datos.
- Estabilización de la varianza: Ayuda a lograr homocedasticidad, una suposición clave en muchos modelos estadísticos.
- Normalización: Puede hacer que los datos sesgados sean más simétricos, aproximándose a una distribución normal.
- Mejora del rendimiento del modelo: Al abordar la no linealidad y la no normalidad, puede mejorar el rendimiento de varios modelos estadísticos y de Machine Learning.
Al aplicar la transformación de Box-Cox, es importante tener en cuenta que requiere que todos los valores sean positivos. Para conjuntos de datos con valores cero o negativos, puede ser necesario agregar una constante antes de la transformación. Además, el valor óptimo de λ puede determinarse mediante estimación de máxima verosimilitud, lo que permite una selección basada en datos de la transformación más adecuada.
Ejemplo: Transformación de Box-Cox
Demostraremos cómo aplicar la transformación de Box-Cox a un conjunto de datos y visualizar los resultados.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
# Generate sample data with a right-skewed distribution
np.random.seed(42)
data = np.random.lognormal(mean=0, sigma=0.5, size=1000)
# Create a DataFrame
df = pd.DataFrame({'original': data})
# Apply Box-Cox transformation
df['box_cox'], lambda_param = stats.boxcox(df['original'])
# Visualize the original and transformed distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.hist(df['original'], bins=30, edgecolor='black')
ax1.set_title('Original Distribution')
ax1.set_xlabel('Value')
ax1.set_ylabel('Frequency')
ax2.hist(df['box_cox'], bins=30, edgecolor='black')
ax2.set_title(f'Box-Cox Transformed (λ = {lambda_param:.2f})')
ax2.set_xlabel('Value')
ax2.set_ylabel('Frequency')
plt.tight_layout()
plt.show()
# Print summary statistics
print("Original Data:")
print(df['original'].describe())
print("\nBox-Cox Transformed Data:")
print(df['box_cox'].describe())
# Print skewness
print(f"\nOriginal Skewness: {df['original'].skew():.2f}")
print(f"Box-Cox Transformed Skewness: {df['box_cox'].skew():.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas y generación de números aleatorios
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones
- scipy.stats: Para la función de transformación de Box-Cox
- Generar datos de muestra:
- Usar np.random.lognormal() para crear una distribución sesgada hacia la derecha
- Almacenar los datos en un DataFrame de pandas
- Aplicar la transformación de Box-Cox:
- Usar stats.boxcox() para transformar los datos
- Esta función devuelve los datos transformados y el valor óptimo de lambda
- Visualizar las distribuciones:
- Crear dos subgráficos uno al lado del otro
- Graficar histogramas de los datos originales y transformados
- Establecer títulos y etiquetas apropiados
- Imprimir estadísticas descriptivas y asimetría:
- Usar describe() para obtener estadísticas descriptivas de los datos originales y transformados
- Calcular e imprimir la asimetría de ambas distribuciones usando skew()
Este ejemplo muestra cómo la transformación de Box-Cox puede normalizar una distribución sesgada hacia la derecha. El valor óptimo de lambda se determina automáticamente, y la transformación reduce significativamente la asimetría de los datos. Esto puede ser particularmente útil para preparar datos para modelos de Machine Learning que asumen características distribuidas normalmente.
Estas transformaciones cumplen múltiples propósitos en el proceso de ingeniería de características:
- Normalizar distribuciones de datos: Muchos métodos estadísticos y algoritmos de Machine Learning asumen datos distribuidos normalmente. Las transformaciones pueden ayudar a aproximar esta condición.
- Estabilizar la varianza: Algunos modelos, como la regresión lineal, asumen una varianza constante en todo el rango de las variables predictoras. Las transformaciones pueden ayudar a cumplir con esta suposición.
- Simplificar relaciones no lineales: Al aplicar la transformación adecuada, relaciones complejas no lineales pueden a veces convertirse en lineales, haciéndolas más fáciles de aprender para los modelos.
- Reducir el impacto de los valores atípicos: Las transformaciones como el logaritmo pueden comprimir la escala de una variable, reduciendo la influencia de valores extremos.
Al aplicar estas transformaciones, es crucial considerar la naturaleza de tus datos y las suposiciones de tu modelo elegido. Siempre valida el impacto de las transformaciones a través del análisis exploratorio de datos y métricas de rendimiento del modelo. Recuerda que, si bien las transformaciones pueden ser poderosas, también pueden afectar la interpretabilidad de tu modelo, así que úsalas con prudencia y documenta tu enfoque minuciosamente.
7.1.2 Extracción de características de fecha y hora
Al trabajar con conjuntos de datos que contienen características de fecha o tiempo, puedes mejorar significativamente el poder predictivo de tu modelo al extraer nuevas características significativas. Este proceso implica desglosar columnas de fecha y hora en sus partes constituyentes, como año, mes, día de la semana o hora. Estas características extraídas pueden capturar patrones temporales importantes y estacionalidad en tus datos.
Por ejemplo, en un conjunto de datos de ventas minoristas, extraer el mes y el día de la semana a partir de una fecha de venta podría revelar ciclos mensuales de ventas o patrones de compras semanales. De manera similar, para datos relacionados con el clima, el mes y el día podrían ayudar a capturar variaciones estacionales. En series temporales financieras, el año y el trimestre podrían ser cruciales para identificar tendencias a largo plazo y patrones cíclicos.
Además, puedes crear características más complejas basadas en el tiempo, como:
- ¿Es fin de semana o día laboral?
- ¿En qué trimestre del año?
- ¿Es un día festivo?
- ¿Número de días desde un evento específico?
Estas características derivadas pueden proporcionar información valiosa sobre fenómenos dependientes del tiempo, permitiendo que tu modelo capture patrones matizados que podrían no ser evidentes en los datos crudos de fecha y hora. Al incorporar estos aspectos temporales, puedes mejorar significativamente la capacidad de tu modelo para predecir resultados influenciados por tendencias estacionales, patrones cíclicos u otros factores basados en el tiempo.
Ejemplo: Extracción de componentes de fecha para crear nuevas características
Supongamos que tenemos un conjunto de datos que incluye una columna con la fecha de una venta de una casa. Podemos extraer nuevas características como YearSold, MonthSold y DayOfWeekSold para capturar tendencias temporales que pueden influir en los precios de las casas.
# Sample data with a date column
data = {
'SaleDate': ['2021-01-15', '2020-07-22', '2021-03-01', '2019-10-10', '2022-12-31'],
'Price': [250000, 300000, 275000, 225000, 350000]
}
df = pd.DataFrame(data)
# Convert the SaleDate column to a datetime object
df['SaleDate'] = pd.to_datetime(df['SaleDate'])
# Extract new features from the SaleDate column
df['YearSold'] = df['SaleDate'].dt.year
df['MonthSold'] = df['SaleDate'].dt.month
df['DayOfWeekSold'] = df['SaleDate'].dt.dayofweek
df['QuarterSold'] = df['SaleDate'].dt.quarter
df['IsWeekend'] = df['SaleDate'].dt.dayofweek.isin([5, 6]).astype(int)
df['DaysSince2019'] = (df['SaleDate'] - pd.Timestamp('2019-01-01')).dt.days
# Create a season column
df['Season'] = pd.cut(df['MonthSold'],
bins=[0, 3, 6, 9, 12],
labels=['Winter', 'Spring', 'Summer', 'Fall'],
include_lowest=True)
# View the new features
print(df)
# Analyze the relationship between time features and price
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(12, 6))
sns.scatterplot(data=df, x='DaysSince2019', y='Price', hue='Season')
plt.title('House Prices Over Time')
plt.show()
# Calculate average price by year and month
avg_price = df.groupby(['YearSold', 'MonthSold'])['Price'].mean().unstack()
plt.figure(figsize=(12, 6))
sns.heatmap(avg_price, annot=True, fmt='.0f', cmap='YlOrRd')
plt.title('Average House Price by Year and Month')
plt.show()
Este ejemplo de código muestra un enfoque completo para extraer y analizar características basadas en fechas de un conjunto de datos. Vamos a desglosar el código y su funcionalidad:
- Creación y Preprocesamiento de Datos:
- Creamos un conjunto de datos de muestra con las columnas 'SaleDate' y 'Price'.
- La columna 'SaleDate' se convierte en un objeto datetime usando pd.to_datetime().
- Extracción de Características:
- Componentes básicos de la fecha: Se extraen el año, el mes y el día de la semana.
- Trimestre: Se extrae el trimestre del año usando dt.quarter.
- IsWeekend: Se crea una característica binaria para indicar si la venta ocurrió en un fin de semana.
- DaysSince2019: Esta característica calcula el número de días desde el 1 de enero de 2019, lo cual puede ser útil para capturar tendencias a largo plazo.
- Season: Se crea una característica categórica utilizando pd.cut() para agrupar los meses en estaciones.
- Visualización de Datos:
- Se crea un gráfico de dispersión para visualizar la relación entre el número de días desde 2019 y el precio de la casa, con los puntos coloreados por estación.
- Se genera un mapa de calor para mostrar el precio promedio de la casa por año y mes, lo que puede revelar patrones estacionales en los precios de las viviendas.
Este ejemplo completo demuestra varias técnicas para extraer características significativas de los datos de fecha y visualizarlos para obtener información. Dicha ingeniería de características puede mejorar significativamente el poder predictivo de los modelos de Machine Learning que trabajan con datos de series temporales.
7.1.3 Combinación de Características
La combinación de múltiples características existentes puede crear nuevas características poderosas que capturen relaciones complejas entre variables. Este proceso, conocido como interacción de características o cruzamiento de características, va más allá de las combinaciones lineales simples y puede revelar patrones no lineales en los datos. Al multiplicar, dividir o tomar razones de características existentes, podemos generar nuevos conocimientos que las características individuales podrían no captar por sí solas.
Por ejemplo, en un conjunto de datos con información sobre casas, podrías crear una nueva característica que represente el precio por pie cuadrado dividiendo el precio de la casa por su tamaño en pies cuadrados. Esta característica derivada normaliza el precio en función del tamaño de la casa, revelando potencialmente patrones que ni el precio ni el tamaño por sí solos podrían mostrar. Otros ejemplos podrían incluir:
- Combinar 'número de habitaciones' y 'tamaño total en pies cuadrados' para crear una característica de 'tamaño promedio de habitación'
- Multiplicar 'edad de la casa' por 'número de renovaciones' para capturar el impacto de las actualizaciones en propiedades más antiguas
- Crear una razón de 'tamaño del terreno' a 'tamaño de la casa' para representar la proporción de tierra respecto a la construcción
Estas características combinadas pueden mejorar significativamente la capacidad de un modelo para capturar relaciones matizadas en los datos, mejorando potencialmente su poder predictivo e interpretabilidad. Sin embargo, es importante abordar la combinación de características de manera reflexiva, ya que la creación indiscriminada de nuevas características puede llevar al sobreajuste o aumentar la complejidad del modelo sin obtener ganancias correspondientes en el rendimiento.
Ejemplo: Creación de una Nueva Característica a partir de la Razón de Dos Características
Supongamos que tenemos un conjunto de datos con precios de casas y tamaños de casas (en pies cuadrados). Podemos crear una nueva característica, PricePerSqFt, para normalizar los precios de las casas en función de su tamaño.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {
'HousePrice': [500000, 700000, 600000, 550000, 800000],
'HouseSize': [2000, 3000, 2500, 1800, 3500],
'Bedrooms': [3, 4, 3, 2, 5],
'YearBuilt': [1990, 2005, 2000, 1985, 2010]
}
df = pd.DataFrame(data)
# Create new features
df['PricePerSqFt'] = df['HousePrice'] / df['HouseSize']
df['AvgRoomSize'] = df['HouseSize'] / df['Bedrooms']
df['AgeOfHouse'] = 2023 - df['YearBuilt']
df['PricePerRoom'] = df['HousePrice'] / df['Bedrooms']
# View the new features
print(df)
# Visualize relationships
plt.figure(figsize=(12, 8))
# Scatter plot of Price vs Size, colored by Age
plt.subplot(2, 2, 1)
sns.scatterplot(data=df, x='HouseSize', y='HousePrice', hue='AgeOfHouse', palette='viridis')
plt.title('House Price vs Size (colored by Age)')
# Bar plot of Average Price per Sq Ft by Bedrooms
plt.subplot(2, 2, 2)
sns.barplot(data=df, x='Bedrooms', y='PricePerSqFt')
plt.title('Avg Price per Sq Ft by Bedrooms')
# Heatmap of correlations
plt.subplot(2, 2, 3)
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
# Scatter plot of Price per Room vs Age of House
plt.subplot(2, 2, 4)
sns.scatterplot(data=df, x='AgeOfHouse', y='PricePerRoom')
plt.title('Price per Room vs Age of House')
plt.tight_layout()
plt.show()
# Statistical summary
print(df.describe())
# Correlation analysis
print(df.corr()['HousePrice'].sort_values(ascending=False))
Este ejemplo de código muestra un enfoque completo para la ingeniería de características y el análisis exploratorio de datos. Vamos a profundizar en sus componentes:
- Preparación de Datos:
- Importamos las bibliotecas necesarias: pandas para la manipulación de datos, matplotlib y seaborn para visualización.
- Se expande el conjunto de datos de muestra para incluir más casas y características adicionales como 'Bedrooms' y 'YearBuilt'.
- Ingeniería de Características:
- PricePerSqFt: Normaliza el precio de la casa según el tamaño.
- AvgRoomSize: Calcula el tamaño promedio de las habitaciones.
- AgeOfHouse: Determina la antigüedad de la casa (asumiendo que el año actual es 2023).
- PricePerRoom: Calcula el precio por dormitorio.
- Visualización de Datos:
- Se crea una cuadrícula de 2x2 gráficos para visualizar diferentes aspectos de los datos:
a) Diagrama de dispersión de House Price vs. Size, coloreado por Age.
b) Gráfico de barras que muestra el precio promedio por pie cuadrado para diferentes cantidades de dormitorios.
c) Mapa de calor de correlaciones entre todas las características.
d) Diagrama de dispersión de Price per Room vs. Age of House.
- Se crea una cuadrícula de 2x2 gráficos para visualizar diferentes aspectos de los datos:
- Análisis Estadístico:
- La función describe() proporciona estadísticas descriptivas para todas las columnas numéricas.
- El análisis de correlación muestra qué tan fuerte se correlaciona cada característica con HousePrice.
Este ejemplo completo no solo crea nuevas características, sino que también explora sus relaciones y posibles impactos en los precios de las viviendas. Las visualizaciones y análisis estadísticos proporcionan información que puede guiar en la ingeniería de características o en los procesos de selección de modelos.
7.1.4 Creación de Términos de Interacción
Los términos de interacción son características que capturan el efecto combinado de dos o más variables, ofreciendo una forma poderosa de modelar relaciones complejas en los datos. Estos términos van más allá de las combinaciones lineales simples, permitiendo la representación de interacciones no lineales entre características. Por ejemplo, en el modelado inmobiliario, la interacción entre el tamaño de una casa y su ubicación podría ser más predictiva de su precio que cualquiera de las características por sí sola. Esto se debe a que el valor de metros cuadrados adicionales puede variar significativamente según el vecindario.
Los términos de interacción son especialmente valiosos cuando hay una relación no lineal entre las características y la variable objetivo. Pueden revelar patrones que las características individuales podrían pasar por alto. Por ejemplo, en un contexto de marketing, la interacción entre la edad de un cliente y sus ingresos podría proporcionar información sobre el comportamiento de compra que ni la edad ni los ingresos podrían captar por sí solos. De manera similar, en estudios ambientales, la interacción entre temperatura y humedad podría ser crucial para predecir ciertos fenómenos meteorológicos.
Crear términos de interacción implica multiplicar dos o más características entre sí. Este proceso permite que el modelo aprenda diferentes efectos para una variable en función de los valores de otra. Es importante tener en cuenta que, aunque los términos de interacción pueden mejorar significativamente el rendimiento del modelo, deben usarse con moderación. Agregar demasiados términos de interacción puede llevar al sobreajuste y hacer que el modelo sea más difícil de interpretar. Por lo tanto, es crucial basar la creación de términos de interacción en el conocimiento del dominio o en el análisis exploratorio de datos para asegurarse de que agreguen un valor significativo al modelo.
Ejemplo: Creación de Términos de Interacción
Supongamos que queremos explorar la interacción entre el precio de una casa y el año en que se vendió. Podemos crear un término de interacción multiplicando estas dos características entre sí.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {
'HousePrice': [500000, 700000, 600000, 550000, 800000],
'YearSold': [2020, 2019, 2021, 2020, 2022],
'SquareFootage': [2000, 2500, 2200, 1800, 3000],
'Bedrooms': [3, 4, 3, 2, 5]
}
df = pd.DataFrame(data)
# Create interaction terms
df['Price_YearInteraction'] = df['HousePrice'] * df['YearSold']
df['Price_SqFtInteraction'] = df['HousePrice'] * df['SquareFootage']
df['PricePerSqFt'] = df['HousePrice'] / df['SquareFootage']
df['PricePerBedroom'] = df['HousePrice'] / df['Bedrooms']
# View the dataframe with new features
print(df)
# Visualize relationships
plt.figure(figsize=(12, 10))
# Scatter plot of Price vs Year, sized by SquareFootage
plt.subplot(2, 2, 1)
sns.scatterplot(data=df, x='YearSold', y='HousePrice', size='SquareFootage', hue='Bedrooms')
plt.title('House Price vs Year Sold')
# Heatmap of correlations
plt.subplot(2, 2, 2)
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
# Scatter plot of Price_YearInteraction vs PricePerSqFt
plt.subplot(2, 2, 3)
sns.scatterplot(data=df, x='Price_YearInteraction', y='PricePerSqFt')
plt.title('Price-Year Interaction vs Price Per Sq Ft')
# Bar plot of average Price Per Bedroom by Year
plt.subplot(2, 2, 4)
sns.barplot(data=df, x='YearSold', y='PricePerBedroom')
plt.title('Avg Price Per Bedroom by Year')
plt.tight_layout()
plt.show()
# Statistical summary
print(df.describe())
# Correlation analysis
print(df.corr()['HousePrice'].sort_values(ascending=False))
Este ejemplo de código demuestra un enfoque completo para crear y analizar términos de interacción en el contexto inmobiliario.
Desglosemos cada parte:
- Preparación de Datos:
- Importamos las bibliotecas necesarias: pandas para la manipulación de datos, matplotlib y seaborn para visualización.
- El conjunto de datos de muestra se expande para incluir más casas y características adicionales como 'SquareFootage' y 'Bedrooms'.
- Ingeniería de Características:
- Price_YearInteraction: Captura la interacción entre el precio de la casa y el año en que se vendió.
- Price_SqFtInteraction: Representa la interacción entre el precio y los pies cuadrados.
- PricePerSqFt: Una característica de razón que normaliza el precio por tamaño.
- PricePerBedroom: Otra característica de razón que muestra el precio por dormitorio.
- Visualización de Datos:
- Se crea una cuadrícula de gráficos 2x2 para visualizar diferentes aspectos de los datos:
a) Diagrama de dispersión de House Price vs. Year Sold, con el tamaño de los puntos representando los pies cuadrados y el color representando el número de dormitorios.
b) Mapa de calor de correlaciones entre todas las características.
c) Diagrama de dispersión de Price-Year Interaction vs. Price Per Sq Ft.
d) Gráfico de barras que muestra el precio promedio por dormitorio en diferentes años.
- Se crea una cuadrícula de gráficos 2x2 para visualizar diferentes aspectos de los datos:
- Análisis Estadístico:
- La función describe() proporciona estadísticas descriptivas para todas las columnas numéricas.
- El análisis de correlación muestra qué tan fuerte se correlaciona cada característica con HousePrice.
Este ejemplo completo no solo crea términos de interacción, sino que también explora sus relaciones con otras características y la variable objetivo (HousePrice). Las visualizaciones y análisis estadísticos proporcionan información que puede guiar en la ingeniería de características o en los procesos de selección de modelos. Por ejemplo, el mapa de calor de correlación puede revelar qué términos de interacción están más fuertemente asociados con los precios de las viviendas, mientras que los gráficos de dispersión pueden mostrar relaciones no lineales que estos términos podrían captar.
7.1.5 Conclusiones Clave y Sus Implicaciones
- Transformaciones matemáticas (como logarítmica o de raíz cuadrada) pueden ayudar a estabilizar la varianza o reducir la asimetría en los datos, mejorando el rendimiento de ciertos modelos de Machine Learning. Estas transformaciones son particularmente útiles cuando se trabaja con características que muestran crecimiento o decaimiento exponencial, o cuando la relación entre variables es no lineal.
- Extracción de características de fecha y hora permite crear nuevas características significativas a partir de columnas de fecha y hora, permitiendo que los modelos capturen patrones estacionales o basados en el tiempo. Esta técnica es crucial para el análisis de series temporales, pronósticos y comprensión de tendencias cíclicas en los datos. Por ejemplo, extraer el día de la semana, el mes o la estación puede revelar patrones importantes en ventas minoristas o consumo de energía.
- Combinación de características como razones o diferencias entre variables existentes puede descubrir relaciones importantes, como normalizar los precios de viviendas por tamaño. Estas características derivadas suelen proporcionar más información interpretativa y significativa que los datos sin procesar. Por ejemplo, en análisis financieros, razones como precio/ganancias o deuda/capital son más informativas que los componentes individuales por sí solos.
- Términos de interacción permiten que el modelo capture los efectos combinados de dos o más características, lo cual puede ser especialmente útil cuando las relaciones entre variables son no lineales. Estos términos pueden mejorar significativamente el rendimiento del modelo al considerar interdependencias complejas. Por ejemplo, en marketing, la interacción entre la edad del cliente y sus ingresos podría predecir mejor el comportamiento de compra que cualquiera de las variables por separado.
Comprender y aplicar estas técnicas de ingeniería de características puede mejorar drásticamente el rendimiento, la interpretabilidad y la robustez de los modelos. Sin embargo, es crucial abordar la creación de características de manera reflexiva, siempre considerando el conocimiento del dominio y los requisitos específicos de la tarea de Machine Learning. La ingeniería de características efectiva requiere una combinación de creatividad, comprensión estadística y experiencia en el dominio.
7.1 Creación de Nuevas Características a partir de Datos Existentes
La creación de nuevas características es una de las técnicas más poderosas para mejorar los modelos de Machine Learning. Este proceso, conocido como ingeniería de características, implica derivar nuevas variables a partir de datos existentes para capturar relaciones complejas, patrones e información que pueden no ser evidentes de inmediato en el conjunto de datos original. Al hacerlo, los científicos de datos pueden mejorar significativamente la precisión, robustez e interpretabilidad de los modelos.
La creación de características puede tomar muchas formas, incluyendo:
- Transformaciones matemáticas (por ejemplo, logarítmica, polinómica)
- Agregaciones (por ejemplo, media, mediana, suma de múltiples características)
- Binning o discretización de variables continuas
- Codificación de variables categóricas
- Creación de características específicas de dominio basadas en el conocimiento experto
En este capítulo, profundizaremos en el proceso de creación de características y exploraremos varias técnicas para combinar características existentes de manera significativa. Comenzaremos examinando métodos para derivar nuevas características a partir de datos existentes, como la extracción de fecha/hora, el análisis de texto y el procesamiento de información geográfica. Luego, avanzaremos hacia conceptos más avanzados, incluyendo los términos de interacción, que capturan los efectos combinados de múltiples características.
Al dominar estas técnicas, podrás extraer más valor de tus datos, descubriendo potencialmente patrones y relaciones ocultas que pueden dar a tus modelos una ventaja significativa en rendimiento predictivo y capacidad de generalización.
La creación de características es un paso crítico en el flujo de trabajo de la ciencia de datos, que implica la generación de nuevas características informativas a partir de datos existentes. Este proceso requiere no solo habilidades técnicas, sino también una comprensión profunda del dominio y del problema específico que se está abordando. Al crear nuevas características, los científicos de datos pueden descubrir patrones ocultos, simplificar relaciones complejas y reducir el ruido en el conjunto de datos, mejorando en última instancia el rendimiento y la interpretabilidad de los modelos de Machine Learning.
El arte de la creación de características a menudo implica pensamiento creativo y experimentación. Puede incluir técnicas tales como:
- Aplicar funciones matemáticas a características existentes
- Extraer información de tipos de datos complejos como fechas, texto o coordenadas geográficas
- Combinar múltiples características para crear representaciones más informativas
- Codificar variables categóricas de formas que capturen sus propiedades inherentes
- Aprovechar la experiencia del dominio para crear características que reflejen relaciones del mundo real
En esta sección, profundizaremos en varios métodos para la creación de características, comenzando con transformaciones matemáticas básicas y avanzando hacia técnicas más avanzadas. Exploraremos cómo extraer información significativa de datos de fecha y hora, lo cual puede ser crucial para capturar patrones temporales y estacionalidad. Además, discutiremos estrategias para combinar características y crear predictores más poderosos, incluyendo la creación de términos de interacción que capturen la interacción entre diferentes variables.
Al dominar estas técnicas, estarás mejor equipado para extraer el máximo valor de tus datos, descubriendo potencialmente ideas que no eran evidentes en el conjunto de datos original. Esto puede conducir a predicciones más precisas, mejor toma de decisiones y una comprensión más profunda de los patrones subyacentes en tus datos.
7.1.1 Transformaciones Matemáticas
Una de las técnicas fundamentales para crear nuevas características es aplicar transformaciones matemáticas a las características numéricas existentes. Estas transformaciones pueden mejorar significativamente la calidad y utilidad de tus datos para los modelos de Machine Learning. Las transformaciones comunes incluyen:
Transformación logarítmica
Esta técnica poderosa es particularmente efectiva para manejar distribuciones sesgadas hacia la derecha y comprimir amplios rangos de valores. Al aplicar la función logarítmica a los datos, podemos:
- Linearizar relaciones exponenciales, haciéndolas más fáciles de interpretar para los modelos
- Reducir el impacto de los valores atípicos, especialmente en conjuntos de datos con valores extremos
- Normalizar datos que abarcan varios órdenes de magnitud
- Mejorar el rendimiento de modelos que asumen datos distribuidos normalmente
Las transformaciones logarítmicas se aplican comúnmente en varios campos:
- Finanzas: Para analizar precios de acciones, rendimientos y otros métricas financieras
- Economía: Al tratar con PIB, crecimiento poblacional o tasas de inflación
- Biología: En el estudio del crecimiento bacteriano o cinética enzimática
- Física: Para analizar fenómenos como la intensidad del sonido o la magnitud de terremotos
Al aplicar transformaciones logarítmicas, es importante considerar:
- La base del logaritmo (logaritmo natural, base 10, etc.) y su impacto en la interpretación
- Manejo de valores cero o negativos, que pueden requerir agregar una constante antes de la transformación
- El efecto en la interpretabilidad del modelo y la necesidad de revertir la transformación de las predicciones
Ejemplo: Transformación Logarítmica para Crear una Nueva Característica
Supongamos que tenemos un conjunto de datos que contiene precios de casas, y sospechamos que la distribución de los precios está sesgada. Para reducir el sesgo y hacer la distribución más normal, podemos crear una nueva característica aplicando una transformación logarítmica a los precios originales.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'HousePrice': [50000, 120000, 250000, 500000, 1200000, 2500000]}
df = pd.DataFrame(data)
# Create a new feature by applying a logarithmic transformation
df['LogHousePrice'] = np.log(df['HousePrice'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(df['HousePrice'], kde=True, ax=ax1)
ax1.set_title('Distribution of Original House Prices')
ax1.set_xlabel('House Price')
sns.histplot(df['LogHousePrice'], kde=True, ax=ax2)
ax2.set_title('Distribution of Log-Transformed House Prices')
ax2.set_xlabel('Log(House Price)')
plt.tight_layout()
plt.show()
# Compare skewness
original_skew = df['HousePrice'].skew()
log_skew = df['LogHousePrice'].skew()
print(f"\nSkewness of original prices: {original_skew:.2f}")
print(f"Skewness of log-transformed prices: {log_skew:.2f}")
Este ejemplo de código demuestra el proceso de aplicar una transformación logarítmica a datos de precios de viviendas y analizar sus efectos.
Aquí tienes un desglose completo del código y su propósito:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización de datos estadísticos
- Crear datos de muestra:
- Un diccionario con una sola clave "HousePrice" y una lista de precios de viviendas como valores
- Convertir el diccionario en un DataFrame de pandas
- Aplicar transformación logarítmica:
- Crear una nueva columna "LogHousePrice" aplicando np.log() a la columna "HousePrice"
- Esta transformación ayuda a reducir la asimetría de los datos y a comprimir el rango de valores
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los precios originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas como la cantidad, media, desviación estándar, mínimo, máximo y cuartiles para ambas columnas
- Visualizar las distribuciones:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para los precios originales y transformados
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos utilizando plt.show()
- Comparar asimetría:
- Calcular la asimetría de las distribuciones de precios originales y transformados usando el método skew()
- Imprimir los valores de asimetría
Este ejemplo completo no solo aplica la transformación logarítmica, sino que también proporciona evidencia visual y estadística de sus efectos. Al comparar las distribuciones originales y transformadas, podemos observar cómo la transformación logarítmica ayuda a normalizar los datos, lo que potencialmente los hace más adecuados para diversos análisis estadísticos y modelos de Machine Learning.
Transformación de raíz cuadrada
Esta transformación es menos extrema que la logarítmica, pero aún es efectiva para reducir la asimetría hacia la derecha. Es particularmente útil para datos de conteo o cuando se enfrenta a una asimetría moderada hacia la derecha. La función de raíz cuadrada comprime el extremo superior de la distribución mientras expande el extremo inferior, lo que la hace ideal para datos que no requieren un cambio tan drástico como la transformación logarítmica.
Los principales beneficios de la transformación de raíz cuadrada incluyen:
- Reducir el impacto de los valores atípicos sin eliminarlos completamente
- Mejorar la normalidad de distribuciones con asimetría positiva
- Estabilizar la varianza en datos de conteo, especialmente cuando la varianza aumenta con la media
- Mantener una relación más intuitiva con los datos originales en comparación con la transformación logarítmica
Al aplicar transformaciones de raíz cuadrada, considera:
- La necesidad de manejar valores cero, lo que puede requerir agregar una pequeña constante antes de la transformación
- El efecto en valores negativos, que puede requerir tratamiento especial o transformaciones alternativas
- El impacto en la interpretabilidad del modelo y la posible necesidad de revertir la transformación de las predicciones
Las transformaciones de raíz cuadrada se utilizan comúnmente en varios campos, incluyendo:
- Ecología: Para analizar datos de abundancia de especies
- Psicología: Al trabajar con datos de tiempo de reacción
- Control de calidad: Para analizar el conteo de defectos en procesos de fabricación
Ejemplo: Transformación de raíz cuadrada para crear una nueva característica
Consideremos un conjunto de datos que contiene el número de defectos encontrados en productos manufacturados. Aplicaremos una transformación de raíz cuadrada a estos datos para reducir la asimetría hacia la derecha y estabilizar la varianza.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'DefectCount': [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]}
df = pd.DataFrame(data)
# Create a new feature by applying a square root transformation
df['SqrtDefectCount'] = np.sqrt(df['DefectCount'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(df['DefectCount'], kde=True, ax=ax1)
ax1.set_title('Distribution of Original Defect Counts')
ax1.set_xlabel('Defect Count')
sns.histplot(df['SqrtDefectCount'], kde=True, ax=ax2)
ax2.set_title('Distribution of Square Root Transformed Defect Counts')
ax2.set_xlabel('Square Root of Defect Count')
plt.tight_layout()
plt.show()
# Compare skewness
original_skew = df['DefectCount'].skew()
sqrt_skew = df['SqrtDefectCount'].skew()
print(f"\nSkewness of original counts: {original_skew:.2f}")
print(f"Skewness of square root transformed counts: {sqrt_skew:.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Un diccionario con una sola clave "DefectCount" y una lista de conteos de defectos como valores
- Convertir el diccionario en un DataFrame de pandas
- Aplicar la transformación de raíz cuadrada:
- Crear una nueva columna "SqrtDefectCount" aplicando np.sqrt() a la columna "DefectCount"
- Esta transformación ayuda a reducir la asimetría de los datos y a estabilizar la varianza
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los conteos de defectos originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas como cantidad, media, desviación estándar, mínimo, máximo y cuartiles para ambas columnas
- Visualizar las distribuciones:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para los conteos de defectos originales y transformados por raíz cuadrada
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos usando plt.show()
- Comparar la asimetría:
- Calcular la asimetría de las distribuciones de conteo de defectos originales y transformados por raíz cuadrada usando el método skew()
- Imprimir los valores de asimetría
Este ejemplo muestra cómo aplicar una transformación de raíz cuadrada a un conjunto de datos, visualizar los resultados y comparar la asimetría de los datos originales y transformados. La transformación de raíz cuadrada puede ser particularmente efectiva para datos de conteo, ayudando a estabilizar la varianza y reducir la asimetría hacia la derecha.
Transformación exponencial:
Esta técnica poderosa puede usarse para amplificar diferencias entre valores o para manejar distribuciones con asimetría hacia la izquierda. A diferencia de las transformaciones logarítmicas, que comprimen valores grandes, las transformaciones exponenciales los expanden, lo que hace que este método sea particularmente útil cuando:
- Quieres enfatizar las diferencias entre valores más altos en tu conjunto de datos
- Tus datos muestran una distribución con asimetría hacia la izquierda (negativa) que necesita ser equilibrada
- Estás trabajando con variables donde los cambios pequeños en valores altos son más significativos que en valores bajos
Aplicaciones comunes de las transformaciones exponenciales incluyen:
- Modelado financiero: Para calcular interés compuesto o tasas de crecimiento
- Dinámica de poblaciones: Al modelar patrones de crecimiento exponencial
- Procesamiento de señales: Para amplificar ciertos componentes de frecuencia
Al aplicar transformaciones exponenciales, es crucial considerar:
- La base de la función exponencial y su impacto en la escala de la transformación
- La posibilidad de crear valores atípicos extremos, lo cual puede requerir manejo adicional
- El efecto en la interpretabilidad del modelo y la necesidad de una cuidadosa transformación inversa de las predicciones
Ejemplo: Transformación Exponencial para Crear una Nueva Característica
Consideremos un conjunto de datos que contiene valores que queremos enfatizar o amplificar. Aplicaremos una transformación exponencial a estos datos para crear una nueva característica que resalte las diferencias entre valores más altos.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'Value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
df = pd.DataFrame(data)
# Create a new feature by applying an exponential transformation
df['ExpValue'] = np.exp(df['Value'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.scatterplot(x='Value', y='ExpValue', data=df, ax=ax1)
ax1.set_title('Original vs Exponential Values')
ax1.set_xlabel('Original Value')
ax1.set_ylabel('Exponential Value')
sns.lineplot(x='Value', y='Value', data=df, ax=ax2, label='Original')
sns.lineplot(x='Value', y='ExpValue', data=df, ax=ax2, label='Exponential')
ax2.set_title('Comparison of Original and Exponential Values')
ax2.set_xlabel('Value')
ax2.set_ylabel('Transformed Value')
ax2.legend()
plt.tight_layout()
plt.show()
# Compare ranges
original_range = df['Value'].max() - df['Value'].min()
exp_range = df['ExpValue'].max() - df['ExpValue'].min()
print(f"\nRange of original values: {original_range:.2f}")
print(f"Range of exponential transformed values: {exp_range:.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Un diccionario con una sola clave "Value" y una lista de valores del 1 al 10
- Convertir el diccionario en un DataFrame de pandas
- Aplicar la transformación exponencial:
- Crear una nueva columna "ExpValue" aplicando np.exp() a la columna "Value"
- Esta transformación amplifica exponencialmente los valores originales
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los valores originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas para ambas columnas
- Visualizar los datos:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar scatterplot() de seaborn para mostrar la relación entre los valores originales y exponenciales
- Usar lineplot() de seaborn para comparar el crecimiento de los valores originales y exponenciales
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos usando plt.show()
- Comparar los rangos:
- Calcular el rango (máximo - mínimo) para ambos valores, originales y transformados exponencialmente
- Imprimir los rangos para mostrar cómo la transformación exponencial ha amplificado las diferencias
Transformaciones de potencia
Incluyen cuadrado, cubo o potencias más altas. Estas transformaciones pueden ser particularmente efectivas para enfatizar valores mayores o capturar relaciones no lineales en tus datos. Aquí tienes una visión más detallada de las transformaciones de potencia:
- Transformación cuadrada (x²): Puede ser útil cuando deseas enfatizar diferencias entre valores grandes mientras comprimes las diferencias entre valores pequeños. A menudo se usa en análisis estadísticos y modelos de Machine Learning para capturar relaciones cuadráticas.
- Transformación cúbica (x³): Esta transformación amplifica aún más las diferencias que la cuadrada. Puede ser especialmente útil al tratar con variables donde pequeños cambios en valores altos son mucho más significativos que en valores bajos.
- Potencias más altas (x⁴, x⁵, etc.): Estas pueden usarse para capturar relaciones no lineales cada vez más complejas. Sin embargo, ten precaución al usar potencias muy altas, ya que pueden llevar a inestabilidad numérica y sobreajuste.
- Potencias fraccionarias (√x, ³√x, etc.): Son menos comunes, pero pueden ser valiosas en ciertos escenarios. Por ejemplo, una transformación de raíz cúbica puede ser útil para manejar valores atípicos extremos mientras mantiene parte de la escala original.
Al aplicar transformaciones de potencia, considera lo siguiente:
- La naturaleza de tus datos y el problema específico que estás intentando resolver. Diferentes transformaciones de potencia pueden ser más o menos apropiadas según tu conjunto de datos y objetivos.
- La posibilidad de crear o agravar valores atípicos, especialmente con potencias altas. Puede ser necesario manejar cuidadosamente los valores extremos.
- El impacto en la interpretabilidad del modelo. Las transformaciones de potencia pueden dificultar la interpretación directa de los coeficientes del modelo.
- La necesidad de escalar las características después de aplicar transformaciones de potencia, ya que pueden cambiar significativamente la escala de tus datos.
Al aplicar transformaciones de potencia de manera reflexiva, puedes a menudo descubrir patrones ocultos en tus datos y mejorar el rendimiento de tus modelos de Machine Learning, especialmente cuando tratas con relaciones complejas y no lineales entre variables.
Ejemplo: Transformación de potencia para crear nuevas características
Demostraremos cómo aplicar transformaciones de potencia a un conjunto de datos, incluyendo transformaciones cuadrada, cúbica y de raíz cuadrada. Visualizaremos los resultados y compararemos las distribuciones de los datos originales y transformados.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'Value': np.random.uniform(1, 100, 1000)}
df = pd.DataFrame(data)
# Apply power transformations
df['Square'] = df['Value'] ** 2
df['Cube'] = df['Value'] ** 3
df['SquareRoot'] = np.sqrt(df['Value'])
# Visualize the distributions
fig, axs = plt.subplots(2, 2, figsize=(15, 15))
sns.histplot(df['Value'], kde=True, ax=axs[0, 0])
axs[0, 0].set_title('Original Distribution')
sns.histplot(df['Square'], kde=True, ax=axs[0, 1])
axs[0, 1].set_title('Square Transformation')
sns.histplot(df['Cube'], kde=True, ax=axs[1, 0])
axs[1, 0].set_title('Cube Transformation')
sns.histplot(df['SquareRoot'], kde=True, ax=axs[1, 1])
axs[1, 1].set_title('Square Root Transformation')
plt.tight_layout()
plt.show()
# Compare skewness
print("Skewness:")
print(f"Original: {df['Value'].skew():.2f}")
print(f"Square: {df['Square'].skew():.2f}")
print(f"Cube: {df['Cube'].skew():.2f}")
print(f"Square Root: {df['SquareRoot'].skew():.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas y generación de números aleatorios
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Generar 1000 valores aleatorios entre 1 y 100 usando np.random.uniform()
- Almacenar los datos en un DataFrame de pandas
- Aplicar transformaciones de potencia:
- Transformación cuadrada:
df['Value'] ** 2
- Transformación cúbica:
df['Value'] ** 3
- Transformación de raíz cuadrada:
np.sqrt(df['Value'])
- Transformación cuadrada:
- Visualizar las distribuciones:
- Crear una cuadrícula de subgráficos de 2x2
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para cada distribución
- Establecer títulos apropiados para cada subgráfico
- Comparar asimetría:
- Calcular e imprimir la asimetría de cada distribución usando el método skew()
Este ejemplo muestra cómo las diferentes transformaciones de potencia afectan la distribución de los datos. Las transformaciones cuadrada y cúbica tienden a enfatizar valores más grandes y pueden aumentar la asimetría hacia la derecha, mientras que la transformación de raíz cuadrada puede ayudar a reducir la asimetría hacia la derecha y comprimir el rango de los valores más grandes.
Transformación de Box-Cox
Una familia versátil de transformaciones de potencia que incluye el logaritmo como caso especial. Esta transformación es particularmente útil para estabilizar la varianza y hacer que las distribuciones de datos se parezcan más a una normal. La transformación de Box-Cox se define por un parámetro λ (lambda), que determina el tipo específico de transformación aplicada a los datos. Cuando λ = 0, se vuelve equivalente a la transformación logarítmica natural.
Características clave de la transformación de Box-Cox incluyen:
- Flexibilidad: Al ajustar el parámetro λ, puede manejar una amplia gama de distribuciones de datos.
- Estabilización de la varianza: Ayuda a lograr homocedasticidad, una suposición clave en muchos modelos estadísticos.
- Normalización: Puede hacer que los datos sesgados sean más simétricos, aproximándose a una distribución normal.
- Mejora del rendimiento del modelo: Al abordar la no linealidad y la no normalidad, puede mejorar el rendimiento de varios modelos estadísticos y de Machine Learning.
Al aplicar la transformación de Box-Cox, es importante tener en cuenta que requiere que todos los valores sean positivos. Para conjuntos de datos con valores cero o negativos, puede ser necesario agregar una constante antes de la transformación. Además, el valor óptimo de λ puede determinarse mediante estimación de máxima verosimilitud, lo que permite una selección basada en datos de la transformación más adecuada.
Ejemplo: Transformación de Box-Cox
Demostraremos cómo aplicar la transformación de Box-Cox a un conjunto de datos y visualizar los resultados.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
# Generate sample data with a right-skewed distribution
np.random.seed(42)
data = np.random.lognormal(mean=0, sigma=0.5, size=1000)
# Create a DataFrame
df = pd.DataFrame({'original': data})
# Apply Box-Cox transformation
df['box_cox'], lambda_param = stats.boxcox(df['original'])
# Visualize the original and transformed distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.hist(df['original'], bins=30, edgecolor='black')
ax1.set_title('Original Distribution')
ax1.set_xlabel('Value')
ax1.set_ylabel('Frequency')
ax2.hist(df['box_cox'], bins=30, edgecolor='black')
ax2.set_title(f'Box-Cox Transformed (λ = {lambda_param:.2f})')
ax2.set_xlabel('Value')
ax2.set_ylabel('Frequency')
plt.tight_layout()
plt.show()
# Print summary statistics
print("Original Data:")
print(df['original'].describe())
print("\nBox-Cox Transformed Data:")
print(df['box_cox'].describe())
# Print skewness
print(f"\nOriginal Skewness: {df['original'].skew():.2f}")
print(f"Box-Cox Transformed Skewness: {df['box_cox'].skew():.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas y generación de números aleatorios
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones
- scipy.stats: Para la función de transformación de Box-Cox
- Generar datos de muestra:
- Usar np.random.lognormal() para crear una distribución sesgada hacia la derecha
- Almacenar los datos en un DataFrame de pandas
- Aplicar la transformación de Box-Cox:
- Usar stats.boxcox() para transformar los datos
- Esta función devuelve los datos transformados y el valor óptimo de lambda
- Visualizar las distribuciones:
- Crear dos subgráficos uno al lado del otro
- Graficar histogramas de los datos originales y transformados
- Establecer títulos y etiquetas apropiados
- Imprimir estadísticas descriptivas y asimetría:
- Usar describe() para obtener estadísticas descriptivas de los datos originales y transformados
- Calcular e imprimir la asimetría de ambas distribuciones usando skew()
Este ejemplo muestra cómo la transformación de Box-Cox puede normalizar una distribución sesgada hacia la derecha. El valor óptimo de lambda se determina automáticamente, y la transformación reduce significativamente la asimetría de los datos. Esto puede ser particularmente útil para preparar datos para modelos de Machine Learning que asumen características distribuidas normalmente.
Estas transformaciones cumplen múltiples propósitos en el proceso de ingeniería de características:
- Normalizar distribuciones de datos: Muchos métodos estadísticos y algoritmos de Machine Learning asumen datos distribuidos normalmente. Las transformaciones pueden ayudar a aproximar esta condición.
- Estabilizar la varianza: Algunos modelos, como la regresión lineal, asumen una varianza constante en todo el rango de las variables predictoras. Las transformaciones pueden ayudar a cumplir con esta suposición.
- Simplificar relaciones no lineales: Al aplicar la transformación adecuada, relaciones complejas no lineales pueden a veces convertirse en lineales, haciéndolas más fáciles de aprender para los modelos.
- Reducir el impacto de los valores atípicos: Las transformaciones como el logaritmo pueden comprimir la escala de una variable, reduciendo la influencia de valores extremos.
Al aplicar estas transformaciones, es crucial considerar la naturaleza de tus datos y las suposiciones de tu modelo elegido. Siempre valida el impacto de las transformaciones a través del análisis exploratorio de datos y métricas de rendimiento del modelo. Recuerda que, si bien las transformaciones pueden ser poderosas, también pueden afectar la interpretabilidad de tu modelo, así que úsalas con prudencia y documenta tu enfoque minuciosamente.
7.1.2 Extracción de características de fecha y hora
Al trabajar con conjuntos de datos que contienen características de fecha o tiempo, puedes mejorar significativamente el poder predictivo de tu modelo al extraer nuevas características significativas. Este proceso implica desglosar columnas de fecha y hora en sus partes constituyentes, como año, mes, día de la semana o hora. Estas características extraídas pueden capturar patrones temporales importantes y estacionalidad en tus datos.
Por ejemplo, en un conjunto de datos de ventas minoristas, extraer el mes y el día de la semana a partir de una fecha de venta podría revelar ciclos mensuales de ventas o patrones de compras semanales. De manera similar, para datos relacionados con el clima, el mes y el día podrían ayudar a capturar variaciones estacionales. En series temporales financieras, el año y el trimestre podrían ser cruciales para identificar tendencias a largo plazo y patrones cíclicos.
Además, puedes crear características más complejas basadas en el tiempo, como:
- ¿Es fin de semana o día laboral?
- ¿En qué trimestre del año?
- ¿Es un día festivo?
- ¿Número de días desde un evento específico?
Estas características derivadas pueden proporcionar información valiosa sobre fenómenos dependientes del tiempo, permitiendo que tu modelo capture patrones matizados que podrían no ser evidentes en los datos crudos de fecha y hora. Al incorporar estos aspectos temporales, puedes mejorar significativamente la capacidad de tu modelo para predecir resultados influenciados por tendencias estacionales, patrones cíclicos u otros factores basados en el tiempo.
Ejemplo: Extracción de componentes de fecha para crear nuevas características
Supongamos que tenemos un conjunto de datos que incluye una columna con la fecha de una venta de una casa. Podemos extraer nuevas características como YearSold, MonthSold y DayOfWeekSold para capturar tendencias temporales que pueden influir en los precios de las casas.
# Sample data with a date column
data = {
'SaleDate': ['2021-01-15', '2020-07-22', '2021-03-01', '2019-10-10', '2022-12-31'],
'Price': [250000, 300000, 275000, 225000, 350000]
}
df = pd.DataFrame(data)
# Convert the SaleDate column to a datetime object
df['SaleDate'] = pd.to_datetime(df['SaleDate'])
# Extract new features from the SaleDate column
df['YearSold'] = df['SaleDate'].dt.year
df['MonthSold'] = df['SaleDate'].dt.month
df['DayOfWeekSold'] = df['SaleDate'].dt.dayofweek
df['QuarterSold'] = df['SaleDate'].dt.quarter
df['IsWeekend'] = df['SaleDate'].dt.dayofweek.isin([5, 6]).astype(int)
df['DaysSince2019'] = (df['SaleDate'] - pd.Timestamp('2019-01-01')).dt.days
# Create a season column
df['Season'] = pd.cut(df['MonthSold'],
bins=[0, 3, 6, 9, 12],
labels=['Winter', 'Spring', 'Summer', 'Fall'],
include_lowest=True)
# View the new features
print(df)
# Analyze the relationship between time features and price
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(12, 6))
sns.scatterplot(data=df, x='DaysSince2019', y='Price', hue='Season')
plt.title('House Prices Over Time')
plt.show()
# Calculate average price by year and month
avg_price = df.groupby(['YearSold', 'MonthSold'])['Price'].mean().unstack()
plt.figure(figsize=(12, 6))
sns.heatmap(avg_price, annot=True, fmt='.0f', cmap='YlOrRd')
plt.title('Average House Price by Year and Month')
plt.show()
Este ejemplo de código muestra un enfoque completo para extraer y analizar características basadas en fechas de un conjunto de datos. Vamos a desglosar el código y su funcionalidad:
- Creación y Preprocesamiento de Datos:
- Creamos un conjunto de datos de muestra con las columnas 'SaleDate' y 'Price'.
- La columna 'SaleDate' se convierte en un objeto datetime usando pd.to_datetime().
- Extracción de Características:
- Componentes básicos de la fecha: Se extraen el año, el mes y el día de la semana.
- Trimestre: Se extrae el trimestre del año usando dt.quarter.
- IsWeekend: Se crea una característica binaria para indicar si la venta ocurrió en un fin de semana.
- DaysSince2019: Esta característica calcula el número de días desde el 1 de enero de 2019, lo cual puede ser útil para capturar tendencias a largo plazo.
- Season: Se crea una característica categórica utilizando pd.cut() para agrupar los meses en estaciones.
- Visualización de Datos:
- Se crea un gráfico de dispersión para visualizar la relación entre el número de días desde 2019 y el precio de la casa, con los puntos coloreados por estación.
- Se genera un mapa de calor para mostrar el precio promedio de la casa por año y mes, lo que puede revelar patrones estacionales en los precios de las viviendas.
Este ejemplo completo demuestra varias técnicas para extraer características significativas de los datos de fecha y visualizarlos para obtener información. Dicha ingeniería de características puede mejorar significativamente el poder predictivo de los modelos de Machine Learning que trabajan con datos de series temporales.
7.1.3 Combinación de Características
La combinación de múltiples características existentes puede crear nuevas características poderosas que capturen relaciones complejas entre variables. Este proceso, conocido como interacción de características o cruzamiento de características, va más allá de las combinaciones lineales simples y puede revelar patrones no lineales en los datos. Al multiplicar, dividir o tomar razones de características existentes, podemos generar nuevos conocimientos que las características individuales podrían no captar por sí solas.
Por ejemplo, en un conjunto de datos con información sobre casas, podrías crear una nueva característica que represente el precio por pie cuadrado dividiendo el precio de la casa por su tamaño en pies cuadrados. Esta característica derivada normaliza el precio en función del tamaño de la casa, revelando potencialmente patrones que ni el precio ni el tamaño por sí solos podrían mostrar. Otros ejemplos podrían incluir:
- Combinar 'número de habitaciones' y 'tamaño total en pies cuadrados' para crear una característica de 'tamaño promedio de habitación'
- Multiplicar 'edad de la casa' por 'número de renovaciones' para capturar el impacto de las actualizaciones en propiedades más antiguas
- Crear una razón de 'tamaño del terreno' a 'tamaño de la casa' para representar la proporción de tierra respecto a la construcción
Estas características combinadas pueden mejorar significativamente la capacidad de un modelo para capturar relaciones matizadas en los datos, mejorando potencialmente su poder predictivo e interpretabilidad. Sin embargo, es importante abordar la combinación de características de manera reflexiva, ya que la creación indiscriminada de nuevas características puede llevar al sobreajuste o aumentar la complejidad del modelo sin obtener ganancias correspondientes en el rendimiento.
Ejemplo: Creación de una Nueva Característica a partir de la Razón de Dos Características
Supongamos que tenemos un conjunto de datos con precios de casas y tamaños de casas (en pies cuadrados). Podemos crear una nueva característica, PricePerSqFt, para normalizar los precios de las casas en función de su tamaño.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {
'HousePrice': [500000, 700000, 600000, 550000, 800000],
'HouseSize': [2000, 3000, 2500, 1800, 3500],
'Bedrooms': [3, 4, 3, 2, 5],
'YearBuilt': [1990, 2005, 2000, 1985, 2010]
}
df = pd.DataFrame(data)
# Create new features
df['PricePerSqFt'] = df['HousePrice'] / df['HouseSize']
df['AvgRoomSize'] = df['HouseSize'] / df['Bedrooms']
df['AgeOfHouse'] = 2023 - df['YearBuilt']
df['PricePerRoom'] = df['HousePrice'] / df['Bedrooms']
# View the new features
print(df)
# Visualize relationships
plt.figure(figsize=(12, 8))
# Scatter plot of Price vs Size, colored by Age
plt.subplot(2, 2, 1)
sns.scatterplot(data=df, x='HouseSize', y='HousePrice', hue='AgeOfHouse', palette='viridis')
plt.title('House Price vs Size (colored by Age)')
# Bar plot of Average Price per Sq Ft by Bedrooms
plt.subplot(2, 2, 2)
sns.barplot(data=df, x='Bedrooms', y='PricePerSqFt')
plt.title('Avg Price per Sq Ft by Bedrooms')
# Heatmap of correlations
plt.subplot(2, 2, 3)
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
# Scatter plot of Price per Room vs Age of House
plt.subplot(2, 2, 4)
sns.scatterplot(data=df, x='AgeOfHouse', y='PricePerRoom')
plt.title('Price per Room vs Age of House')
plt.tight_layout()
plt.show()
# Statistical summary
print(df.describe())
# Correlation analysis
print(df.corr()['HousePrice'].sort_values(ascending=False))
Este ejemplo de código muestra un enfoque completo para la ingeniería de características y el análisis exploratorio de datos. Vamos a profundizar en sus componentes:
- Preparación de Datos:
- Importamos las bibliotecas necesarias: pandas para la manipulación de datos, matplotlib y seaborn para visualización.
- Se expande el conjunto de datos de muestra para incluir más casas y características adicionales como 'Bedrooms' y 'YearBuilt'.
- Ingeniería de Características:
- PricePerSqFt: Normaliza el precio de la casa según el tamaño.
- AvgRoomSize: Calcula el tamaño promedio de las habitaciones.
- AgeOfHouse: Determina la antigüedad de la casa (asumiendo que el año actual es 2023).
- PricePerRoom: Calcula el precio por dormitorio.
- Visualización de Datos:
- Se crea una cuadrícula de 2x2 gráficos para visualizar diferentes aspectos de los datos:
a) Diagrama de dispersión de House Price vs. Size, coloreado por Age.
b) Gráfico de barras que muestra el precio promedio por pie cuadrado para diferentes cantidades de dormitorios.
c) Mapa de calor de correlaciones entre todas las características.
d) Diagrama de dispersión de Price per Room vs. Age of House.
- Se crea una cuadrícula de 2x2 gráficos para visualizar diferentes aspectos de los datos:
- Análisis Estadístico:
- La función describe() proporciona estadísticas descriptivas para todas las columnas numéricas.
- El análisis de correlación muestra qué tan fuerte se correlaciona cada característica con HousePrice.
Este ejemplo completo no solo crea nuevas características, sino que también explora sus relaciones y posibles impactos en los precios de las viviendas. Las visualizaciones y análisis estadísticos proporcionan información que puede guiar en la ingeniería de características o en los procesos de selección de modelos.
7.1.4 Creación de Términos de Interacción
Los términos de interacción son características que capturan el efecto combinado de dos o más variables, ofreciendo una forma poderosa de modelar relaciones complejas en los datos. Estos términos van más allá de las combinaciones lineales simples, permitiendo la representación de interacciones no lineales entre características. Por ejemplo, en el modelado inmobiliario, la interacción entre el tamaño de una casa y su ubicación podría ser más predictiva de su precio que cualquiera de las características por sí sola. Esto se debe a que el valor de metros cuadrados adicionales puede variar significativamente según el vecindario.
Los términos de interacción son especialmente valiosos cuando hay una relación no lineal entre las características y la variable objetivo. Pueden revelar patrones que las características individuales podrían pasar por alto. Por ejemplo, en un contexto de marketing, la interacción entre la edad de un cliente y sus ingresos podría proporcionar información sobre el comportamiento de compra que ni la edad ni los ingresos podrían captar por sí solos. De manera similar, en estudios ambientales, la interacción entre temperatura y humedad podría ser crucial para predecir ciertos fenómenos meteorológicos.
Crear términos de interacción implica multiplicar dos o más características entre sí. Este proceso permite que el modelo aprenda diferentes efectos para una variable en función de los valores de otra. Es importante tener en cuenta que, aunque los términos de interacción pueden mejorar significativamente el rendimiento del modelo, deben usarse con moderación. Agregar demasiados términos de interacción puede llevar al sobreajuste y hacer que el modelo sea más difícil de interpretar. Por lo tanto, es crucial basar la creación de términos de interacción en el conocimiento del dominio o en el análisis exploratorio de datos para asegurarse de que agreguen un valor significativo al modelo.
Ejemplo: Creación de Términos de Interacción
Supongamos que queremos explorar la interacción entre el precio de una casa y el año en que se vendió. Podemos crear un término de interacción multiplicando estas dos características entre sí.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {
'HousePrice': [500000, 700000, 600000, 550000, 800000],
'YearSold': [2020, 2019, 2021, 2020, 2022],
'SquareFootage': [2000, 2500, 2200, 1800, 3000],
'Bedrooms': [3, 4, 3, 2, 5]
}
df = pd.DataFrame(data)
# Create interaction terms
df['Price_YearInteraction'] = df['HousePrice'] * df['YearSold']
df['Price_SqFtInteraction'] = df['HousePrice'] * df['SquareFootage']
df['PricePerSqFt'] = df['HousePrice'] / df['SquareFootage']
df['PricePerBedroom'] = df['HousePrice'] / df['Bedrooms']
# View the dataframe with new features
print(df)
# Visualize relationships
plt.figure(figsize=(12, 10))
# Scatter plot of Price vs Year, sized by SquareFootage
plt.subplot(2, 2, 1)
sns.scatterplot(data=df, x='YearSold', y='HousePrice', size='SquareFootage', hue='Bedrooms')
plt.title('House Price vs Year Sold')
# Heatmap of correlations
plt.subplot(2, 2, 2)
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
# Scatter plot of Price_YearInteraction vs PricePerSqFt
plt.subplot(2, 2, 3)
sns.scatterplot(data=df, x='Price_YearInteraction', y='PricePerSqFt')
plt.title('Price-Year Interaction vs Price Per Sq Ft')
# Bar plot of average Price Per Bedroom by Year
plt.subplot(2, 2, 4)
sns.barplot(data=df, x='YearSold', y='PricePerBedroom')
plt.title('Avg Price Per Bedroom by Year')
plt.tight_layout()
plt.show()
# Statistical summary
print(df.describe())
# Correlation analysis
print(df.corr()['HousePrice'].sort_values(ascending=False))
Este ejemplo de código demuestra un enfoque completo para crear y analizar términos de interacción en el contexto inmobiliario.
Desglosemos cada parte:
- Preparación de Datos:
- Importamos las bibliotecas necesarias: pandas para la manipulación de datos, matplotlib y seaborn para visualización.
- El conjunto de datos de muestra se expande para incluir más casas y características adicionales como 'SquareFootage' y 'Bedrooms'.
- Ingeniería de Características:
- Price_YearInteraction: Captura la interacción entre el precio de la casa y el año en que se vendió.
- Price_SqFtInteraction: Representa la interacción entre el precio y los pies cuadrados.
- PricePerSqFt: Una característica de razón que normaliza el precio por tamaño.
- PricePerBedroom: Otra característica de razón que muestra el precio por dormitorio.
- Visualización de Datos:
- Se crea una cuadrícula de gráficos 2x2 para visualizar diferentes aspectos de los datos:
a) Diagrama de dispersión de House Price vs. Year Sold, con el tamaño de los puntos representando los pies cuadrados y el color representando el número de dormitorios.
b) Mapa de calor de correlaciones entre todas las características.
c) Diagrama de dispersión de Price-Year Interaction vs. Price Per Sq Ft.
d) Gráfico de barras que muestra el precio promedio por dormitorio en diferentes años.
- Se crea una cuadrícula de gráficos 2x2 para visualizar diferentes aspectos de los datos:
- Análisis Estadístico:
- La función describe() proporciona estadísticas descriptivas para todas las columnas numéricas.
- El análisis de correlación muestra qué tan fuerte se correlaciona cada característica con HousePrice.
Este ejemplo completo no solo crea términos de interacción, sino que también explora sus relaciones con otras características y la variable objetivo (HousePrice). Las visualizaciones y análisis estadísticos proporcionan información que puede guiar en la ingeniería de características o en los procesos de selección de modelos. Por ejemplo, el mapa de calor de correlación puede revelar qué términos de interacción están más fuertemente asociados con los precios de las viviendas, mientras que los gráficos de dispersión pueden mostrar relaciones no lineales que estos términos podrían captar.
7.1.5 Conclusiones Clave y Sus Implicaciones
- Transformaciones matemáticas (como logarítmica o de raíz cuadrada) pueden ayudar a estabilizar la varianza o reducir la asimetría en los datos, mejorando el rendimiento de ciertos modelos de Machine Learning. Estas transformaciones son particularmente útiles cuando se trabaja con características que muestran crecimiento o decaimiento exponencial, o cuando la relación entre variables es no lineal.
- Extracción de características de fecha y hora permite crear nuevas características significativas a partir de columnas de fecha y hora, permitiendo que los modelos capturen patrones estacionales o basados en el tiempo. Esta técnica es crucial para el análisis de series temporales, pronósticos y comprensión de tendencias cíclicas en los datos. Por ejemplo, extraer el día de la semana, el mes o la estación puede revelar patrones importantes en ventas minoristas o consumo de energía.
- Combinación de características como razones o diferencias entre variables existentes puede descubrir relaciones importantes, como normalizar los precios de viviendas por tamaño. Estas características derivadas suelen proporcionar más información interpretativa y significativa que los datos sin procesar. Por ejemplo, en análisis financieros, razones como precio/ganancias o deuda/capital son más informativas que los componentes individuales por sí solos.
- Términos de interacción permiten que el modelo capture los efectos combinados de dos o más características, lo cual puede ser especialmente útil cuando las relaciones entre variables son no lineales. Estos términos pueden mejorar significativamente el rendimiento del modelo al considerar interdependencias complejas. Por ejemplo, en marketing, la interacción entre la edad del cliente y sus ingresos podría predecir mejor el comportamiento de compra que cualquiera de las variables por separado.
Comprender y aplicar estas técnicas de ingeniería de características puede mejorar drásticamente el rendimiento, la interpretabilidad y la robustez de los modelos. Sin embargo, es crucial abordar la creación de características de manera reflexiva, siempre considerando el conocimiento del dominio y los requisitos específicos de la tarea de Machine Learning. La ingeniería de características efectiva requiere una combinación de creatividad, comprensión estadística y experiencia en el dominio.
7.1 Creación de Nuevas Características a partir de Datos Existentes
La creación de nuevas características es una de las técnicas más poderosas para mejorar los modelos de Machine Learning. Este proceso, conocido como ingeniería de características, implica derivar nuevas variables a partir de datos existentes para capturar relaciones complejas, patrones e información que pueden no ser evidentes de inmediato en el conjunto de datos original. Al hacerlo, los científicos de datos pueden mejorar significativamente la precisión, robustez e interpretabilidad de los modelos.
La creación de características puede tomar muchas formas, incluyendo:
- Transformaciones matemáticas (por ejemplo, logarítmica, polinómica)
- Agregaciones (por ejemplo, media, mediana, suma de múltiples características)
- Binning o discretización de variables continuas
- Codificación de variables categóricas
- Creación de características específicas de dominio basadas en el conocimiento experto
En este capítulo, profundizaremos en el proceso de creación de características y exploraremos varias técnicas para combinar características existentes de manera significativa. Comenzaremos examinando métodos para derivar nuevas características a partir de datos existentes, como la extracción de fecha/hora, el análisis de texto y el procesamiento de información geográfica. Luego, avanzaremos hacia conceptos más avanzados, incluyendo los términos de interacción, que capturan los efectos combinados de múltiples características.
Al dominar estas técnicas, podrás extraer más valor de tus datos, descubriendo potencialmente patrones y relaciones ocultas que pueden dar a tus modelos una ventaja significativa en rendimiento predictivo y capacidad de generalización.
La creación de características es un paso crítico en el flujo de trabajo de la ciencia de datos, que implica la generación de nuevas características informativas a partir de datos existentes. Este proceso requiere no solo habilidades técnicas, sino también una comprensión profunda del dominio y del problema específico que se está abordando. Al crear nuevas características, los científicos de datos pueden descubrir patrones ocultos, simplificar relaciones complejas y reducir el ruido en el conjunto de datos, mejorando en última instancia el rendimiento y la interpretabilidad de los modelos de Machine Learning.
El arte de la creación de características a menudo implica pensamiento creativo y experimentación. Puede incluir técnicas tales como:
- Aplicar funciones matemáticas a características existentes
- Extraer información de tipos de datos complejos como fechas, texto o coordenadas geográficas
- Combinar múltiples características para crear representaciones más informativas
- Codificar variables categóricas de formas que capturen sus propiedades inherentes
- Aprovechar la experiencia del dominio para crear características que reflejen relaciones del mundo real
En esta sección, profundizaremos en varios métodos para la creación de características, comenzando con transformaciones matemáticas básicas y avanzando hacia técnicas más avanzadas. Exploraremos cómo extraer información significativa de datos de fecha y hora, lo cual puede ser crucial para capturar patrones temporales y estacionalidad. Además, discutiremos estrategias para combinar características y crear predictores más poderosos, incluyendo la creación de términos de interacción que capturen la interacción entre diferentes variables.
Al dominar estas técnicas, estarás mejor equipado para extraer el máximo valor de tus datos, descubriendo potencialmente ideas que no eran evidentes en el conjunto de datos original. Esto puede conducir a predicciones más precisas, mejor toma de decisiones y una comprensión más profunda de los patrones subyacentes en tus datos.
7.1.1 Transformaciones Matemáticas
Una de las técnicas fundamentales para crear nuevas características es aplicar transformaciones matemáticas a las características numéricas existentes. Estas transformaciones pueden mejorar significativamente la calidad y utilidad de tus datos para los modelos de Machine Learning. Las transformaciones comunes incluyen:
Transformación logarítmica
Esta técnica poderosa es particularmente efectiva para manejar distribuciones sesgadas hacia la derecha y comprimir amplios rangos de valores. Al aplicar la función logarítmica a los datos, podemos:
- Linearizar relaciones exponenciales, haciéndolas más fáciles de interpretar para los modelos
- Reducir el impacto de los valores atípicos, especialmente en conjuntos de datos con valores extremos
- Normalizar datos que abarcan varios órdenes de magnitud
- Mejorar el rendimiento de modelos que asumen datos distribuidos normalmente
Las transformaciones logarítmicas se aplican comúnmente en varios campos:
- Finanzas: Para analizar precios de acciones, rendimientos y otros métricas financieras
- Economía: Al tratar con PIB, crecimiento poblacional o tasas de inflación
- Biología: En el estudio del crecimiento bacteriano o cinética enzimática
- Física: Para analizar fenómenos como la intensidad del sonido o la magnitud de terremotos
Al aplicar transformaciones logarítmicas, es importante considerar:
- La base del logaritmo (logaritmo natural, base 10, etc.) y su impacto en la interpretación
- Manejo de valores cero o negativos, que pueden requerir agregar una constante antes de la transformación
- El efecto en la interpretabilidad del modelo y la necesidad de revertir la transformación de las predicciones
Ejemplo: Transformación Logarítmica para Crear una Nueva Característica
Supongamos que tenemos un conjunto de datos que contiene precios de casas, y sospechamos que la distribución de los precios está sesgada. Para reducir el sesgo y hacer la distribución más normal, podemos crear una nueva característica aplicando una transformación logarítmica a los precios originales.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'HousePrice': [50000, 120000, 250000, 500000, 1200000, 2500000]}
df = pd.DataFrame(data)
# Create a new feature by applying a logarithmic transformation
df['LogHousePrice'] = np.log(df['HousePrice'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(df['HousePrice'], kde=True, ax=ax1)
ax1.set_title('Distribution of Original House Prices')
ax1.set_xlabel('House Price')
sns.histplot(df['LogHousePrice'], kde=True, ax=ax2)
ax2.set_title('Distribution of Log-Transformed House Prices')
ax2.set_xlabel('Log(House Price)')
plt.tight_layout()
plt.show()
# Compare skewness
original_skew = df['HousePrice'].skew()
log_skew = df['LogHousePrice'].skew()
print(f"\nSkewness of original prices: {original_skew:.2f}")
print(f"Skewness of log-transformed prices: {log_skew:.2f}")
Este ejemplo de código demuestra el proceso de aplicar una transformación logarítmica a datos de precios de viviendas y analizar sus efectos.
Aquí tienes un desglose completo del código y su propósito:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización de datos estadísticos
- Crear datos de muestra:
- Un diccionario con una sola clave "HousePrice" y una lista de precios de viviendas como valores
- Convertir el diccionario en un DataFrame de pandas
- Aplicar transformación logarítmica:
- Crear una nueva columna "LogHousePrice" aplicando np.log() a la columna "HousePrice"
- Esta transformación ayuda a reducir la asimetría de los datos y a comprimir el rango de valores
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los precios originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas como la cantidad, media, desviación estándar, mínimo, máximo y cuartiles para ambas columnas
- Visualizar las distribuciones:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para los precios originales y transformados
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos utilizando plt.show()
- Comparar asimetría:
- Calcular la asimetría de las distribuciones de precios originales y transformados usando el método skew()
- Imprimir los valores de asimetría
Este ejemplo completo no solo aplica la transformación logarítmica, sino que también proporciona evidencia visual y estadística de sus efectos. Al comparar las distribuciones originales y transformadas, podemos observar cómo la transformación logarítmica ayuda a normalizar los datos, lo que potencialmente los hace más adecuados para diversos análisis estadísticos y modelos de Machine Learning.
Transformación de raíz cuadrada
Esta transformación es menos extrema que la logarítmica, pero aún es efectiva para reducir la asimetría hacia la derecha. Es particularmente útil para datos de conteo o cuando se enfrenta a una asimetría moderada hacia la derecha. La función de raíz cuadrada comprime el extremo superior de la distribución mientras expande el extremo inferior, lo que la hace ideal para datos que no requieren un cambio tan drástico como la transformación logarítmica.
Los principales beneficios de la transformación de raíz cuadrada incluyen:
- Reducir el impacto de los valores atípicos sin eliminarlos completamente
- Mejorar la normalidad de distribuciones con asimetría positiva
- Estabilizar la varianza en datos de conteo, especialmente cuando la varianza aumenta con la media
- Mantener una relación más intuitiva con los datos originales en comparación con la transformación logarítmica
Al aplicar transformaciones de raíz cuadrada, considera:
- La necesidad de manejar valores cero, lo que puede requerir agregar una pequeña constante antes de la transformación
- El efecto en valores negativos, que puede requerir tratamiento especial o transformaciones alternativas
- El impacto en la interpretabilidad del modelo y la posible necesidad de revertir la transformación de las predicciones
Las transformaciones de raíz cuadrada se utilizan comúnmente en varios campos, incluyendo:
- Ecología: Para analizar datos de abundancia de especies
- Psicología: Al trabajar con datos de tiempo de reacción
- Control de calidad: Para analizar el conteo de defectos en procesos de fabricación
Ejemplo: Transformación de raíz cuadrada para crear una nueva característica
Consideremos un conjunto de datos que contiene el número de defectos encontrados en productos manufacturados. Aplicaremos una transformación de raíz cuadrada a estos datos para reducir la asimetría hacia la derecha y estabilizar la varianza.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'DefectCount': [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]}
df = pd.DataFrame(data)
# Create a new feature by applying a square root transformation
df['SqrtDefectCount'] = np.sqrt(df['DefectCount'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(df['DefectCount'], kde=True, ax=ax1)
ax1.set_title('Distribution of Original Defect Counts')
ax1.set_xlabel('Defect Count')
sns.histplot(df['SqrtDefectCount'], kde=True, ax=ax2)
ax2.set_title('Distribution of Square Root Transformed Defect Counts')
ax2.set_xlabel('Square Root of Defect Count')
plt.tight_layout()
plt.show()
# Compare skewness
original_skew = df['DefectCount'].skew()
sqrt_skew = df['SqrtDefectCount'].skew()
print(f"\nSkewness of original counts: {original_skew:.2f}")
print(f"Skewness of square root transformed counts: {sqrt_skew:.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Un diccionario con una sola clave "DefectCount" y una lista de conteos de defectos como valores
- Convertir el diccionario en un DataFrame de pandas
- Aplicar la transformación de raíz cuadrada:
- Crear una nueva columna "SqrtDefectCount" aplicando np.sqrt() a la columna "DefectCount"
- Esta transformación ayuda a reducir la asimetría de los datos y a estabilizar la varianza
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los conteos de defectos originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas como cantidad, media, desviación estándar, mínimo, máximo y cuartiles para ambas columnas
- Visualizar las distribuciones:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para los conteos de defectos originales y transformados por raíz cuadrada
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos usando plt.show()
- Comparar la asimetría:
- Calcular la asimetría de las distribuciones de conteo de defectos originales y transformados por raíz cuadrada usando el método skew()
- Imprimir los valores de asimetría
Este ejemplo muestra cómo aplicar una transformación de raíz cuadrada a un conjunto de datos, visualizar los resultados y comparar la asimetría de los datos originales y transformados. La transformación de raíz cuadrada puede ser particularmente efectiva para datos de conteo, ayudando a estabilizar la varianza y reducir la asimetría hacia la derecha.
Transformación exponencial:
Esta técnica poderosa puede usarse para amplificar diferencias entre valores o para manejar distribuciones con asimetría hacia la izquierda. A diferencia de las transformaciones logarítmicas, que comprimen valores grandes, las transformaciones exponenciales los expanden, lo que hace que este método sea particularmente útil cuando:
- Quieres enfatizar las diferencias entre valores más altos en tu conjunto de datos
- Tus datos muestran una distribución con asimetría hacia la izquierda (negativa) que necesita ser equilibrada
- Estás trabajando con variables donde los cambios pequeños en valores altos son más significativos que en valores bajos
Aplicaciones comunes de las transformaciones exponenciales incluyen:
- Modelado financiero: Para calcular interés compuesto o tasas de crecimiento
- Dinámica de poblaciones: Al modelar patrones de crecimiento exponencial
- Procesamiento de señales: Para amplificar ciertos componentes de frecuencia
Al aplicar transformaciones exponenciales, es crucial considerar:
- La base de la función exponencial y su impacto en la escala de la transformación
- La posibilidad de crear valores atípicos extremos, lo cual puede requerir manejo adicional
- El efecto en la interpretabilidad del modelo y la necesidad de una cuidadosa transformación inversa de las predicciones
Ejemplo: Transformación Exponencial para Crear una Nueva Característica
Consideremos un conjunto de datos que contiene valores que queremos enfatizar o amplificar. Aplicaremos una transformación exponencial a estos datos para crear una nueva característica que resalte las diferencias entre valores más altos.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'Value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
df = pd.DataFrame(data)
# Create a new feature by applying an exponential transformation
df['ExpValue'] = np.exp(df['Value'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.scatterplot(x='Value', y='ExpValue', data=df, ax=ax1)
ax1.set_title('Original vs Exponential Values')
ax1.set_xlabel('Original Value')
ax1.set_ylabel('Exponential Value')
sns.lineplot(x='Value', y='Value', data=df, ax=ax2, label='Original')
sns.lineplot(x='Value', y='ExpValue', data=df, ax=ax2, label='Exponential')
ax2.set_title('Comparison of Original and Exponential Values')
ax2.set_xlabel('Value')
ax2.set_ylabel('Transformed Value')
ax2.legend()
plt.tight_layout()
plt.show()
# Compare ranges
original_range = df['Value'].max() - df['Value'].min()
exp_range = df['ExpValue'].max() - df['ExpValue'].min()
print(f"\nRange of original values: {original_range:.2f}")
print(f"Range of exponential transformed values: {exp_range:.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Un diccionario con una sola clave "Value" y una lista de valores del 1 al 10
- Convertir el diccionario en un DataFrame de pandas
- Aplicar la transformación exponencial:
- Crear una nueva columna "ExpValue" aplicando np.exp() a la columna "Value"
- Esta transformación amplifica exponencialmente los valores originales
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los valores originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas para ambas columnas
- Visualizar los datos:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar scatterplot() de seaborn para mostrar la relación entre los valores originales y exponenciales
- Usar lineplot() de seaborn para comparar el crecimiento de los valores originales y exponenciales
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos usando plt.show()
- Comparar los rangos:
- Calcular el rango (máximo - mínimo) para ambos valores, originales y transformados exponencialmente
- Imprimir los rangos para mostrar cómo la transformación exponencial ha amplificado las diferencias
Transformaciones de potencia
Incluyen cuadrado, cubo o potencias más altas. Estas transformaciones pueden ser particularmente efectivas para enfatizar valores mayores o capturar relaciones no lineales en tus datos. Aquí tienes una visión más detallada de las transformaciones de potencia:
- Transformación cuadrada (x²): Puede ser útil cuando deseas enfatizar diferencias entre valores grandes mientras comprimes las diferencias entre valores pequeños. A menudo se usa en análisis estadísticos y modelos de Machine Learning para capturar relaciones cuadráticas.
- Transformación cúbica (x³): Esta transformación amplifica aún más las diferencias que la cuadrada. Puede ser especialmente útil al tratar con variables donde pequeños cambios en valores altos son mucho más significativos que en valores bajos.
- Potencias más altas (x⁴, x⁵, etc.): Estas pueden usarse para capturar relaciones no lineales cada vez más complejas. Sin embargo, ten precaución al usar potencias muy altas, ya que pueden llevar a inestabilidad numérica y sobreajuste.
- Potencias fraccionarias (√x, ³√x, etc.): Son menos comunes, pero pueden ser valiosas en ciertos escenarios. Por ejemplo, una transformación de raíz cúbica puede ser útil para manejar valores atípicos extremos mientras mantiene parte de la escala original.
Al aplicar transformaciones de potencia, considera lo siguiente:
- La naturaleza de tus datos y el problema específico que estás intentando resolver. Diferentes transformaciones de potencia pueden ser más o menos apropiadas según tu conjunto de datos y objetivos.
- La posibilidad de crear o agravar valores atípicos, especialmente con potencias altas. Puede ser necesario manejar cuidadosamente los valores extremos.
- El impacto en la interpretabilidad del modelo. Las transformaciones de potencia pueden dificultar la interpretación directa de los coeficientes del modelo.
- La necesidad de escalar las características después de aplicar transformaciones de potencia, ya que pueden cambiar significativamente la escala de tus datos.
Al aplicar transformaciones de potencia de manera reflexiva, puedes a menudo descubrir patrones ocultos en tus datos y mejorar el rendimiento de tus modelos de Machine Learning, especialmente cuando tratas con relaciones complejas y no lineales entre variables.
Ejemplo: Transformación de potencia para crear nuevas características
Demostraremos cómo aplicar transformaciones de potencia a un conjunto de datos, incluyendo transformaciones cuadrada, cúbica y de raíz cuadrada. Visualizaremos los resultados y compararemos las distribuciones de los datos originales y transformados.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'Value': np.random.uniform(1, 100, 1000)}
df = pd.DataFrame(data)
# Apply power transformations
df['Square'] = df['Value'] ** 2
df['Cube'] = df['Value'] ** 3
df['SquareRoot'] = np.sqrt(df['Value'])
# Visualize the distributions
fig, axs = plt.subplots(2, 2, figsize=(15, 15))
sns.histplot(df['Value'], kde=True, ax=axs[0, 0])
axs[0, 0].set_title('Original Distribution')
sns.histplot(df['Square'], kde=True, ax=axs[0, 1])
axs[0, 1].set_title('Square Transformation')
sns.histplot(df['Cube'], kde=True, ax=axs[1, 0])
axs[1, 0].set_title('Cube Transformation')
sns.histplot(df['SquareRoot'], kde=True, ax=axs[1, 1])
axs[1, 1].set_title('Square Root Transformation')
plt.tight_layout()
plt.show()
# Compare skewness
print("Skewness:")
print(f"Original: {df['Value'].skew():.2f}")
print(f"Square: {df['Square'].skew():.2f}")
print(f"Cube: {df['Cube'].skew():.2f}")
print(f"Square Root: {df['SquareRoot'].skew():.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas y generación de números aleatorios
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Generar 1000 valores aleatorios entre 1 y 100 usando np.random.uniform()
- Almacenar los datos en un DataFrame de pandas
- Aplicar transformaciones de potencia:
- Transformación cuadrada:
df['Value'] ** 2
- Transformación cúbica:
df['Value'] ** 3
- Transformación de raíz cuadrada:
np.sqrt(df['Value'])
- Transformación cuadrada:
- Visualizar las distribuciones:
- Crear una cuadrícula de subgráficos de 2x2
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para cada distribución
- Establecer títulos apropiados para cada subgráfico
- Comparar asimetría:
- Calcular e imprimir la asimetría de cada distribución usando el método skew()
Este ejemplo muestra cómo las diferentes transformaciones de potencia afectan la distribución de los datos. Las transformaciones cuadrada y cúbica tienden a enfatizar valores más grandes y pueden aumentar la asimetría hacia la derecha, mientras que la transformación de raíz cuadrada puede ayudar a reducir la asimetría hacia la derecha y comprimir el rango de los valores más grandes.
Transformación de Box-Cox
Una familia versátil de transformaciones de potencia que incluye el logaritmo como caso especial. Esta transformación es particularmente útil para estabilizar la varianza y hacer que las distribuciones de datos se parezcan más a una normal. La transformación de Box-Cox se define por un parámetro λ (lambda), que determina el tipo específico de transformación aplicada a los datos. Cuando λ = 0, se vuelve equivalente a la transformación logarítmica natural.
Características clave de la transformación de Box-Cox incluyen:
- Flexibilidad: Al ajustar el parámetro λ, puede manejar una amplia gama de distribuciones de datos.
- Estabilización de la varianza: Ayuda a lograr homocedasticidad, una suposición clave en muchos modelos estadísticos.
- Normalización: Puede hacer que los datos sesgados sean más simétricos, aproximándose a una distribución normal.
- Mejora del rendimiento del modelo: Al abordar la no linealidad y la no normalidad, puede mejorar el rendimiento de varios modelos estadísticos y de Machine Learning.
Al aplicar la transformación de Box-Cox, es importante tener en cuenta que requiere que todos los valores sean positivos. Para conjuntos de datos con valores cero o negativos, puede ser necesario agregar una constante antes de la transformación. Además, el valor óptimo de λ puede determinarse mediante estimación de máxima verosimilitud, lo que permite una selección basada en datos de la transformación más adecuada.
Ejemplo: Transformación de Box-Cox
Demostraremos cómo aplicar la transformación de Box-Cox a un conjunto de datos y visualizar los resultados.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
# Generate sample data with a right-skewed distribution
np.random.seed(42)
data = np.random.lognormal(mean=0, sigma=0.5, size=1000)
# Create a DataFrame
df = pd.DataFrame({'original': data})
# Apply Box-Cox transformation
df['box_cox'], lambda_param = stats.boxcox(df['original'])
# Visualize the original and transformed distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.hist(df['original'], bins=30, edgecolor='black')
ax1.set_title('Original Distribution')
ax1.set_xlabel('Value')
ax1.set_ylabel('Frequency')
ax2.hist(df['box_cox'], bins=30, edgecolor='black')
ax2.set_title(f'Box-Cox Transformed (λ = {lambda_param:.2f})')
ax2.set_xlabel('Value')
ax2.set_ylabel('Frequency')
plt.tight_layout()
plt.show()
# Print summary statistics
print("Original Data:")
print(df['original'].describe())
print("\nBox-Cox Transformed Data:")
print(df['box_cox'].describe())
# Print skewness
print(f"\nOriginal Skewness: {df['original'].skew():.2f}")
print(f"Box-Cox Transformed Skewness: {df['box_cox'].skew():.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas y generación de números aleatorios
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones
- scipy.stats: Para la función de transformación de Box-Cox
- Generar datos de muestra:
- Usar np.random.lognormal() para crear una distribución sesgada hacia la derecha
- Almacenar los datos en un DataFrame de pandas
- Aplicar la transformación de Box-Cox:
- Usar stats.boxcox() para transformar los datos
- Esta función devuelve los datos transformados y el valor óptimo de lambda
- Visualizar las distribuciones:
- Crear dos subgráficos uno al lado del otro
- Graficar histogramas de los datos originales y transformados
- Establecer títulos y etiquetas apropiados
- Imprimir estadísticas descriptivas y asimetría:
- Usar describe() para obtener estadísticas descriptivas de los datos originales y transformados
- Calcular e imprimir la asimetría de ambas distribuciones usando skew()
Este ejemplo muestra cómo la transformación de Box-Cox puede normalizar una distribución sesgada hacia la derecha. El valor óptimo de lambda se determina automáticamente, y la transformación reduce significativamente la asimetría de los datos. Esto puede ser particularmente útil para preparar datos para modelos de Machine Learning que asumen características distribuidas normalmente.
Estas transformaciones cumplen múltiples propósitos en el proceso de ingeniería de características:
- Normalizar distribuciones de datos: Muchos métodos estadísticos y algoritmos de Machine Learning asumen datos distribuidos normalmente. Las transformaciones pueden ayudar a aproximar esta condición.
- Estabilizar la varianza: Algunos modelos, como la regresión lineal, asumen una varianza constante en todo el rango de las variables predictoras. Las transformaciones pueden ayudar a cumplir con esta suposición.
- Simplificar relaciones no lineales: Al aplicar la transformación adecuada, relaciones complejas no lineales pueden a veces convertirse en lineales, haciéndolas más fáciles de aprender para los modelos.
- Reducir el impacto de los valores atípicos: Las transformaciones como el logaritmo pueden comprimir la escala de una variable, reduciendo la influencia de valores extremos.
Al aplicar estas transformaciones, es crucial considerar la naturaleza de tus datos y las suposiciones de tu modelo elegido. Siempre valida el impacto de las transformaciones a través del análisis exploratorio de datos y métricas de rendimiento del modelo. Recuerda que, si bien las transformaciones pueden ser poderosas, también pueden afectar la interpretabilidad de tu modelo, así que úsalas con prudencia y documenta tu enfoque minuciosamente.
7.1.2 Extracción de características de fecha y hora
Al trabajar con conjuntos de datos que contienen características de fecha o tiempo, puedes mejorar significativamente el poder predictivo de tu modelo al extraer nuevas características significativas. Este proceso implica desglosar columnas de fecha y hora en sus partes constituyentes, como año, mes, día de la semana o hora. Estas características extraídas pueden capturar patrones temporales importantes y estacionalidad en tus datos.
Por ejemplo, en un conjunto de datos de ventas minoristas, extraer el mes y el día de la semana a partir de una fecha de venta podría revelar ciclos mensuales de ventas o patrones de compras semanales. De manera similar, para datos relacionados con el clima, el mes y el día podrían ayudar a capturar variaciones estacionales. En series temporales financieras, el año y el trimestre podrían ser cruciales para identificar tendencias a largo plazo y patrones cíclicos.
Además, puedes crear características más complejas basadas en el tiempo, como:
- ¿Es fin de semana o día laboral?
- ¿En qué trimestre del año?
- ¿Es un día festivo?
- ¿Número de días desde un evento específico?
Estas características derivadas pueden proporcionar información valiosa sobre fenómenos dependientes del tiempo, permitiendo que tu modelo capture patrones matizados que podrían no ser evidentes en los datos crudos de fecha y hora. Al incorporar estos aspectos temporales, puedes mejorar significativamente la capacidad de tu modelo para predecir resultados influenciados por tendencias estacionales, patrones cíclicos u otros factores basados en el tiempo.
Ejemplo: Extracción de componentes de fecha para crear nuevas características
Supongamos que tenemos un conjunto de datos que incluye una columna con la fecha de una venta de una casa. Podemos extraer nuevas características como YearSold, MonthSold y DayOfWeekSold para capturar tendencias temporales que pueden influir en los precios de las casas.
# Sample data with a date column
data = {
'SaleDate': ['2021-01-15', '2020-07-22', '2021-03-01', '2019-10-10', '2022-12-31'],
'Price': [250000, 300000, 275000, 225000, 350000]
}
df = pd.DataFrame(data)
# Convert the SaleDate column to a datetime object
df['SaleDate'] = pd.to_datetime(df['SaleDate'])
# Extract new features from the SaleDate column
df['YearSold'] = df['SaleDate'].dt.year
df['MonthSold'] = df['SaleDate'].dt.month
df['DayOfWeekSold'] = df['SaleDate'].dt.dayofweek
df['QuarterSold'] = df['SaleDate'].dt.quarter
df['IsWeekend'] = df['SaleDate'].dt.dayofweek.isin([5, 6]).astype(int)
df['DaysSince2019'] = (df['SaleDate'] - pd.Timestamp('2019-01-01')).dt.days
# Create a season column
df['Season'] = pd.cut(df['MonthSold'],
bins=[0, 3, 6, 9, 12],
labels=['Winter', 'Spring', 'Summer', 'Fall'],
include_lowest=True)
# View the new features
print(df)
# Analyze the relationship between time features and price
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(12, 6))
sns.scatterplot(data=df, x='DaysSince2019', y='Price', hue='Season')
plt.title('House Prices Over Time')
plt.show()
# Calculate average price by year and month
avg_price = df.groupby(['YearSold', 'MonthSold'])['Price'].mean().unstack()
plt.figure(figsize=(12, 6))
sns.heatmap(avg_price, annot=True, fmt='.0f', cmap='YlOrRd')
plt.title('Average House Price by Year and Month')
plt.show()
Este ejemplo de código muestra un enfoque completo para extraer y analizar características basadas en fechas de un conjunto de datos. Vamos a desglosar el código y su funcionalidad:
- Creación y Preprocesamiento de Datos:
- Creamos un conjunto de datos de muestra con las columnas 'SaleDate' y 'Price'.
- La columna 'SaleDate' se convierte en un objeto datetime usando pd.to_datetime().
- Extracción de Características:
- Componentes básicos de la fecha: Se extraen el año, el mes y el día de la semana.
- Trimestre: Se extrae el trimestre del año usando dt.quarter.
- IsWeekend: Se crea una característica binaria para indicar si la venta ocurrió en un fin de semana.
- DaysSince2019: Esta característica calcula el número de días desde el 1 de enero de 2019, lo cual puede ser útil para capturar tendencias a largo plazo.
- Season: Se crea una característica categórica utilizando pd.cut() para agrupar los meses en estaciones.
- Visualización de Datos:
- Se crea un gráfico de dispersión para visualizar la relación entre el número de días desde 2019 y el precio de la casa, con los puntos coloreados por estación.
- Se genera un mapa de calor para mostrar el precio promedio de la casa por año y mes, lo que puede revelar patrones estacionales en los precios de las viviendas.
Este ejemplo completo demuestra varias técnicas para extraer características significativas de los datos de fecha y visualizarlos para obtener información. Dicha ingeniería de características puede mejorar significativamente el poder predictivo de los modelos de Machine Learning que trabajan con datos de series temporales.
7.1.3 Combinación de Características
La combinación de múltiples características existentes puede crear nuevas características poderosas que capturen relaciones complejas entre variables. Este proceso, conocido como interacción de características o cruzamiento de características, va más allá de las combinaciones lineales simples y puede revelar patrones no lineales en los datos. Al multiplicar, dividir o tomar razones de características existentes, podemos generar nuevos conocimientos que las características individuales podrían no captar por sí solas.
Por ejemplo, en un conjunto de datos con información sobre casas, podrías crear una nueva característica que represente el precio por pie cuadrado dividiendo el precio de la casa por su tamaño en pies cuadrados. Esta característica derivada normaliza el precio en función del tamaño de la casa, revelando potencialmente patrones que ni el precio ni el tamaño por sí solos podrían mostrar. Otros ejemplos podrían incluir:
- Combinar 'número de habitaciones' y 'tamaño total en pies cuadrados' para crear una característica de 'tamaño promedio de habitación'
- Multiplicar 'edad de la casa' por 'número de renovaciones' para capturar el impacto de las actualizaciones en propiedades más antiguas
- Crear una razón de 'tamaño del terreno' a 'tamaño de la casa' para representar la proporción de tierra respecto a la construcción
Estas características combinadas pueden mejorar significativamente la capacidad de un modelo para capturar relaciones matizadas en los datos, mejorando potencialmente su poder predictivo e interpretabilidad. Sin embargo, es importante abordar la combinación de características de manera reflexiva, ya que la creación indiscriminada de nuevas características puede llevar al sobreajuste o aumentar la complejidad del modelo sin obtener ganancias correspondientes en el rendimiento.
Ejemplo: Creación de una Nueva Característica a partir de la Razón de Dos Características
Supongamos que tenemos un conjunto de datos con precios de casas y tamaños de casas (en pies cuadrados). Podemos crear una nueva característica, PricePerSqFt, para normalizar los precios de las casas en función de su tamaño.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {
'HousePrice': [500000, 700000, 600000, 550000, 800000],
'HouseSize': [2000, 3000, 2500, 1800, 3500],
'Bedrooms': [3, 4, 3, 2, 5],
'YearBuilt': [1990, 2005, 2000, 1985, 2010]
}
df = pd.DataFrame(data)
# Create new features
df['PricePerSqFt'] = df['HousePrice'] / df['HouseSize']
df['AvgRoomSize'] = df['HouseSize'] / df['Bedrooms']
df['AgeOfHouse'] = 2023 - df['YearBuilt']
df['PricePerRoom'] = df['HousePrice'] / df['Bedrooms']
# View the new features
print(df)
# Visualize relationships
plt.figure(figsize=(12, 8))
# Scatter plot of Price vs Size, colored by Age
plt.subplot(2, 2, 1)
sns.scatterplot(data=df, x='HouseSize', y='HousePrice', hue='AgeOfHouse', palette='viridis')
plt.title('House Price vs Size (colored by Age)')
# Bar plot of Average Price per Sq Ft by Bedrooms
plt.subplot(2, 2, 2)
sns.barplot(data=df, x='Bedrooms', y='PricePerSqFt')
plt.title('Avg Price per Sq Ft by Bedrooms')
# Heatmap of correlations
plt.subplot(2, 2, 3)
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
# Scatter plot of Price per Room vs Age of House
plt.subplot(2, 2, 4)
sns.scatterplot(data=df, x='AgeOfHouse', y='PricePerRoom')
plt.title('Price per Room vs Age of House')
plt.tight_layout()
plt.show()
# Statistical summary
print(df.describe())
# Correlation analysis
print(df.corr()['HousePrice'].sort_values(ascending=False))
Este ejemplo de código muestra un enfoque completo para la ingeniería de características y el análisis exploratorio de datos. Vamos a profundizar en sus componentes:
- Preparación de Datos:
- Importamos las bibliotecas necesarias: pandas para la manipulación de datos, matplotlib y seaborn para visualización.
- Se expande el conjunto de datos de muestra para incluir más casas y características adicionales como 'Bedrooms' y 'YearBuilt'.
- Ingeniería de Características:
- PricePerSqFt: Normaliza el precio de la casa según el tamaño.
- AvgRoomSize: Calcula el tamaño promedio de las habitaciones.
- AgeOfHouse: Determina la antigüedad de la casa (asumiendo que el año actual es 2023).
- PricePerRoom: Calcula el precio por dormitorio.
- Visualización de Datos:
- Se crea una cuadrícula de 2x2 gráficos para visualizar diferentes aspectos de los datos:
a) Diagrama de dispersión de House Price vs. Size, coloreado por Age.
b) Gráfico de barras que muestra el precio promedio por pie cuadrado para diferentes cantidades de dormitorios.
c) Mapa de calor de correlaciones entre todas las características.
d) Diagrama de dispersión de Price per Room vs. Age of House.
- Se crea una cuadrícula de 2x2 gráficos para visualizar diferentes aspectos de los datos:
- Análisis Estadístico:
- La función describe() proporciona estadísticas descriptivas para todas las columnas numéricas.
- El análisis de correlación muestra qué tan fuerte se correlaciona cada característica con HousePrice.
Este ejemplo completo no solo crea nuevas características, sino que también explora sus relaciones y posibles impactos en los precios de las viviendas. Las visualizaciones y análisis estadísticos proporcionan información que puede guiar en la ingeniería de características o en los procesos de selección de modelos.
7.1.4 Creación de Términos de Interacción
Los términos de interacción son características que capturan el efecto combinado de dos o más variables, ofreciendo una forma poderosa de modelar relaciones complejas en los datos. Estos términos van más allá de las combinaciones lineales simples, permitiendo la representación de interacciones no lineales entre características. Por ejemplo, en el modelado inmobiliario, la interacción entre el tamaño de una casa y su ubicación podría ser más predictiva de su precio que cualquiera de las características por sí sola. Esto se debe a que el valor de metros cuadrados adicionales puede variar significativamente según el vecindario.
Los términos de interacción son especialmente valiosos cuando hay una relación no lineal entre las características y la variable objetivo. Pueden revelar patrones que las características individuales podrían pasar por alto. Por ejemplo, en un contexto de marketing, la interacción entre la edad de un cliente y sus ingresos podría proporcionar información sobre el comportamiento de compra que ni la edad ni los ingresos podrían captar por sí solos. De manera similar, en estudios ambientales, la interacción entre temperatura y humedad podría ser crucial para predecir ciertos fenómenos meteorológicos.
Crear términos de interacción implica multiplicar dos o más características entre sí. Este proceso permite que el modelo aprenda diferentes efectos para una variable en función de los valores de otra. Es importante tener en cuenta que, aunque los términos de interacción pueden mejorar significativamente el rendimiento del modelo, deben usarse con moderación. Agregar demasiados términos de interacción puede llevar al sobreajuste y hacer que el modelo sea más difícil de interpretar. Por lo tanto, es crucial basar la creación de términos de interacción en el conocimiento del dominio o en el análisis exploratorio de datos para asegurarse de que agreguen un valor significativo al modelo.
Ejemplo: Creación de Términos de Interacción
Supongamos que queremos explorar la interacción entre el precio de una casa y el año en que se vendió. Podemos crear un término de interacción multiplicando estas dos características entre sí.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {
'HousePrice': [500000, 700000, 600000, 550000, 800000],
'YearSold': [2020, 2019, 2021, 2020, 2022],
'SquareFootage': [2000, 2500, 2200, 1800, 3000],
'Bedrooms': [3, 4, 3, 2, 5]
}
df = pd.DataFrame(data)
# Create interaction terms
df['Price_YearInteraction'] = df['HousePrice'] * df['YearSold']
df['Price_SqFtInteraction'] = df['HousePrice'] * df['SquareFootage']
df['PricePerSqFt'] = df['HousePrice'] / df['SquareFootage']
df['PricePerBedroom'] = df['HousePrice'] / df['Bedrooms']
# View the dataframe with new features
print(df)
# Visualize relationships
plt.figure(figsize=(12, 10))
# Scatter plot of Price vs Year, sized by SquareFootage
plt.subplot(2, 2, 1)
sns.scatterplot(data=df, x='YearSold', y='HousePrice', size='SquareFootage', hue='Bedrooms')
plt.title('House Price vs Year Sold')
# Heatmap of correlations
plt.subplot(2, 2, 2)
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
# Scatter plot of Price_YearInteraction vs PricePerSqFt
plt.subplot(2, 2, 3)
sns.scatterplot(data=df, x='Price_YearInteraction', y='PricePerSqFt')
plt.title('Price-Year Interaction vs Price Per Sq Ft')
# Bar plot of average Price Per Bedroom by Year
plt.subplot(2, 2, 4)
sns.barplot(data=df, x='YearSold', y='PricePerBedroom')
plt.title('Avg Price Per Bedroom by Year')
plt.tight_layout()
plt.show()
# Statistical summary
print(df.describe())
# Correlation analysis
print(df.corr()['HousePrice'].sort_values(ascending=False))
Este ejemplo de código demuestra un enfoque completo para crear y analizar términos de interacción en el contexto inmobiliario.
Desglosemos cada parte:
- Preparación de Datos:
- Importamos las bibliotecas necesarias: pandas para la manipulación de datos, matplotlib y seaborn para visualización.
- El conjunto de datos de muestra se expande para incluir más casas y características adicionales como 'SquareFootage' y 'Bedrooms'.
- Ingeniería de Características:
- Price_YearInteraction: Captura la interacción entre el precio de la casa y el año en que se vendió.
- Price_SqFtInteraction: Representa la interacción entre el precio y los pies cuadrados.
- PricePerSqFt: Una característica de razón que normaliza el precio por tamaño.
- PricePerBedroom: Otra característica de razón que muestra el precio por dormitorio.
- Visualización de Datos:
- Se crea una cuadrícula de gráficos 2x2 para visualizar diferentes aspectos de los datos:
a) Diagrama de dispersión de House Price vs. Year Sold, con el tamaño de los puntos representando los pies cuadrados y el color representando el número de dormitorios.
b) Mapa de calor de correlaciones entre todas las características.
c) Diagrama de dispersión de Price-Year Interaction vs. Price Per Sq Ft.
d) Gráfico de barras que muestra el precio promedio por dormitorio en diferentes años.
- Se crea una cuadrícula de gráficos 2x2 para visualizar diferentes aspectos de los datos:
- Análisis Estadístico:
- La función describe() proporciona estadísticas descriptivas para todas las columnas numéricas.
- El análisis de correlación muestra qué tan fuerte se correlaciona cada característica con HousePrice.
Este ejemplo completo no solo crea términos de interacción, sino que también explora sus relaciones con otras características y la variable objetivo (HousePrice). Las visualizaciones y análisis estadísticos proporcionan información que puede guiar en la ingeniería de características o en los procesos de selección de modelos. Por ejemplo, el mapa de calor de correlación puede revelar qué términos de interacción están más fuertemente asociados con los precios de las viviendas, mientras que los gráficos de dispersión pueden mostrar relaciones no lineales que estos términos podrían captar.
7.1.5 Conclusiones Clave y Sus Implicaciones
- Transformaciones matemáticas (como logarítmica o de raíz cuadrada) pueden ayudar a estabilizar la varianza o reducir la asimetría en los datos, mejorando el rendimiento de ciertos modelos de Machine Learning. Estas transformaciones son particularmente útiles cuando se trabaja con características que muestran crecimiento o decaimiento exponencial, o cuando la relación entre variables es no lineal.
- Extracción de características de fecha y hora permite crear nuevas características significativas a partir de columnas de fecha y hora, permitiendo que los modelos capturen patrones estacionales o basados en el tiempo. Esta técnica es crucial para el análisis de series temporales, pronósticos y comprensión de tendencias cíclicas en los datos. Por ejemplo, extraer el día de la semana, el mes o la estación puede revelar patrones importantes en ventas minoristas o consumo de energía.
- Combinación de características como razones o diferencias entre variables existentes puede descubrir relaciones importantes, como normalizar los precios de viviendas por tamaño. Estas características derivadas suelen proporcionar más información interpretativa y significativa que los datos sin procesar. Por ejemplo, en análisis financieros, razones como precio/ganancias o deuda/capital son más informativas que los componentes individuales por sí solos.
- Términos de interacción permiten que el modelo capture los efectos combinados de dos o más características, lo cual puede ser especialmente útil cuando las relaciones entre variables son no lineales. Estos términos pueden mejorar significativamente el rendimiento del modelo al considerar interdependencias complejas. Por ejemplo, en marketing, la interacción entre la edad del cliente y sus ingresos podría predecir mejor el comportamiento de compra que cualquiera de las variables por separado.
Comprender y aplicar estas técnicas de ingeniería de características puede mejorar drásticamente el rendimiento, la interpretabilidad y la robustez de los modelos. Sin embargo, es crucial abordar la creación de características de manera reflexiva, siempre considerando el conocimiento del dominio y los requisitos específicos de la tarea de Machine Learning. La ingeniería de características efectiva requiere una combinación de creatividad, comprensión estadística y experiencia en el dominio.
7.1 Creación de Nuevas Características a partir de Datos Existentes
La creación de nuevas características es una de las técnicas más poderosas para mejorar los modelos de Machine Learning. Este proceso, conocido como ingeniería de características, implica derivar nuevas variables a partir de datos existentes para capturar relaciones complejas, patrones e información que pueden no ser evidentes de inmediato en el conjunto de datos original. Al hacerlo, los científicos de datos pueden mejorar significativamente la precisión, robustez e interpretabilidad de los modelos.
La creación de características puede tomar muchas formas, incluyendo:
- Transformaciones matemáticas (por ejemplo, logarítmica, polinómica)
- Agregaciones (por ejemplo, media, mediana, suma de múltiples características)
- Binning o discretización de variables continuas
- Codificación de variables categóricas
- Creación de características específicas de dominio basadas en el conocimiento experto
En este capítulo, profundizaremos en el proceso de creación de características y exploraremos varias técnicas para combinar características existentes de manera significativa. Comenzaremos examinando métodos para derivar nuevas características a partir de datos existentes, como la extracción de fecha/hora, el análisis de texto y el procesamiento de información geográfica. Luego, avanzaremos hacia conceptos más avanzados, incluyendo los términos de interacción, que capturan los efectos combinados de múltiples características.
Al dominar estas técnicas, podrás extraer más valor de tus datos, descubriendo potencialmente patrones y relaciones ocultas que pueden dar a tus modelos una ventaja significativa en rendimiento predictivo y capacidad de generalización.
La creación de características es un paso crítico en el flujo de trabajo de la ciencia de datos, que implica la generación de nuevas características informativas a partir de datos existentes. Este proceso requiere no solo habilidades técnicas, sino también una comprensión profunda del dominio y del problema específico que se está abordando. Al crear nuevas características, los científicos de datos pueden descubrir patrones ocultos, simplificar relaciones complejas y reducir el ruido en el conjunto de datos, mejorando en última instancia el rendimiento y la interpretabilidad de los modelos de Machine Learning.
El arte de la creación de características a menudo implica pensamiento creativo y experimentación. Puede incluir técnicas tales como:
- Aplicar funciones matemáticas a características existentes
- Extraer información de tipos de datos complejos como fechas, texto o coordenadas geográficas
- Combinar múltiples características para crear representaciones más informativas
- Codificar variables categóricas de formas que capturen sus propiedades inherentes
- Aprovechar la experiencia del dominio para crear características que reflejen relaciones del mundo real
En esta sección, profundizaremos en varios métodos para la creación de características, comenzando con transformaciones matemáticas básicas y avanzando hacia técnicas más avanzadas. Exploraremos cómo extraer información significativa de datos de fecha y hora, lo cual puede ser crucial para capturar patrones temporales y estacionalidad. Además, discutiremos estrategias para combinar características y crear predictores más poderosos, incluyendo la creación de términos de interacción que capturen la interacción entre diferentes variables.
Al dominar estas técnicas, estarás mejor equipado para extraer el máximo valor de tus datos, descubriendo potencialmente ideas que no eran evidentes en el conjunto de datos original. Esto puede conducir a predicciones más precisas, mejor toma de decisiones y una comprensión más profunda de los patrones subyacentes en tus datos.
7.1.1 Transformaciones Matemáticas
Una de las técnicas fundamentales para crear nuevas características es aplicar transformaciones matemáticas a las características numéricas existentes. Estas transformaciones pueden mejorar significativamente la calidad y utilidad de tus datos para los modelos de Machine Learning. Las transformaciones comunes incluyen:
Transformación logarítmica
Esta técnica poderosa es particularmente efectiva para manejar distribuciones sesgadas hacia la derecha y comprimir amplios rangos de valores. Al aplicar la función logarítmica a los datos, podemos:
- Linearizar relaciones exponenciales, haciéndolas más fáciles de interpretar para los modelos
- Reducir el impacto de los valores atípicos, especialmente en conjuntos de datos con valores extremos
- Normalizar datos que abarcan varios órdenes de magnitud
- Mejorar el rendimiento de modelos que asumen datos distribuidos normalmente
Las transformaciones logarítmicas se aplican comúnmente en varios campos:
- Finanzas: Para analizar precios de acciones, rendimientos y otros métricas financieras
- Economía: Al tratar con PIB, crecimiento poblacional o tasas de inflación
- Biología: En el estudio del crecimiento bacteriano o cinética enzimática
- Física: Para analizar fenómenos como la intensidad del sonido o la magnitud de terremotos
Al aplicar transformaciones logarítmicas, es importante considerar:
- La base del logaritmo (logaritmo natural, base 10, etc.) y su impacto en la interpretación
- Manejo de valores cero o negativos, que pueden requerir agregar una constante antes de la transformación
- El efecto en la interpretabilidad del modelo y la necesidad de revertir la transformación de las predicciones
Ejemplo: Transformación Logarítmica para Crear una Nueva Característica
Supongamos que tenemos un conjunto de datos que contiene precios de casas, y sospechamos que la distribución de los precios está sesgada. Para reducir el sesgo y hacer la distribución más normal, podemos crear una nueva característica aplicando una transformación logarítmica a los precios originales.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'HousePrice': [50000, 120000, 250000, 500000, 1200000, 2500000]}
df = pd.DataFrame(data)
# Create a new feature by applying a logarithmic transformation
df['LogHousePrice'] = np.log(df['HousePrice'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(df['HousePrice'], kde=True, ax=ax1)
ax1.set_title('Distribution of Original House Prices')
ax1.set_xlabel('House Price')
sns.histplot(df['LogHousePrice'], kde=True, ax=ax2)
ax2.set_title('Distribution of Log-Transformed House Prices')
ax2.set_xlabel('Log(House Price)')
plt.tight_layout()
plt.show()
# Compare skewness
original_skew = df['HousePrice'].skew()
log_skew = df['LogHousePrice'].skew()
print(f"\nSkewness of original prices: {original_skew:.2f}")
print(f"Skewness of log-transformed prices: {log_skew:.2f}")
Este ejemplo de código demuestra el proceso de aplicar una transformación logarítmica a datos de precios de viviendas y analizar sus efectos.
Aquí tienes un desglose completo del código y su propósito:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización de datos estadísticos
- Crear datos de muestra:
- Un diccionario con una sola clave "HousePrice" y una lista de precios de viviendas como valores
- Convertir el diccionario en un DataFrame de pandas
- Aplicar transformación logarítmica:
- Crear una nueva columna "LogHousePrice" aplicando np.log() a la columna "HousePrice"
- Esta transformación ayuda a reducir la asimetría de los datos y a comprimir el rango de valores
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los precios originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas como la cantidad, media, desviación estándar, mínimo, máximo y cuartiles para ambas columnas
- Visualizar las distribuciones:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para los precios originales y transformados
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos utilizando plt.show()
- Comparar asimetría:
- Calcular la asimetría de las distribuciones de precios originales y transformados usando el método skew()
- Imprimir los valores de asimetría
Este ejemplo completo no solo aplica la transformación logarítmica, sino que también proporciona evidencia visual y estadística de sus efectos. Al comparar las distribuciones originales y transformadas, podemos observar cómo la transformación logarítmica ayuda a normalizar los datos, lo que potencialmente los hace más adecuados para diversos análisis estadísticos y modelos de Machine Learning.
Transformación de raíz cuadrada
Esta transformación es menos extrema que la logarítmica, pero aún es efectiva para reducir la asimetría hacia la derecha. Es particularmente útil para datos de conteo o cuando se enfrenta a una asimetría moderada hacia la derecha. La función de raíz cuadrada comprime el extremo superior de la distribución mientras expande el extremo inferior, lo que la hace ideal para datos que no requieren un cambio tan drástico como la transformación logarítmica.
Los principales beneficios de la transformación de raíz cuadrada incluyen:
- Reducir el impacto de los valores atípicos sin eliminarlos completamente
- Mejorar la normalidad de distribuciones con asimetría positiva
- Estabilizar la varianza en datos de conteo, especialmente cuando la varianza aumenta con la media
- Mantener una relación más intuitiva con los datos originales en comparación con la transformación logarítmica
Al aplicar transformaciones de raíz cuadrada, considera:
- La necesidad de manejar valores cero, lo que puede requerir agregar una pequeña constante antes de la transformación
- El efecto en valores negativos, que puede requerir tratamiento especial o transformaciones alternativas
- El impacto en la interpretabilidad del modelo y la posible necesidad de revertir la transformación de las predicciones
Las transformaciones de raíz cuadrada se utilizan comúnmente en varios campos, incluyendo:
- Ecología: Para analizar datos de abundancia de especies
- Psicología: Al trabajar con datos de tiempo de reacción
- Control de calidad: Para analizar el conteo de defectos en procesos de fabricación
Ejemplo: Transformación de raíz cuadrada para crear una nueva característica
Consideremos un conjunto de datos que contiene el número de defectos encontrados en productos manufacturados. Aplicaremos una transformación de raíz cuadrada a estos datos para reducir la asimetría hacia la derecha y estabilizar la varianza.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'DefectCount': [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]}
df = pd.DataFrame(data)
# Create a new feature by applying a square root transformation
df['SqrtDefectCount'] = np.sqrt(df['DefectCount'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(df['DefectCount'], kde=True, ax=ax1)
ax1.set_title('Distribution of Original Defect Counts')
ax1.set_xlabel('Defect Count')
sns.histplot(df['SqrtDefectCount'], kde=True, ax=ax2)
ax2.set_title('Distribution of Square Root Transformed Defect Counts')
ax2.set_xlabel('Square Root of Defect Count')
plt.tight_layout()
plt.show()
# Compare skewness
original_skew = df['DefectCount'].skew()
sqrt_skew = df['SqrtDefectCount'].skew()
print(f"\nSkewness of original counts: {original_skew:.2f}")
print(f"Skewness of square root transformed counts: {sqrt_skew:.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Un diccionario con una sola clave "DefectCount" y una lista de conteos de defectos como valores
- Convertir el diccionario en un DataFrame de pandas
- Aplicar la transformación de raíz cuadrada:
- Crear una nueva columna "SqrtDefectCount" aplicando np.sqrt() a la columna "DefectCount"
- Esta transformación ayuda a reducir la asimetría de los datos y a estabilizar la varianza
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los conteos de defectos originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas como cantidad, media, desviación estándar, mínimo, máximo y cuartiles para ambas columnas
- Visualizar las distribuciones:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para los conteos de defectos originales y transformados por raíz cuadrada
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos usando plt.show()
- Comparar la asimetría:
- Calcular la asimetría de las distribuciones de conteo de defectos originales y transformados por raíz cuadrada usando el método skew()
- Imprimir los valores de asimetría
Este ejemplo muestra cómo aplicar una transformación de raíz cuadrada a un conjunto de datos, visualizar los resultados y comparar la asimetría de los datos originales y transformados. La transformación de raíz cuadrada puede ser particularmente efectiva para datos de conteo, ayudando a estabilizar la varianza y reducir la asimetría hacia la derecha.
Transformación exponencial:
Esta técnica poderosa puede usarse para amplificar diferencias entre valores o para manejar distribuciones con asimetría hacia la izquierda. A diferencia de las transformaciones logarítmicas, que comprimen valores grandes, las transformaciones exponenciales los expanden, lo que hace que este método sea particularmente útil cuando:
- Quieres enfatizar las diferencias entre valores más altos en tu conjunto de datos
- Tus datos muestran una distribución con asimetría hacia la izquierda (negativa) que necesita ser equilibrada
- Estás trabajando con variables donde los cambios pequeños en valores altos son más significativos que en valores bajos
Aplicaciones comunes de las transformaciones exponenciales incluyen:
- Modelado financiero: Para calcular interés compuesto o tasas de crecimiento
- Dinámica de poblaciones: Al modelar patrones de crecimiento exponencial
- Procesamiento de señales: Para amplificar ciertos componentes de frecuencia
Al aplicar transformaciones exponenciales, es crucial considerar:
- La base de la función exponencial y su impacto en la escala de la transformación
- La posibilidad de crear valores atípicos extremos, lo cual puede requerir manejo adicional
- El efecto en la interpretabilidad del modelo y la necesidad de una cuidadosa transformación inversa de las predicciones
Ejemplo: Transformación Exponencial para Crear una Nueva Característica
Consideremos un conjunto de datos que contiene valores que queremos enfatizar o amplificar. Aplicaremos una transformación exponencial a estos datos para crear una nueva característica que resalte las diferencias entre valores más altos.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'Value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
df = pd.DataFrame(data)
# Create a new feature by applying an exponential transformation
df['ExpValue'] = np.exp(df['Value'])
# View the original and transformed features
print("Original DataFrame:")
print(df)
# Calculate summary statistics
print("\nSummary Statistics:")
print(df.describe())
# Visualize the distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
sns.scatterplot(x='Value', y='ExpValue', data=df, ax=ax1)
ax1.set_title('Original vs Exponential Values')
ax1.set_xlabel('Original Value')
ax1.set_ylabel('Exponential Value')
sns.lineplot(x='Value', y='Value', data=df, ax=ax2, label='Original')
sns.lineplot(x='Value', y='ExpValue', data=df, ax=ax2, label='Exponential')
ax2.set_title('Comparison of Original and Exponential Values')
ax2.set_xlabel('Value')
ax2.set_ylabel('Transformed Value')
ax2.legend()
plt.tight_layout()
plt.show()
# Compare ranges
original_range = df['Value'].max() - df['Value'].min()
exp_range = df['ExpValue'].max() - df['ExpValue'].min()
print(f"\nRange of original values: {original_range:.2f}")
print(f"Range of exponential transformed values: {exp_range:.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones estáticas, animadas e interactivas
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Un diccionario con una sola clave "Value" y una lista de valores del 1 al 10
- Convertir el diccionario en un DataFrame de pandas
- Aplicar la transformación exponencial:
- Crear una nueva columna "ExpValue" aplicando np.exp() a la columna "Value"
- Esta transformación amplifica exponencialmente los valores originales
- Mostrar el DataFrame original:
- Imprimir el DataFrame para mostrar tanto los valores originales como los transformados
- Calcular y mostrar estadísticas descriptivas:
- Utilizar el método describe() para obtener medidas estadísticas para ambas columnas
- Visualizar los datos:
- Crear una figura con dos subgráficos uno al lado del otro
- Usar scatterplot() de seaborn para mostrar la relación entre los valores originales y exponenciales
- Usar lineplot() de seaborn para comparar el crecimiento de los valores originales y exponenciales
- Establecer títulos y etiquetas apropiados para los gráficos
- Mostrar los gráficos usando plt.show()
- Comparar los rangos:
- Calcular el rango (máximo - mínimo) para ambos valores, originales y transformados exponencialmente
- Imprimir los rangos para mostrar cómo la transformación exponencial ha amplificado las diferencias
Transformaciones de potencia
Incluyen cuadrado, cubo o potencias más altas. Estas transformaciones pueden ser particularmente efectivas para enfatizar valores mayores o capturar relaciones no lineales en tus datos. Aquí tienes una visión más detallada de las transformaciones de potencia:
- Transformación cuadrada (x²): Puede ser útil cuando deseas enfatizar diferencias entre valores grandes mientras comprimes las diferencias entre valores pequeños. A menudo se usa en análisis estadísticos y modelos de Machine Learning para capturar relaciones cuadráticas.
- Transformación cúbica (x³): Esta transformación amplifica aún más las diferencias que la cuadrada. Puede ser especialmente útil al tratar con variables donde pequeños cambios en valores altos son mucho más significativos que en valores bajos.
- Potencias más altas (x⁴, x⁵, etc.): Estas pueden usarse para capturar relaciones no lineales cada vez más complejas. Sin embargo, ten precaución al usar potencias muy altas, ya que pueden llevar a inestabilidad numérica y sobreajuste.
- Potencias fraccionarias (√x, ³√x, etc.): Son menos comunes, pero pueden ser valiosas en ciertos escenarios. Por ejemplo, una transformación de raíz cúbica puede ser útil para manejar valores atípicos extremos mientras mantiene parte de la escala original.
Al aplicar transformaciones de potencia, considera lo siguiente:
- La naturaleza de tus datos y el problema específico que estás intentando resolver. Diferentes transformaciones de potencia pueden ser más o menos apropiadas según tu conjunto de datos y objetivos.
- La posibilidad de crear o agravar valores atípicos, especialmente con potencias altas. Puede ser necesario manejar cuidadosamente los valores extremos.
- El impacto en la interpretabilidad del modelo. Las transformaciones de potencia pueden dificultar la interpretación directa de los coeficientes del modelo.
- La necesidad de escalar las características después de aplicar transformaciones de potencia, ya que pueden cambiar significativamente la escala de tus datos.
Al aplicar transformaciones de potencia de manera reflexiva, puedes a menudo descubrir patrones ocultos en tus datos y mejorar el rendimiento de tus modelos de Machine Learning, especialmente cuando tratas con relaciones complejas y no lineales entre variables.
Ejemplo: Transformación de potencia para crear nuevas características
Demostraremos cómo aplicar transformaciones de potencia a un conjunto de datos, incluyendo transformaciones cuadrada, cúbica y de raíz cuadrada. Visualizaremos los resultados y compararemos las distribuciones de los datos originales y transformados.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {'Value': np.random.uniform(1, 100, 1000)}
df = pd.DataFrame(data)
# Apply power transformations
df['Square'] = df['Value'] ** 2
df['Cube'] = df['Value'] ** 3
df['SquareRoot'] = np.sqrt(df['Value'])
# Visualize the distributions
fig, axs = plt.subplots(2, 2, figsize=(15, 15))
sns.histplot(df['Value'], kde=True, ax=axs[0, 0])
axs[0, 0].set_title('Original Distribution')
sns.histplot(df['Square'], kde=True, ax=axs[0, 1])
axs[0, 1].set_title('Square Transformation')
sns.histplot(df['Cube'], kde=True, ax=axs[1, 0])
axs[1, 0].set_title('Cube Transformation')
sns.histplot(df['SquareRoot'], kde=True, ax=axs[1, 1])
axs[1, 1].set_title('Square Root Transformation')
plt.tight_layout()
plt.show()
# Compare skewness
print("Skewness:")
print(f"Original: {df['Value'].skew():.2f}")
print(f"Square: {df['Square'].skew():.2f}")
print(f"Cube: {df['Cube'].skew():.2f}")
print(f"Square Root: {df['SquareRoot'].skew():.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas y generación de números aleatorios
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones
- seaborn (sns): Para visualización estadística de datos
- Crear datos de muestra:
- Generar 1000 valores aleatorios entre 1 y 100 usando np.random.uniform()
- Almacenar los datos en un DataFrame de pandas
- Aplicar transformaciones de potencia:
- Transformación cuadrada:
df['Value'] ** 2
- Transformación cúbica:
df['Value'] ** 3
- Transformación de raíz cuadrada:
np.sqrt(df['Value'])
- Transformación cuadrada:
- Visualizar las distribuciones:
- Crear una cuadrícula de subgráficos de 2x2
- Usar histplot() de seaborn para crear histogramas con estimaciones de densidad de núcleo (KDE) para cada distribución
- Establecer títulos apropiados para cada subgráfico
- Comparar asimetría:
- Calcular e imprimir la asimetría de cada distribución usando el método skew()
Este ejemplo muestra cómo las diferentes transformaciones de potencia afectan la distribución de los datos. Las transformaciones cuadrada y cúbica tienden a enfatizar valores más grandes y pueden aumentar la asimetría hacia la derecha, mientras que la transformación de raíz cuadrada puede ayudar a reducir la asimetría hacia la derecha y comprimir el rango de los valores más grandes.
Transformación de Box-Cox
Una familia versátil de transformaciones de potencia que incluye el logaritmo como caso especial. Esta transformación es particularmente útil para estabilizar la varianza y hacer que las distribuciones de datos se parezcan más a una normal. La transformación de Box-Cox se define por un parámetro λ (lambda), que determina el tipo específico de transformación aplicada a los datos. Cuando λ = 0, se vuelve equivalente a la transformación logarítmica natural.
Características clave de la transformación de Box-Cox incluyen:
- Flexibilidad: Al ajustar el parámetro λ, puede manejar una amplia gama de distribuciones de datos.
- Estabilización de la varianza: Ayuda a lograr homocedasticidad, una suposición clave en muchos modelos estadísticos.
- Normalización: Puede hacer que los datos sesgados sean más simétricos, aproximándose a una distribución normal.
- Mejora del rendimiento del modelo: Al abordar la no linealidad y la no normalidad, puede mejorar el rendimiento de varios modelos estadísticos y de Machine Learning.
Al aplicar la transformación de Box-Cox, es importante tener en cuenta que requiere que todos los valores sean positivos. Para conjuntos de datos con valores cero o negativos, puede ser necesario agregar una constante antes de la transformación. Además, el valor óptimo de λ puede determinarse mediante estimación de máxima verosimilitud, lo que permite una selección basada en datos de la transformación más adecuada.
Ejemplo: Transformación de Box-Cox
Demostraremos cómo aplicar la transformación de Box-Cox a un conjunto de datos y visualizar los resultados.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
# Generate sample data with a right-skewed distribution
np.random.seed(42)
data = np.random.lognormal(mean=0, sigma=0.5, size=1000)
# Create a DataFrame
df = pd.DataFrame({'original': data})
# Apply Box-Cox transformation
df['box_cox'], lambda_param = stats.boxcox(df['original'])
# Visualize the original and transformed distributions
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.hist(df['original'], bins=30, edgecolor='black')
ax1.set_title('Original Distribution')
ax1.set_xlabel('Value')
ax1.set_ylabel('Frequency')
ax2.hist(df['box_cox'], bins=30, edgecolor='black')
ax2.set_title(f'Box-Cox Transformed (λ = {lambda_param:.2f})')
ax2.set_xlabel('Value')
ax2.set_ylabel('Frequency')
plt.tight_layout()
plt.show()
# Print summary statistics
print("Original Data:")
print(df['original'].describe())
print("\nBox-Cox Transformed Data:")
print(df['box_cox'].describe())
# Print skewness
print(f"\nOriginal Skewness: {df['original'].skew():.2f}")
print(f"Box-Cox Transformed Skewness: {df['box_cox'].skew():.2f}")
Desglose del código:
- Importar las bibliotecas necesarias:
- numpy (np): Para operaciones numéricas y generación de números aleatorios
- pandas (pd): Para manipulación y análisis de datos
- matplotlib.pyplot (plt): Para crear visualizaciones
- scipy.stats: Para la función de transformación de Box-Cox
- Generar datos de muestra:
- Usar np.random.lognormal() para crear una distribución sesgada hacia la derecha
- Almacenar los datos en un DataFrame de pandas
- Aplicar la transformación de Box-Cox:
- Usar stats.boxcox() para transformar los datos
- Esta función devuelve los datos transformados y el valor óptimo de lambda
- Visualizar las distribuciones:
- Crear dos subgráficos uno al lado del otro
- Graficar histogramas de los datos originales y transformados
- Establecer títulos y etiquetas apropiados
- Imprimir estadísticas descriptivas y asimetría:
- Usar describe() para obtener estadísticas descriptivas de los datos originales y transformados
- Calcular e imprimir la asimetría de ambas distribuciones usando skew()
Este ejemplo muestra cómo la transformación de Box-Cox puede normalizar una distribución sesgada hacia la derecha. El valor óptimo de lambda se determina automáticamente, y la transformación reduce significativamente la asimetría de los datos. Esto puede ser particularmente útil para preparar datos para modelos de Machine Learning que asumen características distribuidas normalmente.
Estas transformaciones cumplen múltiples propósitos en el proceso de ingeniería de características:
- Normalizar distribuciones de datos: Muchos métodos estadísticos y algoritmos de Machine Learning asumen datos distribuidos normalmente. Las transformaciones pueden ayudar a aproximar esta condición.
- Estabilizar la varianza: Algunos modelos, como la regresión lineal, asumen una varianza constante en todo el rango de las variables predictoras. Las transformaciones pueden ayudar a cumplir con esta suposición.
- Simplificar relaciones no lineales: Al aplicar la transformación adecuada, relaciones complejas no lineales pueden a veces convertirse en lineales, haciéndolas más fáciles de aprender para los modelos.
- Reducir el impacto de los valores atípicos: Las transformaciones como el logaritmo pueden comprimir la escala de una variable, reduciendo la influencia de valores extremos.
Al aplicar estas transformaciones, es crucial considerar la naturaleza de tus datos y las suposiciones de tu modelo elegido. Siempre valida el impacto de las transformaciones a través del análisis exploratorio de datos y métricas de rendimiento del modelo. Recuerda que, si bien las transformaciones pueden ser poderosas, también pueden afectar la interpretabilidad de tu modelo, así que úsalas con prudencia y documenta tu enfoque minuciosamente.
7.1.2 Extracción de características de fecha y hora
Al trabajar con conjuntos de datos que contienen características de fecha o tiempo, puedes mejorar significativamente el poder predictivo de tu modelo al extraer nuevas características significativas. Este proceso implica desglosar columnas de fecha y hora en sus partes constituyentes, como año, mes, día de la semana o hora. Estas características extraídas pueden capturar patrones temporales importantes y estacionalidad en tus datos.
Por ejemplo, en un conjunto de datos de ventas minoristas, extraer el mes y el día de la semana a partir de una fecha de venta podría revelar ciclos mensuales de ventas o patrones de compras semanales. De manera similar, para datos relacionados con el clima, el mes y el día podrían ayudar a capturar variaciones estacionales. En series temporales financieras, el año y el trimestre podrían ser cruciales para identificar tendencias a largo plazo y patrones cíclicos.
Además, puedes crear características más complejas basadas en el tiempo, como:
- ¿Es fin de semana o día laboral?
- ¿En qué trimestre del año?
- ¿Es un día festivo?
- ¿Número de días desde un evento específico?
Estas características derivadas pueden proporcionar información valiosa sobre fenómenos dependientes del tiempo, permitiendo que tu modelo capture patrones matizados que podrían no ser evidentes en los datos crudos de fecha y hora. Al incorporar estos aspectos temporales, puedes mejorar significativamente la capacidad de tu modelo para predecir resultados influenciados por tendencias estacionales, patrones cíclicos u otros factores basados en el tiempo.
Ejemplo: Extracción de componentes de fecha para crear nuevas características
Supongamos que tenemos un conjunto de datos que incluye una columna con la fecha de una venta de una casa. Podemos extraer nuevas características como YearSold, MonthSold y DayOfWeekSold para capturar tendencias temporales que pueden influir en los precios de las casas.
# Sample data with a date column
data = {
'SaleDate': ['2021-01-15', '2020-07-22', '2021-03-01', '2019-10-10', '2022-12-31'],
'Price': [250000, 300000, 275000, 225000, 350000]
}
df = pd.DataFrame(data)
# Convert the SaleDate column to a datetime object
df['SaleDate'] = pd.to_datetime(df['SaleDate'])
# Extract new features from the SaleDate column
df['YearSold'] = df['SaleDate'].dt.year
df['MonthSold'] = df['SaleDate'].dt.month
df['DayOfWeekSold'] = df['SaleDate'].dt.dayofweek
df['QuarterSold'] = df['SaleDate'].dt.quarter
df['IsWeekend'] = df['SaleDate'].dt.dayofweek.isin([5, 6]).astype(int)
df['DaysSince2019'] = (df['SaleDate'] - pd.Timestamp('2019-01-01')).dt.days
# Create a season column
df['Season'] = pd.cut(df['MonthSold'],
bins=[0, 3, 6, 9, 12],
labels=['Winter', 'Spring', 'Summer', 'Fall'],
include_lowest=True)
# View the new features
print(df)
# Analyze the relationship between time features and price
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(12, 6))
sns.scatterplot(data=df, x='DaysSince2019', y='Price', hue='Season')
plt.title('House Prices Over Time')
plt.show()
# Calculate average price by year and month
avg_price = df.groupby(['YearSold', 'MonthSold'])['Price'].mean().unstack()
plt.figure(figsize=(12, 6))
sns.heatmap(avg_price, annot=True, fmt='.0f', cmap='YlOrRd')
plt.title('Average House Price by Year and Month')
plt.show()
Este ejemplo de código muestra un enfoque completo para extraer y analizar características basadas en fechas de un conjunto de datos. Vamos a desglosar el código y su funcionalidad:
- Creación y Preprocesamiento de Datos:
- Creamos un conjunto de datos de muestra con las columnas 'SaleDate' y 'Price'.
- La columna 'SaleDate' se convierte en un objeto datetime usando pd.to_datetime().
- Extracción de Características:
- Componentes básicos de la fecha: Se extraen el año, el mes y el día de la semana.
- Trimestre: Se extrae el trimestre del año usando dt.quarter.
- IsWeekend: Se crea una característica binaria para indicar si la venta ocurrió en un fin de semana.
- DaysSince2019: Esta característica calcula el número de días desde el 1 de enero de 2019, lo cual puede ser útil para capturar tendencias a largo plazo.
- Season: Se crea una característica categórica utilizando pd.cut() para agrupar los meses en estaciones.
- Visualización de Datos:
- Se crea un gráfico de dispersión para visualizar la relación entre el número de días desde 2019 y el precio de la casa, con los puntos coloreados por estación.
- Se genera un mapa de calor para mostrar el precio promedio de la casa por año y mes, lo que puede revelar patrones estacionales en los precios de las viviendas.
Este ejemplo completo demuestra varias técnicas para extraer características significativas de los datos de fecha y visualizarlos para obtener información. Dicha ingeniería de características puede mejorar significativamente el poder predictivo de los modelos de Machine Learning que trabajan con datos de series temporales.
7.1.3 Combinación de Características
La combinación de múltiples características existentes puede crear nuevas características poderosas que capturen relaciones complejas entre variables. Este proceso, conocido como interacción de características o cruzamiento de características, va más allá de las combinaciones lineales simples y puede revelar patrones no lineales en los datos. Al multiplicar, dividir o tomar razones de características existentes, podemos generar nuevos conocimientos que las características individuales podrían no captar por sí solas.
Por ejemplo, en un conjunto de datos con información sobre casas, podrías crear una nueva característica que represente el precio por pie cuadrado dividiendo el precio de la casa por su tamaño en pies cuadrados. Esta característica derivada normaliza el precio en función del tamaño de la casa, revelando potencialmente patrones que ni el precio ni el tamaño por sí solos podrían mostrar. Otros ejemplos podrían incluir:
- Combinar 'número de habitaciones' y 'tamaño total en pies cuadrados' para crear una característica de 'tamaño promedio de habitación'
- Multiplicar 'edad de la casa' por 'número de renovaciones' para capturar el impacto de las actualizaciones en propiedades más antiguas
- Crear una razón de 'tamaño del terreno' a 'tamaño de la casa' para representar la proporción de tierra respecto a la construcción
Estas características combinadas pueden mejorar significativamente la capacidad de un modelo para capturar relaciones matizadas en los datos, mejorando potencialmente su poder predictivo e interpretabilidad. Sin embargo, es importante abordar la combinación de características de manera reflexiva, ya que la creación indiscriminada de nuevas características puede llevar al sobreajuste o aumentar la complejidad del modelo sin obtener ganancias correspondientes en el rendimiento.
Ejemplo: Creación de una Nueva Característica a partir de la Razón de Dos Características
Supongamos que tenemos un conjunto de datos con precios de casas y tamaños de casas (en pies cuadrados). Podemos crear una nueva característica, PricePerSqFt, para normalizar los precios de las casas en función de su tamaño.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {
'HousePrice': [500000, 700000, 600000, 550000, 800000],
'HouseSize': [2000, 3000, 2500, 1800, 3500],
'Bedrooms': [3, 4, 3, 2, 5],
'YearBuilt': [1990, 2005, 2000, 1985, 2010]
}
df = pd.DataFrame(data)
# Create new features
df['PricePerSqFt'] = df['HousePrice'] / df['HouseSize']
df['AvgRoomSize'] = df['HouseSize'] / df['Bedrooms']
df['AgeOfHouse'] = 2023 - df['YearBuilt']
df['PricePerRoom'] = df['HousePrice'] / df['Bedrooms']
# View the new features
print(df)
# Visualize relationships
plt.figure(figsize=(12, 8))
# Scatter plot of Price vs Size, colored by Age
plt.subplot(2, 2, 1)
sns.scatterplot(data=df, x='HouseSize', y='HousePrice', hue='AgeOfHouse', palette='viridis')
plt.title('House Price vs Size (colored by Age)')
# Bar plot of Average Price per Sq Ft by Bedrooms
plt.subplot(2, 2, 2)
sns.barplot(data=df, x='Bedrooms', y='PricePerSqFt')
plt.title('Avg Price per Sq Ft by Bedrooms')
# Heatmap of correlations
plt.subplot(2, 2, 3)
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
# Scatter plot of Price per Room vs Age of House
plt.subplot(2, 2, 4)
sns.scatterplot(data=df, x='AgeOfHouse', y='PricePerRoom')
plt.title('Price per Room vs Age of House')
plt.tight_layout()
plt.show()
# Statistical summary
print(df.describe())
# Correlation analysis
print(df.corr()['HousePrice'].sort_values(ascending=False))
Este ejemplo de código muestra un enfoque completo para la ingeniería de características y el análisis exploratorio de datos. Vamos a profundizar en sus componentes:
- Preparación de Datos:
- Importamos las bibliotecas necesarias: pandas para la manipulación de datos, matplotlib y seaborn para visualización.
- Se expande el conjunto de datos de muestra para incluir más casas y características adicionales como 'Bedrooms' y 'YearBuilt'.
- Ingeniería de Características:
- PricePerSqFt: Normaliza el precio de la casa según el tamaño.
- AvgRoomSize: Calcula el tamaño promedio de las habitaciones.
- AgeOfHouse: Determina la antigüedad de la casa (asumiendo que el año actual es 2023).
- PricePerRoom: Calcula el precio por dormitorio.
- Visualización de Datos:
- Se crea una cuadrícula de 2x2 gráficos para visualizar diferentes aspectos de los datos:
a) Diagrama de dispersión de House Price vs. Size, coloreado por Age.
b) Gráfico de barras que muestra el precio promedio por pie cuadrado para diferentes cantidades de dormitorios.
c) Mapa de calor de correlaciones entre todas las características.
d) Diagrama de dispersión de Price per Room vs. Age of House.
- Se crea una cuadrícula de 2x2 gráficos para visualizar diferentes aspectos de los datos:
- Análisis Estadístico:
- La función describe() proporciona estadísticas descriptivas para todas las columnas numéricas.
- El análisis de correlación muestra qué tan fuerte se correlaciona cada característica con HousePrice.
Este ejemplo completo no solo crea nuevas características, sino que también explora sus relaciones y posibles impactos en los precios de las viviendas. Las visualizaciones y análisis estadísticos proporcionan información que puede guiar en la ingeniería de características o en los procesos de selección de modelos.
7.1.4 Creación de Términos de Interacción
Los términos de interacción son características que capturan el efecto combinado de dos o más variables, ofreciendo una forma poderosa de modelar relaciones complejas en los datos. Estos términos van más allá de las combinaciones lineales simples, permitiendo la representación de interacciones no lineales entre características. Por ejemplo, en el modelado inmobiliario, la interacción entre el tamaño de una casa y su ubicación podría ser más predictiva de su precio que cualquiera de las características por sí sola. Esto se debe a que el valor de metros cuadrados adicionales puede variar significativamente según el vecindario.
Los términos de interacción son especialmente valiosos cuando hay una relación no lineal entre las características y la variable objetivo. Pueden revelar patrones que las características individuales podrían pasar por alto. Por ejemplo, en un contexto de marketing, la interacción entre la edad de un cliente y sus ingresos podría proporcionar información sobre el comportamiento de compra que ni la edad ni los ingresos podrían captar por sí solos. De manera similar, en estudios ambientales, la interacción entre temperatura y humedad podría ser crucial para predecir ciertos fenómenos meteorológicos.
Crear términos de interacción implica multiplicar dos o más características entre sí. Este proceso permite que el modelo aprenda diferentes efectos para una variable en función de los valores de otra. Es importante tener en cuenta que, aunque los términos de interacción pueden mejorar significativamente el rendimiento del modelo, deben usarse con moderación. Agregar demasiados términos de interacción puede llevar al sobreajuste y hacer que el modelo sea más difícil de interpretar. Por lo tanto, es crucial basar la creación de términos de interacción en el conocimiento del dominio o en el análisis exploratorio de datos para asegurarse de que agreguen un valor significativo al modelo.
Ejemplo: Creación de Términos de Interacción
Supongamos que queremos explorar la interacción entre el precio de una casa y el año en que se vendió. Podemos crear un término de interacción multiplicando estas dos características entre sí.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Sample data
data = {
'HousePrice': [500000, 700000, 600000, 550000, 800000],
'YearSold': [2020, 2019, 2021, 2020, 2022],
'SquareFootage': [2000, 2500, 2200, 1800, 3000],
'Bedrooms': [3, 4, 3, 2, 5]
}
df = pd.DataFrame(data)
# Create interaction terms
df['Price_YearInteraction'] = df['HousePrice'] * df['YearSold']
df['Price_SqFtInteraction'] = df['HousePrice'] * df['SquareFootage']
df['PricePerSqFt'] = df['HousePrice'] / df['SquareFootage']
df['PricePerBedroom'] = df['HousePrice'] / df['Bedrooms']
# View the dataframe with new features
print(df)
# Visualize relationships
plt.figure(figsize=(12, 10))
# Scatter plot of Price vs Year, sized by SquareFootage
plt.subplot(2, 2, 1)
sns.scatterplot(data=df, x='YearSold', y='HousePrice', size='SquareFootage', hue='Bedrooms')
plt.title('House Price vs Year Sold')
# Heatmap of correlations
plt.subplot(2, 2, 2)
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
# Scatter plot of Price_YearInteraction vs PricePerSqFt
plt.subplot(2, 2, 3)
sns.scatterplot(data=df, x='Price_YearInteraction', y='PricePerSqFt')
plt.title('Price-Year Interaction vs Price Per Sq Ft')
# Bar plot of average Price Per Bedroom by Year
plt.subplot(2, 2, 4)
sns.barplot(data=df, x='YearSold', y='PricePerBedroom')
plt.title('Avg Price Per Bedroom by Year')
plt.tight_layout()
plt.show()
# Statistical summary
print(df.describe())
# Correlation analysis
print(df.corr()['HousePrice'].sort_values(ascending=False))
Este ejemplo de código demuestra un enfoque completo para crear y analizar términos de interacción en el contexto inmobiliario.
Desglosemos cada parte:
- Preparación de Datos:
- Importamos las bibliotecas necesarias: pandas para la manipulación de datos, matplotlib y seaborn para visualización.
- El conjunto de datos de muestra se expande para incluir más casas y características adicionales como 'SquareFootage' y 'Bedrooms'.
- Ingeniería de Características:
- Price_YearInteraction: Captura la interacción entre el precio de la casa y el año en que se vendió.
- Price_SqFtInteraction: Representa la interacción entre el precio y los pies cuadrados.
- PricePerSqFt: Una característica de razón que normaliza el precio por tamaño.
- PricePerBedroom: Otra característica de razón que muestra el precio por dormitorio.
- Visualización de Datos:
- Se crea una cuadrícula de gráficos 2x2 para visualizar diferentes aspectos de los datos:
a) Diagrama de dispersión de House Price vs. Year Sold, con el tamaño de los puntos representando los pies cuadrados y el color representando el número de dormitorios.
b) Mapa de calor de correlaciones entre todas las características.
c) Diagrama de dispersión de Price-Year Interaction vs. Price Per Sq Ft.
d) Gráfico de barras que muestra el precio promedio por dormitorio en diferentes años.
- Se crea una cuadrícula de gráficos 2x2 para visualizar diferentes aspectos de los datos:
- Análisis Estadístico:
- La función describe() proporciona estadísticas descriptivas para todas las columnas numéricas.
- El análisis de correlación muestra qué tan fuerte se correlaciona cada característica con HousePrice.
Este ejemplo completo no solo crea términos de interacción, sino que también explora sus relaciones con otras características y la variable objetivo (HousePrice). Las visualizaciones y análisis estadísticos proporcionan información que puede guiar en la ingeniería de características o en los procesos de selección de modelos. Por ejemplo, el mapa de calor de correlación puede revelar qué términos de interacción están más fuertemente asociados con los precios de las viviendas, mientras que los gráficos de dispersión pueden mostrar relaciones no lineales que estos términos podrían captar.
7.1.5 Conclusiones Clave y Sus Implicaciones
- Transformaciones matemáticas (como logarítmica o de raíz cuadrada) pueden ayudar a estabilizar la varianza o reducir la asimetría en los datos, mejorando el rendimiento de ciertos modelos de Machine Learning. Estas transformaciones son particularmente útiles cuando se trabaja con características que muestran crecimiento o decaimiento exponencial, o cuando la relación entre variables es no lineal.
- Extracción de características de fecha y hora permite crear nuevas características significativas a partir de columnas de fecha y hora, permitiendo que los modelos capturen patrones estacionales o basados en el tiempo. Esta técnica es crucial para el análisis de series temporales, pronósticos y comprensión de tendencias cíclicas en los datos. Por ejemplo, extraer el día de la semana, el mes o la estación puede revelar patrones importantes en ventas minoristas o consumo de energía.
- Combinación de características como razones o diferencias entre variables existentes puede descubrir relaciones importantes, como normalizar los precios de viviendas por tamaño. Estas características derivadas suelen proporcionar más información interpretativa y significativa que los datos sin procesar. Por ejemplo, en análisis financieros, razones como precio/ganancias o deuda/capital son más informativas que los componentes individuales por sí solos.
- Términos de interacción permiten que el modelo capture los efectos combinados de dos o más características, lo cual puede ser especialmente útil cuando las relaciones entre variables son no lineales. Estos términos pueden mejorar significativamente el rendimiento del modelo al considerar interdependencias complejas. Por ejemplo, en marketing, la interacción entre la edad del cliente y sus ingresos podría predecir mejor el comportamiento de compra que cualquiera de las variables por separado.
Comprender y aplicar estas técnicas de ingeniería de características puede mejorar drásticamente el rendimiento, la interpretabilidad y la robustez de los modelos. Sin embargo, es crucial abordar la creación de características de manera reflexiva, siempre considerando el conocimiento del dominio y los requisitos específicos de la tarea de Machine Learning. La ingeniería de características efectiva requiere una combinación de creatividad, comprensión estadística y experiencia en el dominio.