Ingeniería de Características: Guía Exhaustiva y Práctica
OLTP vs OLAP: Fundamentos de los Sistemas de Datos
Diferencias Fundamentales
OLTP (Online Transaction Processing) y OLAP (Online Analytical Processing) representan dos paradigmas distintos en el manejo de datos empresariales. Mientras que OLTP está diseñado para procesar transacciones en tiempo real de manera rápida y eficiente, OLAP se enfoca en el análisis de datos históricos agregados para la toma de decisiones estratégicas.
Características de OLTP
Los sistemas OLTP se caracterizan por:
- Procesamiento transaccional en tiempo real con operaciones CRUD frecuentes
- Estructura de datos normalizada para minimizar redundancia
- Tiempos de respuesta rápidos (milisegundos) para transacciones individuales
- Datos operacionales actuales de un solo origen
- Arquitectura de tres niveles: presentación, lógica de negocio y almacenamiento
Ejemplo práctico de OLTP:
# Sistema de ventas en línea
transacciones = pd.DataFrame({
'transaction_id': [1, 2, 3, 4, 5],
'customer_id': [101, 102, 101, 103, 102],
'product_id': [201, 202, 203, 201, 202],
'quantity': [2, 1, 3, 1, 2],
'price': [25.99, 15.50, 35.00, 25.99, 15.50],
'timestamp': pd.to_datetime(['2023-05-20 10:30:00', '2023-05-20 11:15:00',
'2023-05-20 12:00:00', '2023-05-20 14:30:00',
'2023-05-20 15:45:00'])
})
Características de OLAP
Los sistemas OLAP presentan:
- Análisis multidimensional de datos históricos agregados
- Estructura desnormalizada optimizada para consultas complejas
- Tiempos de respuesta más lentos (segundos o minutos) pero con análisis profundo
- Datos de múltiples fuentes integrados en cubos dimensionales
- Operaciones analíticas: Roll-up, Drill-down, Slice, Dice y Pivot
Ejemplo práctico de OLAP:
# Cubo de análisis de ventas
cubo_ventas = pd.DataFrame({
'año': [2023, 2023, 2023, 2023],
'mes': ['Mayo', 'Mayo', 'Junio', 'Junio'],
'region': ['Norte', 'Sur', 'Norte', 'Sur'],
'categoria_producto': ['Electrónicos', 'Ropa', 'Electrónicos', 'Ropa'],
'total_ventas': [15000, 8500, 18000, 9200],
'unidades_vendidas': [150, 85, 180, 92]
})
Data Warehouse y Proceso ETL
Conceptos Fundamentales del Data Warehouse
Un Data Warehouse es un almacén centralizado que integra datos de múltiples fuentes para análisis y reporting. Utiliza una arquitectura optimizada para consultas analíticas complejas, típicamente implementando esquemas en estrella o copo de nieve.
El Proceso ETL (Extract, Transform, Load)
El proceso ETL constituye el pipeline fundamental para mover datos desde sistemas operacionales hacia el data warehouse.
1. Extract (Extracción)
La fase de extracción recopila datos de múltiples fuentes:
- Bases de datos transaccionales
- APIs y servicios web
- Archivos planos (CSV, XML, JSON)
- Sistemas legacy
def extraer_datos():
# Múltiples fuentes de datos
crm = pd.read_csv('crm_data.csv')
ventas = pd.read_csv('sales_data.csv')
productos = pd.read_csv('product_data.csv')
return crm, ventas, productos
2. Transform (Transformación)
La transformación aplica reglas de negocio para limpiar, enriquecer y estructurar los datos:
- Limpieza: eliminación de duplicados, valores nulos
- Normalización: estandarización de formatos
- Agregación: cálculos y métricas derivadas
- Validación: aplicación de reglas de calidad
def transformar_datos(crm, ventas, productos):
# Limpieza de datos
crm['email'] = crm['email'].str.lower()
ventas['precio'] = pd.to_numeric(ventas['precio'], errors='coerce')
# Unión de tablas
datos_unidos = ventas.merge(crm, on='cliente_id')
datos_unidos = datos_unidos.merge(productos, on='producto_id')
# Crear características derivadas
datos_unidos['categoria_precio'] = pd.cut(datos_unidos['precio'],
bins=[0, 100, 500, 1000],
labels=['Bajo', 'Medio', 'Alto'])
return datos_unidos
3. Load (Carga)
La carga transfiere los datos transformados al destino final, típicamente separando en tablas de hechos y dimensiones:
def cargar_warehouse(datos_transformados):
# Separar en tablas de hechos y dimensiones
fact_ventas = datos_transformados[['venta_id', 'cliente_id',
'producto_id', 'precio', 'fecha']]
dim_clientes = datos_transformados[['cliente_id', 'nombre',
'email']].drop_duplicates()
# Cargar al data warehouse
fact_ventas.to_sql('fact_ventas', engine, if_exists='replace')
dim_clientes.to_sql('dim_clientes', engine, if_exists='replace')
Tabla Analítica de Datos (TAD): El Corazón del Machine Learning
Principios Fundamentales de la TAD
Una Tabla Analítica de Datos (TAD) representa la estructura optimizada para algoritmos de machine learning. Siguiendo los principios establecidos:
- Una fila = una unidad de análisis (cliente, transacción, producto)
- Matriz de valores continuos, finitos y no nulos
- Cada columna representa una característica medible
- Preparada para alimentar directamente los algoritmos
La Analogía de Cocina en Machine Learning
Esta analogía clarifica el rol de cada componente:
- 🥕 Ingredientes (Variables): Las características extraídas de los datos
- 📝 Receta (Modelo): El algoritmo que combina las características
- 🍽️ Platillo (Predicción): El resultado final del modelo
def crear_tad(datos_raw):
# 1. Definir unidad de análisis (ej: cliente)
tad = datos_raw.groupby('cliente_id').agg({
# Variables demográficas
'edad': 'first',
'ingresos': 'first',
# Variables de comportamiento (agregadas)
'num_compras': 'count',
'total_gastado': 'sum',
'precio_promedio': 'mean'
}).reset_index()
# 2. Crear variables derivadas
tad['gasto_promedio_mensual'] = tad['total_gastado'] / 12
tad['frecuencia_compra'] = tad['num_compras'] / 365
# 3. Verificar calidad TAD
print(f"Valores nulos: {tad.isnull().sum().sum()}")
print(f"Valores infinitos: {np.isinf(tad.select_dtypes(include=[np.number])).sum().sum()}")
return tad
Ejemplo específico de la analogía:
- Ingrediente principal: edad = 45 años
- Ingrediente secundario: ingresos =$52,000
- Platillo resultante: probabilidad_compra = 0.73
Reducción de Dimensionalidad: PCA y Selección de Características
Análisis de Componentes Principales (PCA)
PCA es un método clásico que proyecta datos de alta dimensión a un espacio de menor dimensión, maximizando la varianza conservada. El método busca una transformación ortogonal que identifica las direcciones de máxima variabilidad en los datos.
Fundamentos Matemáticos de PCA
El proceso matemático involucra:
- Estandarización de las variables originales
- Cálculo de la matriz de covarianza
- Descomposición en valores y vectores propios
- Selección de componentes principales basada en varianza explicada
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
def aplicar_pca(X, varianza_objetivo=0.95):
# Estandarizar datos
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# PCA completo para analizar varianza
pca_full = PCA()
pca_full.fit(X_scaled)
# Encontrar componentes para varianza objetivo
cumulative_variance = np.cumsum(pca_full.explained_variance_ratio_)
n_components = np.argmax(cumulative_variance >= varianza_objetivo) + 1
# Aplicar PCA reducido
pca_final = PCA(n_components=n_components)
X_reducido = pca_final.fit_transform(X_scaled)
print(f"Reducción: {X.shape} → {n_components} características")
print(f"Varianza conservada: {cumulative_variance[n_components-1]:.1%}")
return X_reducido, pca_final
Ventajas de PCA
- Maximiza la varianza capturada en cada componente
- Garantiza ortogonalidad entre componentes
- Reduce la multicolinealidad efectivamente
- Útil para visualización de datos complejos
Selección de Características (Feature Selection)
La selección de características identifica las variables más relevantes sin crear combinaciones lineales. Existen tres enfoques principales:
Métodos de Filtrado
Evalúan características independientemente del modelo usando métricas estadísticas:
- Correlación de Pearson
- Test Chi-cuadrado
- Información Mutua
Métodos Wrapper
Utilizan el rendimiento del modelo como criterio de evaluación:
- Sequential Feature Selector
- Recursive Feature Elimination
Métodos Embedded
Integran la selección durante el entrenamiento:
- LASSO Regression
- Random Forest Feature Importance
from sklearn.feature_selection import SelectKBest, f_regression
def seleccionar_caracteristicas(X, y, k=10):
# Selección basada en F-score
selector = SelectKBest(score_func=f_regression, k=k)
X_selected = selector.fit_transform(X, y)
# Características seleccionadas
selected_features = X.columns[selector.get_support()].tolist()
print(f"Características seleccionadas: {selected_features}")
return X_selected, selector
Comparación: PCA vs Selección de Características
| Aspecto | PCA | Selección de Características |
|---|---|---|
| Interpretabilidad | Baja (componentes sintéticos) | Alta (variables originales) |
| Varianza capturada | Máxima por diseño | Variable según método |
| Multicolinealidad | Elimina completamente | Puede persistir |
| Complejidad computacional | Media | Variable según método |
| Uso recomendado | Datos muy correlacionados | Interpretabilidad importante |
Series de Tiempo: Análisis de Acciones de Apple
Características Específicas de Series Temporales
El análisis de series de tiempo requiere características especializadas que capturen patrones temporales, tendencias y volatilidad. Para el análisis de acciones como Apple, se emplean múltiples categorías de características:
Indicadores Técnicos Fundamentales
Medias Móviles
Las medias móviles suavizan fluctuaciones revelando tendencias subyacentes:
def crear_medias_moviles(df, precio_col='precio_cierre'):
# Medias móviles simples
for window in [5, 10, 20, 50, 200]:
df[f'ma_{window}'] = df[precio_col].rolling(window).mean()
df[f'precio_vs_ma{window}'] = (df[precio_col] / df[f'ma_{window}'] - 1) * 100
return df
Indicadores de Volatilidad
Miden la variabilidad de los precios:
# Volatilidad histórica
df['volatilidad_20'] = df['retorno_diario'].rolling(20).std()
df['volatilidad_anualizada'] = df['volatilidad_20'] * np.sqrt(252)
# Bandas de Bollinger
df['bb_superior'] = df['ma_20'] + (2 * df['precio_cierre'].rolling(20).std())
df['bb_inferior'] = df['ma_20'] - (2 * df['precio_cierre'].rolling(20).std())
df['bb_posicion'] = (df['precio_cierre'] - df['bb_inferior']) / (df['bb_superior'] - df['bb_inferior'])
RSI (Relative Strength Index)
Mide condiciones de sobrecompra/sobreventa:
def calcular_rsi(df, precio_col='precio_cierre', window=14):
delta = df[precio_col].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
rs = gain / loss
df['rsi'] = 100 - (100 / (1 + rs))
return df
Características de Retraso (Lags)
Las características lag capturan dependencias temporales:
def crear_lags(df, columnas, max_lag=10):
for col in columnas:
for lag in range(1, max_lag + 1):
df[f'{col}_lag_{lag}'] = df[col].shift(lag)
return df
Ejemplo Completo: Análisis de Apple
Aplicando el análisis completo a datos de Apple:
def analisis_completo_apple(df):
# 1. Retornos básicos
df['retorno_diario'] = df['precio_cierre'].pct_change()
df['log_retorno'] = np.log(df['precio_cierre'] / df['precio_cierre'].shift(1))
# 2. Medias móviles y señales
df = crear_medias_moviles(df)
# 3. Volatilidad y riesgo
df['volatilidad_20'] = df['retorno_diario'].rolling(20).std()
df['var_95'] = df['retorno_diario'].rolling(50).quantile(0.05) # Value at Risk
# 4. Indicadores técnicos
df = calcular_rsi(df)
# 5. Características temporales
df['dia_semana'] = df['fecha'].dt.dayofweek
df['mes'] = df['fecha'].dt.month
df['trimestre'] = df['fecha'].dt.quarter
# 6. Variables lag
df = crear_lags(df, ['precio_cierre', 'retorno_diario', 'volatilidad_20'], max_lag=5)
return df
Métricas Relevantes para Apple
Para el período analizado, los datos muestran:
- Retorno anualizado: 11.2%
- Volatilidad anualizada: 30.1%
- Ratio Sharpe estimado: 0.39
- Rango de precios:153.00
TAD para Series Temporales
La creación de TAD para series temporales utiliza ventanas deslizantes:
def crear_tad_temporal(df, ventana=60):
tad_rows = []
for i in range(ventana, len(df)):
row = {}
ventana_data = df.iloc[i-ventana:i]
# Estadísticas de ventana
row['precio_medio'] = ventana_data['precio_cierre'].mean()
row['volatilidad_media'] = ventana_data['volatilidad_20'].mean()
row['rsi_promedio'] = ventana_data['rsi'].mean()
# Objetivo (día siguiente)
row['precio_siguiente'] = df.iloc[i]['precio_cierre']
tad_rows.append(row)
return pd.DataFrame(tad_rows)
Plantillas de Código Implementadas
Se han desarrollado plantillas completas para cada concepto, disponibles en el archivo adjunto que incluye:
- Código OLTP vs OLAP: Estructuras transaccionales y analíticas
- Proceso ETL completo: Extract, Transform, Load
- Creación de TAD: Tabla Analítica optimizada
- Reducción dimensional: PCA y selección de características
- Series temporales: Análisis técnico completo
Estas plantillas proporcionan una base sólida para implementar ingeniería de características en proyectos reales de machine learning, siguiendo las mejores prácticas de la industria y los principios fundamentales establecidos en el transcript de ingeniería de características.
Hi :)
Matemáticas
Vectores
Álgebra Lineal
Geometría Analítica
Producto Punto
Espacios Vectoriales
Ortogonalidad
Normalización
Funciones
Álgebra
Composición de Funciones
Función Inversa
Combinación de Funciones
Transformaciones Gráficas
Aplicaciones Económicas
Interés Compuesto
Proporcionalidad
R
Data
Machine Learning
Aprendizaje Supervisado
Inteligencia Artificial
Clasificación
Regresión
Deep Learning