Spaces:
Running
Running
Christoph Hemmer
commited on
Commit
·
e1b0bd6
1
Parent(s):
3512ab7
improve preprocessing stability
Browse files
dynamix/preprocessing_utilities.py
CHANGED
|
@@ -388,12 +388,12 @@ class BoxCoxTransformer:
|
|
| 388 |
|
| 389 |
class Detrending:
|
| 390 |
"""
|
| 391 |
-
Applies
|
| 392 |
"""
|
| 393 |
@staticmethod
|
| 394 |
-
def
|
| 395 |
"""
|
| 396 |
-
|
| 397 |
|
| 398 |
Args:
|
| 399 |
t: Time points
|
|
@@ -408,7 +408,7 @@ class Detrending:
|
|
| 408 |
@staticmethod
|
| 409 |
def fit_objective(params, data):
|
| 410 |
"""
|
| 411 |
-
Objective function for
|
| 412 |
|
| 413 |
Args:
|
| 414 |
params: Model parameters
|
|
@@ -418,13 +418,13 @@ class Detrending:
|
|
| 418 |
Sum of squared errors
|
| 419 |
"""
|
| 420 |
t = np.arange(1, len(data) + 1)
|
| 421 |
-
predicted = Detrending.
|
| 422 |
return np.sum((data - predicted) ** 2)
|
| 423 |
|
| 424 |
@staticmethod
|
| 425 |
def apply_detrending(data):
|
| 426 |
"""
|
| 427 |
-
Apply
|
| 428 |
|
| 429 |
Args:
|
| 430 |
data: Input data tensor of shape (seq_length, N)
|
|
@@ -434,6 +434,11 @@ class Detrending:
|
|
| 434 |
"""
|
| 435 |
# Convert to numpy
|
| 436 |
data_np, is_torch, device, dtype = TimeSeriesProcessor.to_numpy(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
|
| 438 |
seq_length, n_dims = data_np.shape
|
| 439 |
detrended_data = np.zeros_like(data_np)
|
|
@@ -441,13 +446,13 @@ class Detrending:
|
|
| 441 |
|
| 442 |
for dim in range(n_dims):
|
| 443 |
# Define the objective function for this dimension
|
| 444 |
-
objective = lambda params: Detrending.fit_objective(params,
|
| 445 |
|
| 446 |
# Initial parameter guess
|
| 447 |
-
initial_params = [0.0, 1.0,
|
| 448 |
|
| 449 |
# Bounds for parameters
|
| 450 |
-
bounds = [(None, None), (0.
|
| 451 |
|
| 452 |
# Optimize
|
| 453 |
result = optimize.minimize(
|
|
@@ -456,17 +461,20 @@ class Detrending:
|
|
| 456 |
method='L-BFGS-B',
|
| 457 |
bounds=bounds,
|
| 458 |
options={
|
| 459 |
-
'maxiter':
|
| 460 |
'gtol': 1e-6,
|
| 461 |
'maxfun': 1500,
|
| 462 |
'maxcor': 10
|
| 463 |
}
|
| 464 |
)
|
| 465 |
optimal_params = np.round(result.x, 3)
|
|
|
|
|
|
|
|
|
|
| 466 |
|
| 467 |
# Calculate trend and detrend the data
|
| 468 |
t = np.arange(1, seq_length + 1)
|
| 469 |
-
trend = Detrending.
|
| 470 |
detrended_data[:, dim] = data_np[:, dim] - trend
|
| 471 |
|
| 472 |
# Store parameters for inverse transformation
|
|
@@ -502,7 +510,7 @@ class Detrending:
|
|
| 502 |
# Add trend back to each dimension
|
| 503 |
for dim in range(min(n_dims, len(detrending_params))):
|
| 504 |
params = detrending_params[dim]
|
| 505 |
-
trend = Detrending.
|
| 506 |
data_np[:, dim] = data_np[:, dim] + trend
|
| 507 |
|
| 508 |
# Convert back to torch if needed
|
|
|
|
| 388 |
|
| 389 |
class Detrending:
|
| 390 |
"""
|
| 391 |
+
Applies detrending model to time series data.
|
| 392 |
"""
|
| 393 |
@staticmethod
|
| 394 |
+
def trend_model(t, params):
|
| 395 |
"""
|
| 396 |
+
Model for detrending
|
| 397 |
|
| 398 |
Args:
|
| 399 |
t: Time points
|
|
|
|
| 408 |
@staticmethod
|
| 409 |
def fit_objective(params, data):
|
| 410 |
"""
|
| 411 |
+
Objective function for trend model fitting
|
| 412 |
|
| 413 |
Args:
|
| 414 |
params: Model parameters
|
|
|
|
| 418 |
Sum of squared errors
|
| 419 |
"""
|
| 420 |
t = np.arange(1, len(data) + 1)
|
| 421 |
+
predicted = Detrending.trend_model(t, params)
|
| 422 |
return np.sum((data - predicted) ** 2)
|
| 423 |
|
| 424 |
@staticmethod
|
| 425 |
def apply_detrending(data):
|
| 426 |
"""
|
| 427 |
+
Apply trend model to data
|
| 428 |
|
| 429 |
Args:
|
| 430 |
data: Input data tensor of shape (seq_length, N)
|
|
|
|
| 434 |
"""
|
| 435 |
# Convert to numpy
|
| 436 |
data_np, is_torch, device, dtype = TimeSeriesProcessor.to_numpy(data)
|
| 437 |
+
|
| 438 |
+
# Apply min max scaling for a more stable trend fit
|
| 439 |
+
_min = np.min(data_np)
|
| 440 |
+
_max = np.max(data_np)
|
| 441 |
+
data_scaled = (data_np - _min) / (_max - _min)
|
| 442 |
|
| 443 |
seq_length, n_dims = data_np.shape
|
| 444 |
detrended_data = np.zeros_like(data_np)
|
|
|
|
| 446 |
|
| 447 |
for dim in range(n_dims):
|
| 448 |
# Define the objective function for this dimension
|
| 449 |
+
objective = lambda params: Detrending.fit_objective(params, data_scaled[:, dim])
|
| 450 |
|
| 451 |
# Initial parameter guess
|
| 452 |
+
initial_params = [0.0, 1.0, data_scaled[0,dim]]
|
| 453 |
|
| 454 |
# Bounds for parameters
|
| 455 |
+
bounds = [(None, None), (0.0, 3.0), (None, None)]
|
| 456 |
|
| 457 |
# Optimize
|
| 458 |
result = optimize.minimize(
|
|
|
|
| 461 |
method='L-BFGS-B',
|
| 462 |
bounds=bounds,
|
| 463 |
options={
|
| 464 |
+
'maxiter': 5000,
|
| 465 |
'gtol': 1e-6,
|
| 466 |
'maxfun': 1500,
|
| 467 |
'maxcor': 10
|
| 468 |
}
|
| 469 |
)
|
| 470 |
optimal_params = np.round(result.x, 3)
|
| 471 |
+
#Adjust params to min max scale
|
| 472 |
+
optimal_params[0] = (_max - _min) * optimal_params[0]
|
| 473 |
+
optimal_params[2] = (_max - _min) * optimal_params[2] + _min
|
| 474 |
|
| 475 |
# Calculate trend and detrend the data
|
| 476 |
t = np.arange(1, seq_length + 1)
|
| 477 |
+
trend = Detrending.trend_model(t, optimal_params)
|
| 478 |
detrended_data[:, dim] = data_np[:, dim] - trend
|
| 479 |
|
| 480 |
# Store parameters for inverse transformation
|
|
|
|
| 510 |
# Add trend back to each dimension
|
| 511 |
for dim in range(min(n_dims, len(detrending_params))):
|
| 512 |
params = detrending_params[dim]
|
| 513 |
+
trend = Detrending.trend_model(t, params)
|
| 514 |
data_np[:, dim] = data_np[:, dim] + trend
|
| 515 |
|
| 516 |
# Convert back to torch if needed
|