Using TimeCopilot with Google Endpoints¶
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.
The api key should be loaded into the GOOGLE_API_KEY environment variable.
This is how you would load the environment variables in in a Unix-like system:
export GOOGLE_API_KEY='your-secret-key'
If you store your environment variables 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 'google-gla:model-id' or instantiating a model with pydantic_ai.models.google.GoogleModel.
For more details on how Pydantic works with Google's Generative Language API, see the Pydantic docs on Google
String example:¶
tc = TimeCopilot(
llm='google-gla:gemini-3-pro-preview',
)
GoogleProvider Example:¶
from pydantic_ai import Agent
from pydantic_ai.models.google import GoogleModel
from pydantic_ai.providers.google import GoogleProvider
provider = GoogleProvider(api_key='your-api-key')
google_model = GoogleModel('gemini-3-pro-preview', provider=provider)
tc = TimeCopilot(
llm=google_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, 101.63it/s] 1it [00:00, 20.05it/s] 1it [00:00, 8.42it/s] 0it [00:00, ?it/s]15:57:28 - cmdstanpy - INFO - Chain [1] start processing 15:57:28 - cmdstanpy - INFO - Chain [1] done processing 1it [00:03, 3.53s/it] 1it [00:00, 151.38it/s] 15:57:36 - cmdstanpy - INFO - Chain [1] start processing 15:57:36 - cmdstanpy - INFO - Chain [1] done processing 0it [00:00, ?it/s]15:57:44 - cmdstanpy - INFO - Chain [1] start processing 15:57:44 - cmdstanpy - INFO - Chain [1] done processing 1it [00:03, 3.04s/it]15:57:47 - cmdstanpy - INFO - Chain [1] start processing 15:57:47 - cmdstanpy - INFO - Chain [1] done processing 2it [00:06, 3.02s/it]15:57:50 - cmdstanpy - INFO - Chain [1] start processing 15:57:50 - cmdstanpy - INFO - Chain [1] done processing 3it [00:09, 3.05s/it]15:57:53 - cmdstanpy - INFO - Chain [1] start processing 15:57:53 - cmdstanpy - INFO - Chain [1] done processing 4it [00:12, 3.07s/it]15:57:56 - cmdstanpy - INFO - Chain [1] start processing 15:57:56 - cmdstanpy - INFO - Chain [1] done processing 5it [00:15, 3.09s/it]15:57:59 - cmdstanpy - INFO - Chain [1] start processing 15:57:59 - cmdstanpy - INFO - Chain [1] done processing 6it [00:18, 3.09s/it]15:58:02 - cmdstanpy - INFO - Chain [1] start processing 15:58:02 - cmdstanpy - INFO - Chain [1] done processing 7it [00:21, 3.14s/it]15:58:05 - cmdstanpy - INFO - Chain [1] start processing 15:58:05 - cmdstanpy - INFO - Chain [1] done processing 8it [00:24, 3.14s/it]15:58:08 - cmdstanpy - INFO - Chain [1] start processing 15:58:08 - cmdstanpy - INFO - Chain [1] done processing 9it [00:27, 3.10s/it]15:58:11 - cmdstanpy - INFO - Chain [1] start processing 15:58:11 - cmdstanpy - INFO - Chain [1] done processing 10it [00:30, 3.07s/it]15:58:14 - cmdstanpy - INFO - Chain [1] start processing 15:58:14 - cmdstanpy - INFO - Chain [1] done processing 11it [00:33, 3.08s/it]
print(result)
AgentRunResult(output=ForecastAgentOutput(tsfeatures_analysis='The time series analysis revealed a highly structured and predictable dataset with the following key characteristics:\n\n* **Seasonality (High):** `seasonal_strength` is 0.98 with a clear 12-month period (`seasonal_period`: 12). This is the dominant feature, necessitating a model that explicitly handles seasonality.\n* **Trend (High):** `trend` strength is 0.99, indicating a consistent upward trajectory. The data is non-stationary (`unitroot_kpss`: 2.74).\n* **Entropy (Low):** A value of 0.43 indicates the signal is very strong compared to the noise, suggesting high forecastability.\n* **Structure:** The data exhibits `nonlinearity` (0.42) and strong autocorrelation (`acf_features`), consistent with the classic multiplicative seasonality (variance increases as the trend rises) seen in airline passenger data.', selected_model='Prophet', model_details="**Selected Model: Prophet**\n\n**Technical Overview:**\nProphet is an additive regression model developed by Meta. It decomposes the time series into three main components:\n1. **Trend:**Modeled here as a non-linear saturating growth or piecewise linear model.\n2. **Seasonality:** Modeled using Fourier series to capture periodic changes (in this case, annual).\n3. **Holidays/Events:** (Not explicitly used here, but part of the model capability).\n\n**Why it fits this data:**\n* **Flexibility:** It adapts well to strong seasonal patterns that don't fit perfectly into rigid ARIMA/ETS structures.\n* **Trend Changes:** It can automatically detect change points in the trend, which is useful for long series like AirPassengers where growth rates may vary over decades.\n* **Robustness:** It is generally robust to missing data and shifts, providing a stable forecast for business metrics.", model_comparison="We evaluated five models using Mean Absolute Scaled Error (MASE). Lower scores indicate better performance.\n\n1. **Prophet (MASE: 1.09):** The clear winner. Prophet's ability to model distinct seasonal components and piecewise trends allowed it to capture the complex seasonality and trend shifts of the dataset much better than the rigid statistical models.\n2. **DynamicOptimizedTheta (MASE: 1.66):** Performed respectably, significantly beating the baseline. It handled the general trend and seasonality well but was less precise than Prophet.\n3. **AutoETS (MASE: 2.38) & AutoARIMA (MASE: 2.40):** Surprisingly, these standard models performed only slightly better than the baseline. They likely struggled with the specific window of evaluation or the intensifying amplitude of the seasonality without specific multiplicative tuning in the default setup.\n4. **SeasonalNaive (MASE: 2.49):** The baseline model. While it captures the basic seasonal pattern, it fails to account for the trend, leading to the highest error rate.", is_better_than_seasonal_naive=True, reason_for_selection='Prophet was selected because it achieved the lowest MASE score (1.09) in cross-validation, significantly outperforming the next best model (DynamicOptimizedTheta at 1.66) and the Seasonal Naive baseline (2.49). Its ability to accurately model the compounding seasonal variance and strong trend made it the superior choice.', forecast_analysis="The forecast for the next 24 months projects a continuation of the established historical patterns:\n\n1. **Trend:** A clear positive trend persists. The passenger numbers are expected to grow from a baseline of ~460 in the first forecast month to peaks exceeding 600 in the second year.\n2. **Seasonality:** The strong annual cycle remains dominant.\n * **Peaks:** We expect major peaks in the summer months (July/August), reaching approximately 577 in the first forecasted year and 614 in the second.\n * **Troughs:** The lowest activity is predicted for the winter months (November-February), dipping below 470.\n3. **Reliability:** Given the model's strong performance (MASE ~1.09) and the data's high predictability (low entropy), this forecast is considered reliable, assuming no major external disruptions to air travel occur (e.g., economic recession).", anomaly_analysis="The analysis detected 8 anomalies (approximately 6.1% of the data points) using a 95% confidence level. \n\n**Pattern of Anomalies:**\nThe anomalies are clustered in specific months across several years:\n* **Summer Peaks:** July 1955, July 1956, July/August 1959, July/August 1960.\n* **Late 1958:** November/December 1958.\n\n**Interpretation:**\nMost anomalies coincide with the peak travel months (July/August). This suggests that the seasonal amplitude (the difference between low and high months) was increasing at a rate slightly faster than the model predicted. In the AirPassengers dataset, seasonality is multiplicative (the peaks get higher as the total number of passengers grows). While Prophet handles seasonality well, extreme seasonal peaks in the final years exceeded the model's confidence intervals, flagging them as anomalies. These should likely be interpreted as 'stronger than expected' seasonal deviations rather than errors in data collection.", user_query_response='I have analyzed the AirPassengers dataset as requested. \n\nThe data is highly seasonal and trend-driven. After testing multiple models, **Prophet** proved to be the most accurate, reducing the error rate by over 50% compared to a standard seasonal baseline. \n\nThe forecast predicts continued growth in air travel, with annual peaks in July/August exceeding 600 passengers in the second forecasted year. Be aware that the "anomalies" detected are primarily just exceptionally strong summer months in the most recent years, reflecting the booming growth rather than data errors.'))
print(result.output.tsfeatures_analysis)
The time series analysis revealed a highly structured and predictable dataset with the following key characteristics: * **Seasonality (High):** `seasonal_strength` is 0.98 with a clear 12-month period (`seasonal_period`: 12). This is the dominant feature, necessitating a model that explicitly handles seasonality. * **Trend (High):** `trend` strength is 0.99, indicating a consistent upward trajectory. The data is non-stationary (`unitroot_kpss`: 2.74). * **Entropy (Low):** A value of 0.43 indicates the signal is very strong compared to the noise, suggesting high forecastability. * **Structure:** The data exhibits `nonlinearity` (0.42) and strong autocorrelation (`acf_features`), consistent with the classic multiplicative seasonality (variance increases as the trend rises) seen in airline passenger data.
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)
Based on the forecast from the **Prophet** model (which performed best with a MASE of **1.09**), the total number of passengers predicted for the next year (1961) is approximately **6,074**. This figure is derived by summing the forecasted values for the first 12 months: * **January:** 467 * **February:** 461 * **March:** 493 * **April:** 492 * **May:** 496 * **June:** 538 * **July:** 577 * **August:** 578 * **September:** 529 * **October:** 494 * **November:** 460 * **December:** 489 This forecast reflects the **strong upward trend** (strength: 0.99) and **seasonality** (strength: 0.98) identified in the historical data. Would you like to see a plot of this forecast to visualize the monthly variations?