{"id":23305785,"url":"https://github.com/mmsaki/mercado_libre_forecasting","last_synced_at":"2025-08-25T15:07:25.621Z","repository":{"id":110307857,"uuid":"491607461","full_name":"mmsaki/mercado_libre_forecasting","owner":"mmsaki","description":"With over 200 million users, MercadoLibre is the most popular e-commerce site in Latin America. Find out if the ability to predict search traffic can translate into the ability to successfully trade the stock.","archived":false,"fork":false,"pushed_at":"2022-07-17T04:58:37.000Z","size":31802,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-06T23:46:53.445Z","etag":null,"topics":["fbprophet","forecasting","mercadolibre","predictive-modeling","prophet","sales-forecast","search-traffic","time-series","time-series-forecasting"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mmsaki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-05-12T17:25:35.000Z","updated_at":"2024-06-05T21:59:40.000Z","dependencies_parsed_at":"2023-05-09T19:32:08.010Z","dependency_job_id":null,"html_url":"https://github.com/mmsaki/mercado_libre_forecasting","commit_stats":{"total_commits":57,"total_committers":2,"mean_commits":28.5,"dds":"0.24561403508771928","last_synced_commit":"4fe8d426e82485af802e357686e0c53891a73ef8"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mmsaki/mercado_libre_forecasting","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Fmercado_libre_forecasting","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Fmercado_libre_forecasting/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Fmercado_libre_forecasting/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Fmercado_libre_forecasting/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mmsaki","download_url":"https://codeload.github.com/mmsaki/mercado_libre_forecasting/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Fmercado_libre_forecasting/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272084830,"owners_count":24870584,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-25T02:00:12.092Z","response_time":1107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fbprophet","forecasting","mercadolibre","predictive-modeling","prophet","sales-forecast","search-traffic","time-series","time-series-forecasting"],"created_at":"2024-12-20T12:14:17.356Z","updated_at":"2025-08-25T15:07:25.598Z","avatar_url":"https://github.com/mmsaki.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Prophet Forecasting for MercadoLibre\n\n## Table of Contents\n\n\n1. [Part One: Find unusual patterns in hourly Google search traffic](#part-one-find-unusual-patterns-in-hourly-google-search-traffic)\n\n2. [Part Two: Mine the search traffic data for seasonality](#part-two-mine-the-search-traffic-data-for-seasonality)\n\n3. [Part Three: Relate the search traffic to stock price patterns](#part-three-relate-the-search-traffic-to-stock-price-patterns)\n\n4. [Part Four: Create a time series model by using Prophet](#part-four-create-a-time-series-model-by-using-prophet)\n\n5. [Part Five (Optional): Forecast the revenue by using time series models](#part-five-optional-forecast-the-revenue-by-using-time-series-models)\n\n6. [Conclusion](#conclusion)\n\n7. [Results](#results)\n\n## Part One: Find Unusual Patterns in Hourly Google Search Traffic\n\n- [x] Read the search data into a DataFrame, and then slice the data to just the month of May 2020. \n   - During this month, MercadoLibre released its quarterly financial results. \n   - Use hvPlot to visualize the results. \n   - Do any unusual patterns exist? \n      - **Answer:** Yes\n   - Did the Google search traffic increase during the month that MercadoLibre released its financial results?\n      - **Answer:** Yes, the median traffic search increased.\n```python\n# Store data in dataframe\ndf_mercado_trends = pd.read_csv('google_hourly_search_trends.csv', index_col=\"Date\", parse_dates=True)\n\n# Slice the DataFrame to just the month of May 2020\ndf_may_2020 = df_mercado_trends.loc[\"2020-05\"]\n\n# Use hvPlot to visualize the data for May 2020\ndf_may_2020.hvplot(title=\"Search trends MercadoLibre May 2020\")\n\n# Calculate the sum of the total search traffic for May 2020\ntraffic_may_2020 = df_may_2020.loc[\"2020-05\"].sum()\n\n# Calcluate the monhtly median search traffic across all months \n# Group the DataFrame by index year and then index month, chain the sum and then the median functions\nmedian_monthly_traffic = df_mercado_trends[\"Search Trends\"].groupby(by=[df_mercado_trends.index.year, df_mercado_trends.index.month]).median()\n```\n\n   ![](./Images/01_search_trends_may_2020.png)\n   \n## Part Two: Mine the Search Traffic Data for Seasonality\n\n- [x] Group the hourly search data to plot the average traffic by the day of the week for example, Monday vs. Friday.\n\n```python\n# Group the hourly search data to plot (use hvPlot) the average traffic by the day of week \ngroup_level_weeks = df_mercado_trends.index.dayofweek\ndf_mercado_trends.groupby(group_level_weeks).mean().hvplot(title = \"Average Google search traffic grouped by day of week\")\n```\n\n- [x] Using hvPlot, visualize this traffic as a heatmap, referencing `index.hour` for the x-axis and `index.dayofweek` for the y-axis. \n   - Does any day-of-week effect that you observe concentrate in just a few hours of that day? \n      - **Answer:** Yes\n\n```python\n# Use hvPlot to visualize the hour of the day and day of week search traffic as a heatmap.\nweekly_trends = df_mercado_trends.index.dayofweek\ndf_mercado_trends.groupby(weekly_trends).mean().hvplot()\n\ndf_mercado_trends.hvplot.heatmap(\n    x='index.hour',\n    y='index.dayofweek',\n    C='Search Trends',\n    cmap='reds',\n    title= \"Average search traffic during Hour of the day grouped by Days of the week\"\n).aggregate(function=np.mean)\n```\n\n![](./Images/03_avg_traffic_during_hour_grouped_by_dayofweek.png)\n\n- [x] Group the search data by the week of the year. \n   - Does the search traffic tend to increase during the winter holiday period (weeks 40 through 52)? \n      - **Answer:** Yes, Traffic increase during the winter holiday period.\n\n```python\n# Group the hourly search data to plot (use hvPlot) the average traffic by the week of the year\ngroup_level_week_num = df_mercado_trends.index.isocalendar().week\ndf_mercado_trends.groupby(group_level_week_num).mean().hvplot(title=\"Average search traffic grouped by Week of the year\")\n```\n\n![](./Images/04_avg_traffic_grouped_by_week_of_year.png)\n\n## Part Three: Relate the Search Traffic to Stock Price Patterns\n\n- [x] Read in and plot the stock price data. \n   - Concatenate the stock price data to the search data in a single DataFrame\n\n```python\n# Store data in dataframe\ndf_mercado_stock = pd.read_csv(\"mercado_stock_price.csv\", index_col=\"date\", parse_dates=True)\ndf_mercado_stock.index = pd.to_datetime(df_mercado_stock.index, infer_datetime_format = True)\n\n# Concatenate the df_mercado_stock DataFrame with the df_mercado_trends DataFrame\n# Concatenate the DataFrame by columns (axis=1), and drop and rows with only one column of data\nmercado_stock_trends_df = pd.concat([df_mercado_trends, df_mercado_stock], axis=1).dropna()\n```\n\n- [x] Slice the data to just the first half of 2020, `2020-01` to `2020-06` in the DataFrame, and then use hvPlot to plot the data. \n   - Do both time series indicate a common trend that’s consistent with this narrative?\n      - **Answer:** Yes, there is a trend consisent with the narative. Market events emerged during the year of 2020 that many companies found difficult. But, after the initial shock to global financial markets, new customers and revenue increased for e-commerce platforms.\n\n```python\n# For the combined dataframe, slice to just the first half of 2020 (2020-01 through 2020-06) \nfirst_half_2020 = mercado_stock_trends_df.loc[\"2020-01\":\"2020-06\"]\n\n# Use hvPlot to visualize the close and Search Trends data\n# Plot each column on a separate axes\nfirst_half_2020.hvplot(shared_axes=False, subplots=True).cols(1)\n```\n\n![](./Images/06_search_trends_and_close_price.png)\n\n- [x] Create a new column in the DataFrame named “Lagged Search Trends” that offsets, or shifts, the search traffic by one hour. \n\n```python\n# This column should shift the Search Trends information by one hour\nmercado_stock_trends_df['Lagged Search Trends'] = mercado_stock_trends_df['Search Trends'].shift(periods=1)\n```\n\n- [x] “Stock Volatility”, which holds an exponentially weighted four-hour rolling average of the company’s stock volatility\n\n```python\n# This column should calculate the standard deviation of the closing stock price return data over a 4 period rolling window\nmercado_stock_trends_df['Stock Volatility'] = mercado_stock_trends_df['close'].pct_change().rolling(4).std()\n```\n\n- [x] “Hourly Stock Return”, which holds the percentage of change in the company stock price on an hourly basis\n\n```python\n# This column should calculate hourly return percentage of the closing price\nmercado_stock_trends_df['Hourly Stock Return'] = mercado_stock_trends_df['close'].pct_change()\n```\n\n- [x] Review the time series correlation, and then answer the following question: \n   - Does a predictable relationship exist between the lagged search traffic and the stock volatility or between the lagged search traffic and the stock price returns?\n      - **Answer:** The lagged search traffic has a negative correlation with stock volatility, but it has positive correlation with hourly stock returns.\n\n![](./Images/lagged_trends_correlation.png)\n\n## Part Four: Create a Time Series Model by Using Prophet\n\n- Set up the Google search data for a Prophet forecasting model.\n   - After estimating the model, plot the forecast. \n   \n```python\n# Using the df_mercado_trends DataFrame, reset the index so the date information is no longer the index\nmercado_prophet_df = df_mercado_trends.sort_index()\nmercado_prophet_df = df_mercado_trends.reset_index()\n\n# Label the columns ds and y so that the syntax is recognized by Prophet\nmercado_prophet_df.columns = [\"ds\", \"y\"]\n\n# Drop an NaN values from the prophet_df DataFrame\nmercado_prophet_df = mercado_prophet_df.dropna()\n\n# Call the Prophet function, store as an object\nmodel_mercado_trend = Prophet()\n\n# Fit the time-series model.\nmodel_mercado_trend.fit(mercado_prophet_df)\n\n# Create a future dataframe to hold predictions\n# Make the prediction go out as far as 2000 hours (approx 80 days)\nfuture_mercado_trends = model_mercado_trend.make_future_dataframe(periods=2000, freq=\"H\")\n\n# Make the predictions for the trend data using the future_mercado_trends DataFrame\nforecast_mercado_trends = model_mercado_trend.predict(future_mercado_trends)\n\n# Plot the Prophet predictions for the Mercado trends data\nmodel_mercado_trend.plot(forecast_mercado_trends)\n```\n\n- How's the near-term forecast for the popularity of MercadoLibre?\n   - **Answer:** Decreasing near-term\n\n![](./Images/08_mercado_model_trend.png)\n\n- [x] Plot the individual time series components of the model to answer the following questions:\n\n   - What time of day exhibits the greatest popularity?\n      - **Answer:** 00:00 Midnight\n\n   - Which day of the week gets the most search traffic?\n      - **Answer:** # Tuesday\n\n   - What's the lowest point for search traffic in the calendar year?\n      - **Answer:** October - November\n\n```python\n# Set the index in the forecast_mercado_trends DataFrame to the ds datetime column\nforecast_mercado_trends = forecast_mercado_trends.set_index(\"ds\")\n\n# From the forecast_mercado_trends DataFrame, use hvPlot to visualize\n#  the yhat, yhat_lower, and yhat_upper columns over the last 2000 hours \nforecast_mercado_trends[[\"yhat\", \"yhat_lower\", \"yhat_upper\"]].iloc[-2000:,:].hvplot()\n\n# Reset the index in the forecast_mercado_trends DataFrame\nforecast_mercado_trends = forecast_mercado_trends.reset_index()\n\n# Use the plot_components function to visualize the forecast results \n# for the forecast_mercado DataFrame \nfigures_mercado_trends = model_mercado_trend.plot_components(forecast_mercado_trends)\n```\n   ![](./Images/10_mercado_trends_plot.png)\n\n## Part Five (Optional): Forecast the Revenue by Using Time Series Models\n\n- [x] Read in the daily historical sales that revenue figures, and then apply a Prophet model to the data.\n\n```python\n# Create dataframe\ndf_mercado_sales = pd.read_csv(\"mercado_daily_revenue.csv\", index_col = \"date\", infer_datetime_format=True, parse_dates= True).dropna()\n\n# Using the df_mercado_trends DataFrame, reset the index so the date information is no longer the index\ndf_mercado_sales = df_mercado_sales.sort_index()\ndf_mercado_sales = df_mercado_sales.reset_index()\n\n# Label the columns ds and y so that the syntax is recognized by Prophet\ndf_mercado_sales.columns = [\"ds\", \"y\"]\n\n# Drop an NaN values from the prophet_df DataFrame\ndf_mercado_sales = df_mercado_sales.dropna()\n\n# Create the model\nmercado_sales_prophet_model = Prophet(yearly_seasonality = True)\n\n# Fit the model\nmercado_sales_prophet_model.fit(df_mercado_sales)\n\n# Predict sales for 90 days (1 quarter) out into the future.\n\n# Start by making a future dataframe\nmercado_sales_prophet_future = mercado_sales_prophet_model.make_future_dataframe(periods=90, freq=\"D\")\n\n# Make predictions for the sales each day over the next quarter\nmercado_sales_prophet_forecast = mercado_sales_prophet_model.predict(mercado_sales_prophet_future)\n\n```\n\n- Interpret the model output to identify any seasonal patterns in the company revenue.       \n   - For example, what are the peak revenue days?\n      - **Answer:** Mondays - Wednesdays\n\n```python\n# Use the plot_components function to analyze seasonal patterns in the company's revenue\nfigures_mercado_sales = mercado_sales_prophet_model.plot_components(mercado_sales_prophet_forecast)\n\n```\n\n![](./Images/12_mercado_sales_forecast.png)\n\n- [x] Produce a sales forecast for the finance group. \n   - Give them a number for the expected total sales in the next quarter. \n   - Include the best- and worst-case scenarios to help them make better plans.\n      - **Answer:** The most likely total sales forecast for next quater for the period 2020-07-01 to 2020-09-30 is `965.0.`. The Best Case total sales forecast is `1044.0.`. The Worst Case total sales forecast is `887.0`.\n\n```python\n# Plot the predictions for the Mercado sales\nmercado_sales_prophet_model.plot(mercado_sales_prophet_forecast)\n\n# For the mercado_sales_prophet_forecast DataFrame, set the ds column as the DataFrame Index\nmercado_sales_prophet_forecast = mercado_sales_prophet_forecast.set_index(\"ds\")\n\n# Provide best case (yhat_upper), worst case (yhat_lower), and most likely (yhat) scenarios.\nmercado_sales_prophet_forecast = mercado_sales_prophet_forecast[[\"yhat\", \"yhat_upper\", \"yhat_lower\"]]\n\n# Create a forecast_quarter Dataframe for the period 2020-07-01 to 2020-09-30\n# The DataFrame should include the columns yhat_upper, yhat_lower, and yhat\nmercado_sales_forecast_quarter = mercado_sales_prophet_forecast.loc[\"2020-07-01\":\"2020-09-30\"]\n\n# Update the column names for the forecast_quarter DataFrame \n# to match what the finance division is looking for \nmercado_sales_forecast_quarter = mercado_sales_forecast_quarter.rename(columns= {\"yhat\": \"Mostly likely\", \"yhat_upper\": \"Best Case\", \"yhat_lower\": \"Worst Case\"})\n\n# Displayed the summed values for all the rows in the forecast_quarter DataFrame\nmercado_sales_forecast_quarter.sum()\n\n```\n\n![](./Images/13_mercado_forecast_plot.png)\n\n## Conclusion\n\n- This project accomplishes the following tasks:\n\n   - Identifying patterns in time series data.\n\n   - Mining for patterns in seasonality by using visualizations.\n\n   - Building sales-forecast and user-interest predictive models.\n\n## Results\n\n**Results:** [Forecasting Analysis](./mercado_libre_forecast.ipynb)\n\n**Resources:** [Resources](./Resources/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmsaki%2Fmercado_libre_forecasting","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmmsaki%2Fmercado_libre_forecasting","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmsaki%2Fmercado_libre_forecasting/lists"}