Christoph Hemmer commited on
Commit
e1b0bd6
·
1 Parent(s): 3512ab7

improve preprocessing stability

Browse files
Files changed (1) hide show
  1. dynamix/preprocessing_utilities.py +20 -12
dynamix/preprocessing_utilities.py CHANGED
@@ -388,12 +388,12 @@ class BoxCoxTransformer:
388
 
389
  class Detrending:
390
  """
391
- Applies exponential detrending to time series data.
392
  """
393
  @staticmethod
394
- def exp_model(t, params):
395
  """
396
- Exponential model for detrending
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 exponential model fitting
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.exp_model(t, params)
422
  return np.sum((data - predicted) ** 2)
423
 
424
  @staticmethod
425
  def apply_detrending(data):
426
  """
427
- Apply exponential detrending to data
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, data_np[:, dim])
445
 
446
  # Initial parameter guess
447
- initial_params = [0.0, 1.0, data_np[0,dim]]
448
 
449
  # Bounds for parameters
450
- bounds = [(None, None), (0.1, 3.0), (None, None)]
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': 1000,
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.exp_model(t, optimal_params)
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.exp_model(t, params)
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