Tonic commited on
Commit
6347217
·
1 Parent(s): 2384e68

adds improved predictions for chronos model

Browse files
Files changed (1) hide show
  1. app.py +27 -21
app.py CHANGED
@@ -295,7 +295,7 @@ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5
295
  if strategy == "chronos":
296
  try:
297
  # Prepare data for Chronos
298
- # Use Close prices instead of returns for better prediction
299
  prices = df['Close'].values
300
 
301
  # Calculate returns for additional context
@@ -349,12 +349,9 @@ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5
349
 
350
  with torch.inference_mode():
351
  try:
352
- # Generate multiple predictions for ensemble
353
- num_ensemble = 5
354
- all_predictions = []
355
-
356
- for _ in range(num_ensemble):
357
- # Use predict_quantiles for probabilistic forecasts
358
  quantiles, mean = pipe.predict_quantiles(
359
  context=context,
360
  prediction_length=actual_prediction_length,
@@ -368,20 +365,29 @@ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5
368
  quantiles = quantiles.detach().cpu().numpy()
369
  mean = mean.detach().cpu().numpy()
370
 
371
- # Store predictions
372
- all_predictions.append((quantiles, mean))
373
-
374
- # Ensemble the predictions
375
- ensemble_quantiles = np.mean([p[0] for p in all_predictions], axis=0)
376
- ensemble_mean = np.mean([p[1] for p in all_predictions], axis=0)
377
-
378
- # Denormalize predictions
379
- mean_pred = scaler.inverse_transform(ensemble_mean.reshape(-1, 1)).flatten()
380
- lower_bound = scaler.inverse_transform(ensemble_quantiles[0, :, 0].reshape(-1, 1)).flatten()
381
- upper_bound = scaler.inverse_transform(ensemble_quantiles[0, :, 2].reshape(-1, 1)).flatten()
382
-
383
- # Calculate standard deviation from quantiles
384
- std_pred = (upper_bound - lower_bound) / (2 * 1.645) # 90% confidence interval
 
 
 
 
 
 
 
 
 
385
 
386
  # If we had to limit the prediction length, extend the prediction
387
  if actual_prediction_length < prediction_days:
 
295
  if strategy == "chronos":
296
  try:
297
  # Prepare data for Chronos
298
+ # Use Close prices for prediction
299
  prices = df['Close'].values
300
 
301
  # Calculate returns for additional context
 
349
 
350
  with torch.inference_mode():
351
  try:
352
+ # Generate predictions using Chronos
353
+ # First try with predict_quantiles
354
+ try:
 
 
 
355
  quantiles, mean = pipe.predict_quantiles(
356
  context=context,
357
  prediction_length=actual_prediction_length,
 
365
  quantiles = quantiles.detach().cpu().numpy()
366
  mean = mean.detach().cpu().numpy()
367
 
368
+ # Denormalize predictions
369
+ mean_pred = scaler.inverse_transform(mean.reshape(-1, 1)).flatten()
370
+ lower_bound = scaler.inverse_transform(quantiles[0, :, 0].reshape(-1, 1)).flatten()
371
+ upper_bound = scaler.inverse_transform(quantiles[0, :, 2].reshape(-1, 1)).flatten()
372
+
373
+ # Calculate standard deviation from quantiles
374
+ std_pred = (upper_bound - lower_bound) / (2 * 1.645) # 90% confidence interval
375
+
376
+ except Exception as e:
377
+ print(f"predict_quantiles failed, trying predict: {str(e)}")
378
+ # Fallback to predict if predict_quantiles fails
379
+ prediction = pipe.predict(
380
+ context=context,
381
+ prediction_length=actual_prediction_length,
382
+ num_samples=100
383
+ ).detach().cpu().numpy()
384
+
385
+ if prediction is None or prediction.size == 0:
386
+ raise ValueError("Chronos returned empty prediction")
387
+
388
+ # Calculate mean and std from samples
389
+ mean_pred = scaler.inverse_transform(prediction.mean(axis=0).reshape(-1, 1)).flatten()
390
+ std_pred = prediction.std(axis=0) * (scaler.data_max_ - scaler.data_min_)
391
 
392
  # If we had to limit the prediction length, extend the prediction
393
  if actual_prediction_length < prediction_days: