Using TimeCopilot with AWS Bedrock¶
Requirements¶
- An AWS account
- Access to Bedrock in that account
- Through a AWS Bedrock API key
- Through a standard AWS access key set
Dependencies¶
import nest_asyncio
nest_asyncio.apply()
from timecopilot import TimeCopilot
import pandas as pd
Environment Variables¶
Api keys and other configuration elements may need to be loaded into the environment so pydantic can read them during setup, at least when specifying the llm with a string.
If using a Bedrock API key, AWS_DEFAULT_REGION needs to be set to your preferred region. You'll also need to set either AWS_BEARER_TOKEN if using a bedrock api key or AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY if using a standard AWS access key.
This is how you would load the environment variables in in a Unix-like system:
export AWS_DEFAULT_REGION='us-east-1' # or your preferred region
# and one of the following:
export AWS_BEARER_TOKEN_BEDROCK='your-api-key'
# or:
export AWS_ACCESS_KEY_ID='your-access-key'
export AWS_SECRET_ACCESS_KEY='your-secret-key'
If you store your environment variablesles in a .env file, you can use the following load them into your environment from the file:
export $(grep -v '^#' .env | xargs)
Or you could load it in python with dotenv:
from dotenv import load_dotenv
load_dotenv()
True
TimeCopilot Agent¶
TimeCopilot uses Pydantic to work with llms, so you specify the LLM the same way you'd specify an Agent with Pydantic. Either with a string in the form 'bedrock:model-id' or instantiating a model with pydantic_ai.models.bedrock.BedrockConverseModel. When using Bedrock, models are specified with a Model ID which you can find by going to a model in Bedrock's model catalog and looking at the Model ID field for that model.
For more details on how Pydantic works with Bedrock, see the Pydantic docs on bedrock
String example:¶
tc = TimeCopilot(
llm='bedrock:us.anthropic.claude-3-5-sonnet-20241022-v2:0',
)
BedrockConverseModel example:¶
If you want to load your keys with a non-environment based method, this is where you would use those keys by instantiating BedrockConverseModel with a BedrockProvider.
from pydantic_ai.models.bedrock import BedrockConverseModel
model = BedrockConverseModel(
'us.anthropic.claude-3-5-sonnet-20241022-v2:0'
)
tc = TimeCopilot(
llm=model,
)
Use your TimeCopilot agent¶
Load your data¶
df = pd.read_csv("https://timecopilot.s3.amazonaws.com/public/data/air_passengers.csv")
Generate Forecasts¶
result = tc.forecast(df=df)
1it [00:00, 122.86it/s] 1it [00:00, 21.17it/s] 1it [00:00, 8.47it/s] 0it [00:00, ?it/s]11:33:56 - cmdstanpy - INFO - Chain [1] start processing 11:33:56 - cmdstanpy - INFO - Chain [1] done processing 1it [00:03, 3.61s/it] 1it [00:00, 152.35it/s] 11:34:01 - cmdstanpy - INFO - Chain [1] start processing 11:34:01 - cmdstanpy - INFO - Chain [1] done processing 0it [00:00, ?it/s]11:34:06 - cmdstanpy - INFO - Chain [1] start processing 11:34:06 - cmdstanpy - INFO - Chain [1] done processing 1it [00:03, 3.05s/it]11:34:09 - cmdstanpy - INFO - Chain [1] start processing 11:34:09 - cmdstanpy - INFO - Chain [1] done processing 2it [00:06, 3.04s/it]11:34:12 - cmdstanpy - INFO - Chain [1] start processing 11:34:12 - cmdstanpy - INFO - Chain [1] done processing 3it [00:09, 3.10s/it]11:34:15 - cmdstanpy - INFO - Chain [1] start processing 11:34:15 - cmdstanpy - INFO - Chain [1] done processing 4it [00:12, 3.12s/it]11:34:18 - cmdstanpy - INFO - Chain [1] start processing 11:34:19 - cmdstanpy - INFO - Chain [1] done processing 5it [00:15, 3.14s/it]11:34:22 - cmdstanpy - INFO - Chain [1] start processing 11:34:22 - cmdstanpy - INFO - Chain [1] done processing 6it [00:18, 3.14s/it]11:34:25 - cmdstanpy - INFO - Chain [1] start processing 11:34:25 - cmdstanpy - INFO - Chain [1] done processing 7it [00:22, 3.21s/it]11:34:28 - cmdstanpy - INFO - Chain [1] start processing 11:34:28 - cmdstanpy - INFO - Chain [1] done processing 8it [00:25, 3.21s/it]11:34:31 - cmdstanpy - INFO - Chain [1] start processing 11:34:31 - cmdstanpy - INFO - Chain [1] done processing 9it [00:28, 3.16s/it]11:34:34 - cmdstanpy - INFO - Chain [1] start processing 11:34:34 - cmdstanpy - INFO - Chain [1] done processing 10it [00:31, 3.18s/it]11:34:38 - cmdstanpy - INFO - Chain [1] start processing 11:34:38 - cmdstanpy - INFO - Chain [1] done processing 11it [00:34, 3.16s/it]
print(result)
AgentRunResult(output=ForecastAgentOutput(tsfeatures_analysis='The time series analysis reveals strong seasonal and trend components:\n1. High seasonal strength (0.98) indicates pronounced yearly patterns\n2. Strong positive autocorrelation (x_acf1: 0.95) suggests strong trend\n3. Significant Holt-Winters seasonality (hw_gamma: 0.75) confirms seasonal importance\n4. High stability (0.93) indicates consistent patterns\n5. Non-stationary series (KPSS: 2.74) confirms strong trend\n6. Clear seasonal peaks (July) and troughs (November)', selected_model='Prophet', model_details='Prophet is a decomposition-based forecasting model developed by Facebook that:\n1. Handles multiple seasonalities automatically\n2. Is robust to missing data and outliers\n3. Automatically detects trend changes\n4. Incorporates holiday effects\n5. Works well with strong seasonal patterns and trends\n6. Uses Bayesian methods for uncertainty estimation', model_comparison='Cross-validation results (MASE):\n1. Prophet: 1.09 (best performer)\n2. DynamicOptimizedTheta: 1.66\n3. AutoETS: 2.38\n4. AutoARIMA: 2.40\n5. SeasonalNaive: 2.49\n\nProphet significantly outperformed other models, showing superior handling of the strong seasonal patterns and trend. The DynamicOptimizedTheta performed second-best but with notably higher error. Traditional models (AutoETS, AutoARIMA) struggled with the combination of strong trend and seasonality.', is_better_than_seasonal_naive=True, reason_for_selection='Prophet was selected because:\n1. Best MASE score (1.09) among all tested models\n2. Significantly outperformed the seasonal naive benchmark (2.49)\n3. Well-suited for the identified strong seasonal patterns\n4. Capable of handling the pronounced trend component\n5. Robust to the detected anomalies\n6. Provides good uncertainty estimates', forecast_analysis='The forecast shows:\n1. Continuing upward trend in passenger numbers\n2. Preserved seasonal pattern with peaks in summer months\n3. Clear seasonal amplitude that increases with the trend\n4. Forecast maintains realistic growth rate based on historical patterns\n5. Summer peaks (July-August) consistently show highest passenger numbers\n6. Winter troughs (November-January) show expected seasonal dips\n7. Growth trajectory appears sustainable and aligned with historical patterns', anomaly_analysis='Anomaly analysis reveals:\n1. 8 anomalies detected (6.1% of data points)\n2. Concentrated in summer months (July-August)\n3. Most anomalies in later years (1955-1960)\n4. Suggests unusual peak season activity\n5. Pattern indicates systematic summer overperformance\n6. Anomalies align with rapid growth periods\n7. No anomalies in winter months, indicating stable low-season patterns\n8. Recommendations:\n - Monitor summer capacity planning\n - Consider these peaks for future forecasting\n - Adjust resources for high-season operations', user_query_response='The analysis has been completed following all required steps:\n\n1. Time series features show strong seasonality and trend\n2. Prophet model selected as best performer with MASE of 1.09\n3. Forecast indicates continued growth with seasonal patterns\n4. 8 anomalies detected, mainly in summer peaks\n\nThe time series represents monthly air passenger counts, showing clear yearly patterns with summer peaks and winter troughs. The forecast suggests continued growth while maintaining these seasonal patterns. Special attention should be paid to summer months due to detected anomalies in peak seasons.'))
print(result.output.tsfeatures_analysis)
The time series analysis reveals strong seasonal and trend components: 1. High seasonal strength (0.98) indicates pronounced yearly patterns 2. Strong positive autocorrelation (x_acf1: 0.95) suggests strong trend 3. Significant Holt-Winters seasonality (hw_gamma: 0.75) confirms seasonal importance 4. High stability (0.93) indicates consistent patterns 5. Non-stationary series (KPSS: 2.74) confirms strong trend 6. Clear seasonal peaks (July) and troughs (November)
print(result.output.tsfeatures_analysis)
The time series analysis reveals strong seasonal and trend components: 1. High seasonal strength (0.98) indicates pronounced yearly patterns 2. Strong positive autocorrelation (x_acf1: 0.95) suggests strong trend 3. Significant Holt-Winters seasonality (hw_gamma: 0.75) confirms seasonal importance 4. High stability (0.93) indicates consistent patterns 5. Non-stationary series (KPSS: 2.74) confirms strong trend 6. Clear seasonal peaks (July) and troughs (November)
print(result.fcst_df)
unique_id ds Prophet 0 AirPassengers 1961-01-01 466.560401 1 AirPassengers 1961-02-01 461.042082 2 AirPassengers 1961-03-01 493.413542 3 AirPassengers 1961-04-01 492.113653 4 AirPassengers 1961-05-01 496.445709 5 AirPassengers 1961-06-01 537.592041 6 AirPassengers 1961-07-01 577.166093 7 AirPassengers 1961-08-01 577.599117 8 AirPassengers 1961-09-01 529.038266 9 AirPassengers 1961-10-01 493.889181 10 AirPassengers 1961-11-01 460.030234 11 AirPassengers 1961-12-01 489.392785 12 AirPassengers 1962-01-01 502.415939 13 AirPassengers 1962-02-01 496.321423 14 AirPassengers 1962-03-01 531.969966 15 AirPassengers 1962-04-01 528.065107 16 AirPassengers 1962-05-01 534.174659 17 AirPassengers 1962-06-01 573.615281 18 AirPassengers 1962-07-01 614.245102 19 AirPassengers 1962-08-01 614.206790 20 AirPassengers 1962-09-01 566.306418 21 AirPassengers 1962-10-01 530.606803 22 AirPassengers 1962-11-01 497.766797 23 AirPassengers 1962-12-01 527.289739
Make Queries¶
query_result = tc.query("What will the total number of passengers be in the next year?")
print(query_result.output)
Let me help you calculate the total number of passengers predicted by the Prophet model (our best performing model with MASE = 1.09) for the forecast period. Looking at the forecast data in fcst_df, I'll sum up all the predicted values: From the "AirPassengers" forecasts, let me sum up the Prophet predictions: 466.56 + 461.04 + 493.41 + 492.11 + 496.45 + 537.59 + 577.17 + 577.60 + 529.04 + 493.89 + 460.03 + 489.39 + 502.42 + 496.32 + 531.97 + 528.07 + 534.17 + 573.62 + 614.25 + 614.21 + 566.31 + 530.61 + 497.77 + 527.29 The total predicted number of passengers for the next 24 months is approximately 12,591 thousand passengers. Breaking this down: - First 12 months total: 6,074 thousand passengers - Second 12 months total: 6,517 thousand passengers You can notice an increasing trend in the passenger numbers from year to year, which is consistent with the strong trend feature (trend = 0.997) we see in our features data. The predictions also maintain the seasonal pattern with higher numbers during summer months (peaks around July-August) and lower numbers during winter months (troughs around November-December). Let me show you the forecast visualization so you can see this pattern: