UT4: Datos Especiales¶
Introducción¶
Esta unidad se centra en el manejo y procesamiento de tipos de datos especiales que requieren técnicas específicas de extracción y transformación de features: datos geoespaciales, audio e imágenes.
Datos Geoespaciales¶
Conceptos Fundamentals¶
Datos geoespaciales: Información que tiene un componente de ubicación geográfica asociado.
Tipos de geometrías:
- Point: Ubicación específica (lat, lon)
- LineString: Secuencia de puntos conectados
- Polygon: Área cerrada definida por sus límites
- MultiPoint, MultiLineString, MultiPolygon: Colecciones de geometrías
GeoPandas¶
GeoPandas extiende pandas para trabajar con datos geoespaciales.
import geopandas as gpd
from shapely.geometry import Point, Polygon
# Crear GeoDataFrame
gdf = gpd.GeoDataFrame(
data,
geometry=gpd.points_from_xy(data.longitude, data.latitude),
crs="EPSG:4326" # Sistema de coordenadas WGS84
)
# Operaciones espaciales
gdf['area'] = gdf.geometry.area
gdf['centroid'] = gdf.geometry.centroid
Shapely¶
Librería para operaciones geométricas.
from shapely.geometry import Point, Polygon
from shapely.ops import unary_union
# Crear geometrías
point = Point(0, 0)
polygon = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
# Operaciones
distance = point.distance(polygon)
contains = polygon.contains(point)
intersection = polygon1.intersection(polygon2)
Feature Engineering Geoespacial¶
# Distancias a puntos de interés
gdf['dist_to_center'] = gdf.geometry.distance(city_center)
# Área y perímetro
gdf['area'] = gdf.geometry.area
gdf['perimeter'] = gdf.geometry.length
# Buffers
gdf['buffer_500m'] = gdf.geometry.buffer(500)
# Conteo de vecinos
gdf['neighbors_count'] = gdf.geometry.apply(
lambda x: gdf[gdf.geometry.intersects(x.buffer(1000))].shape[0]
)
# Coordenadas
gdf['latitude'] = gdf.geometry.y
gdf['longitude'] = gdf.geometry.x
Datos de Audio¶
Conceptos Fundamentales¶
Señal de audio: Representación de ondas sonoras en el dominio del tiempo.
Propiedades clave:
- Sample rate: Frecuencia de muestreo (Hz)
- Duration: Duración en segundos
- Amplitude: Magnitud de la señal
Librosa¶
Librería especializada en análisis de audio.
import librosa
import numpy as np
# Cargar audio
audio, sr = librosa.load('audio.wav', sr=22050)
# Información básica
duration = librosa.get_duration(y=audio, sr=sr)
Feature Extraction de Audio¶
# Características temporales
zero_crossing_rate = librosa.feature.zero_crossing_rate(audio)[0]
energy = np.sum(audio ** 2) / len(audio)
# Características espectrales
spectral_centroids = librosa.feature.spectral_centroid(y=audio, sr=sr)[0]
spectral_rolloff = librosa.feature.spectral_rolloff(y=audio, sr=sr)[0]
# MFCCs (Mel-Frequency Cepstral Coefficients)
mfccs = librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=13)
mfcc_mean = np.mean(mfccs, axis=1)
mfcc_std = np.std(mfccs, axis=1)
# Chroma features
chroma = librosa.feature.chroma_stft(y=audio, sr=sr)
# Tempo
tempo, beats = librosa.beat.beat_track(y=audio, sr=sr)
Espectrogramas¶
# Espectrograma
D = librosa.stft(audio)
S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
# Mel-spectrogram
mel_spec = librosa.feature.melspectrogram(y=audio, sr=sr)
mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max)
Datos de Imágenes¶
OpenCV¶
Librería para procesamiento de imágenes.
import cv2
import numpy as np
# Cargar imagen
img = cv2.imread('image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Información básica
height, width = gray.shape
total_pixels = height * width
Feature Extraction de Imágenes¶
Características de bajo nivel:
# Estadísticas de color
mean_color = np.mean(img, axis=(0, 1))
std_color = np.std(img, axis=(0, 1))
# Histogramas
hist_r = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_g = cv2.calcHist([img], [1], None, [256], [0, 256])
hist_b = cv2.calcHist([img], [2], None, [256], [0, 256])
# Bordes
edges = cv2.Canny(gray, 100, 200)
edge_density = np.sum(edges > 0) / total_pixels
# Texturas con GLCM
from skimage.feature import greycomatrix, greycoprops
glcm = greycomatrix(gray, [1], [0, np.pi/4, np.pi/2], levels=256)
contrast = greycoprops(glcm, 'contrast')[0, 0]
dissimilarity = greycoprops(glcm, 'dissimilarity')[0, 0]
homogeneity = greycoprops(glcm, 'homogeneity')[0, 0]
Características de forma:
# Detección de contornos
contours, _ = cv2.findContours(
edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
# Features de forma
if contours:
cnt = contours[0]
area = cv2.contourArea(cnt)
perimeter = cv2.arcLength(cnt, True)
x, y, w, h = cv2.boundingRect(cnt)
aspect_ratio = float(w) / h
Detectores de características:
# SIFT (Scale-Invariant Feature Transform)
sift = cv2.SIFT_create()
keypoints, descriptors = sift.detectAndCompute(gray, None)
# ORB (Oriented FAST and Rotated BRIEF)
orb = cv2.ORB_create()
keypoints, descriptors = orb.detectAndCompute(gray, None)
# Features: número de keypoints, estadísticas de descriptors
n_keypoints = len(keypoints)
descriptor_mean = np.mean(descriptors, axis=0) if descriptors is not None else 0
Integración en Pipelines de ML¶
Transformadores Personalizados¶
from sklearn.base import BaseEstimator, TransformerMixin
class GeoFeatureExtractor(BaseEstimator, TransformerMixin):
def __init__(self, reference_point):
self.reference_point = reference_point
def fit(self, X, y=None):
return self
def transform(self, X):
features = []
for geom in X:
features.append([
geom.distance(self.reference_point),
geom.area,
geom.length,
geom.centroid.x,
geom.centroid.y
])
return np.array(features)
class AudioFeatureExtractor(BaseEstimator, TransformerMixin):
def __init__(self, sr=22050):
self.sr = sr
def fit(self, X, y=None):
return self
def transform(self, X):
features = []
for audio_path in X:
audio, sr = librosa.load(audio_path, sr=self.sr)
mfccs = librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=13)
features.append(np.concatenate([
np.mean(mfccs, axis=1),
np.std(mfccs, axis=1)
]))
return np.array(features)
class ImageFeatureExtractor(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
features = []
for img_path in X:
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Extraer múltiples features
mean_color = np.mean(img, axis=(0, 1))
std_color = np.std(img, axis=(0, 1))
edges = cv2.Canny(gray, 100, 200)
edge_density = np.sum(edges > 0) / edges.size
features.append(np.concatenate([
mean_color,
std_color,
[edge_density]
]))
return np.array(features)
Pipeline Completo¶
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
# Combinar múltiples tipos de features
pipeline = Pipeline([
('features', FeatureUnion([
('geo', GeoFeatureExtractor(reference_point)),
('audio', AudioFeatureExtractor()),
('image', ImageFeatureExtractor())
])),
('scaler', StandardScaler()),
('classifier', RandomForestClassifier())
])
# Entrenar
pipeline.fit(X_train, y_train)
# Predecir
y_pred = pipeline.predict(X_test)
Consideraciones Especiales¶
Performance¶
Datos geoespaciales:
- Usar índices espaciales para consultas rápidas
- Simplificar geometrías complejas cuando sea apropiado
- Vectorizar operaciones cuando sea posible
Audio e imágenes:
- Pre-calcular features cuando sea posible
- Usar batch processing para grandes volúmenes
- Considerar compresión y downsampling
Almacenamiento¶
# Guardar features extraídas
import joblib
# Extraer y guardar
features = feature_extractor.transform(data)
joblib.dump(features, 'extracted_features.pkl')
# Cargar features pre-calculadas
features = joblib.load('extracted_features.pkl')
Validación¶
# Validación espacial: considerar autocorrelación espacial
from sklearn.model_selection import GroupKFold
# Agrupar por región para evitar data leakage
groups = gdf['region_id']
gkf = GroupKFold(n_splits=5)
for train_idx, test_idx in gkf.split(X, y, groups):
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
Recursos Adicionales¶
GeoPandas y Shapely:
- Documentación oficial de GeoPandas
- Tutoriales de análisis geoespacial
- Proyecciones y sistemas de coordenadas
Audio:
- Documentación de librosa
- Teoría de procesamiento de señales
- Music Information Retrieval (MIR)
Imágenes:
- Documentación de OpenCV
- Computer Vision: Algorithms and Applications
- Deep Learning para imágenes
Integración:
- Scikit-learn custom transformers
- Pipeline best practices
- Feature Union y Column Transformer
Conclusión¶
El manejo de datos especiales requiere:
- Comprensión del dominio específico
- Selección apropiada de features a extraer
- Integración efectiva en pipelines de ML
- Consideración de aspectos de performance y almacenamiento
- Validación apropiada según el tipo de dato
La correcta extracción y transformación de features de datos geoespaciales, audio e imágenes permite incorporar información rica y valiosa en modelos de machine learning.