Ejemplo DBSCAN para precios#
Creación de una serie de tiempo con saltos:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN
# Generar datos de precios simulados
np.random.seed(34)
n_samples = 1000
prices = np.cumsum(np.random.normal(loc=0, scale=1, size=n_samples))
# Introducir algunos saltos
jump_indices = np.random.choice(n_samples, size=10, replace=False)
prices[jump_indices] += np.random.normal(loc=0, scale=20, size=10)
# Calcular los rendimientos (diferencias en los precios)
returns = np.diff(prices)
# Visualizar el precio
plt.figure(figsize=(14, 7))
plt.plot(prices, label="Precios")
plt.xlabel("Tiempo")
plt.ylabel("Precios")
plt.title("Serie de tiempo con saltos")
plt.legend()
plt.show()
Rendimientos:
# Calcular los rendimientos (diferencias en los precios)
returns = np.diff(prices)
# Escalar los rendimientos
scaler = StandardScaler()
returns_scaled = scaler.fit_transform(returns.reshape(-1, 1))
# Visualizar los rendimientos
plt.figure(figsize=(14, 7))
plt.plot(returns, label="Rendimientos")
plt.xlabel("Tiempo")
plt.ylabel("Rendimientos")
plt.title("Rendimientos")
plt.legend()
plt.show()
Ajuste modelo DBSCAN:
# Aplicar DBSCAN para identificar saltos
db = DBSCAN(eps=1, min_samples=5)
db_labels = db.fit_predict(returns_scaled)
El cluster -1 es el de los datos atípicos, en este caso, los saltos.
# Identificar los índices de los saltos
jump_points = np.where(db_labels == -1)[0]
print(jump_points)
print("Cantidad de saltos identificados:", len(jump_points))
[174 175 256 257 353 354 456 457 502 503 530 531 965 966]
Cantidad de saltos identificados: 14
# Visualizar los precios y los saltos identificados
plt.figure(figsize=(14, 7))
plt.plot(prices, label="Precios")
plt.scatter(
jump_points + 1,
prices[jump_points + 1], # +1 para compensar la diferencia de rendimientos
color="darkred",
label="Saltos",
marker="o",
)
plt.xlabel("Tiempo")
plt.ylabel("Precios")
plt.title("Identificación de Saltos en los Precios usando DBSCAN")
plt.legend()
plt.show()