From 08ab9131f82fd00afc7c0ab9aa2d2428e3ba8365 Mon Sep 17 00:00:00 2001 From: Ewout ter Hoeven Date: Sat, 23 Mar 2024 14:45:22 +0100 Subject: [PATCH] Create lemon_stand.ipynb Upload initial version of lemon stand notebook. --- ema_workbench/examples/lemon_stand.ipynb | 424 +++++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 ema_workbench/examples/lemon_stand.ipynb diff --git a/ema_workbench/examples/lemon_stand.ipynb b/ema_workbench/examples/lemon_stand.ipynb new file mode 100644 index 000000000..62893f305 --- /dev/null +++ b/ema_workbench/examples/lemon_stand.ipynb @@ -0,0 +1,424 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [], + "metadata": { + "collapsed": false + }, + "id": "b5f9494af015a1f5" + }, + { + "cell_type": "markdown", + "source": [ + "## Introduction: The Lemonade Stand\n", + "\n", + "Welcome to our interactive tutorial where we'll dive into the exciting world of decision-making and strategy through the lens of running a lemonade stand. This journey isn't just about selling lemonade; it's a comprehensive exploration of how to navigate uncertainties, optimize decisions, and adapt strategies in a business context, all wrapped in the fun and accessible scenario of a lemonade stand.\n", + "\n", + "### Why a Lemonade Stand?\n", + "\n", + "A lemonade stand, though simple, encapsulates the essence of business: understanding customer needs, dealing with uncertainties (like the weather), setting prices, and marketing. These elements are not just the core of running a lemonade stand but are fundamental to managing any business, making it a perfect, relatable model for learning.\n", + "\n", + "### What you will learn\n", + "\n", + "Through this tutorial, you will:\n", + "- **Understand Uncertainty**: Learn to identify and characterize uncertainties (e.g., weather conditions, lemon costs) and their impact on business decisions.\n", + "- **Explore Scenarios**: Dive into scenario analysis to understand how different conditions affect outcomes and how to prepare for them.\n", + "- **Optimize Decisions**: Discover how to make the best decisions in light of these uncertainties and scenarios, balancing various objectives like profit, costs, and time investment.\n", + "- **Adapt Strategies**: Learn about adaptive policymaking, adjusting your strategy as you gain more information and as conditions change." + ], + "metadata": { + "collapsed": false + }, + "id": "e029ba66d4273746" + }, + { + "cell_type": "markdown", + "source": [ + "### The Simulation Model\n", + "\n", + "Our exploration is centered around a Python simulation model of a lemonade stand. This model will help us understand the dynamics of running the stand under different conditions. It takes into account factors such as:\n", + "- Weather (sunny, cloudy, rainy)\n", + "- Day type (weekday, weekend)\n", + "- Pricing strategies\n", + "- Marketing efforts\n", + "- Hours of operation\n", + "- Uncertain lemon purchase prices\n", + "- Special events that might increase demand\n", + "\n", + "We'll use this model to simulate various scenarios, analyze the outcomes, and optimize our lemonade stand's operations." + ], + "metadata": { + "collapsed": false + }, + "id": "a4567af7cf68335c" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "initial_id", + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Some imports to get us started\n", + "import random\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "def simulate_lemonade_stand(weather, day, price, marketing_spend, hours_open, lemon_cost, special_event=False):\n", + " \"\"\"\n", + " Simulates a day at the lemonade stand, considering various factors including time spent and lemon cost.\n", + "\n", + " Parameters:\n", + " - weather: 'sunny', 'cloudy', or 'rainy'\n", + " - day: 'weekday' or 'weekend'\n", + " - price: Price per cup of lemonade\n", + " - marketing_spend: Money spent on marketing that day\n", + " - hours_open: Hours the lemonade stand is open\n", + " - lemon_cost: Cost per lemon (uncertain variable)\n", + " - special_event: Boolean indicating if there's a special event nearby\n", + "\n", + " Returns:\n", + " - sales: Number of lemonade cups sold\n", + " - profit: Net profit for the day\n", + " - time_spent: Total time spent operating the stand\n", + " \"\"\"\n", + " # Base demand model\n", + " base_demand = 50 if weather == 'sunny' else 30 if weather == 'cloudy' else 10\n", + "\n", + " # Adjust demand for weekend, special events, and hours open\n", + " if day == 'weekend':\n", + " base_demand *= 1.5\n", + " if special_event:\n", + " base_demand *= 2\n", + " base_demand *= (hours_open / 8) # Assume max demand if open 8 hours\n", + "\n", + " # Influence of marketing spend (logarithmic growth)\n", + " marketing_effectiveness = 10 * (1 - 1 / (1 + marketing_spend / 50))\n", + "\n", + " # Adjust demand for price (demand decreases as price increases, but not linearly)\n", + " price_sensitivity = 50 - (price - 1) ** 2 if price < 5 else 20 - (price - 5)\n", + " price_sensitivity = max(0, price_sensitivity)\n", + "\n", + " # Calculate final demand\n", + " final_demand = base_demand + marketing_effectiveness + price_sensitivity\n", + "\n", + " # Calculate sales and profit\n", + " sales = int(final_demand)\n", + " cost_per_cup = 0.5 + lemon_cost # Adjusted cost to include lemon cost\n", + " profit = sales * (price - cost_per_cup) - marketing_spend\n", + "\n", + " # Time spent at the stand\n", + " time_spent = hours_open\n", + "\n", + " return sales, profit, time_spent" + ], + "metadata": { + "collapsed": false + }, + "id": "960bf753e886f86e", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "Let run it once to see how it works:" + ], + "metadata": { + "collapsed": false + }, + "id": "43be03a09c865b8e" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "# Example simulation with uncertain lemon cost\n", + "weather = random.choice(['sunny', 'cloudy', 'rainy'])\n", + "day = random.choice(['weekday', 'weekend'])\n", + "price = round(random.uniform(1, 5), 2)\n", + "marketing_spend = random.randint(0, 100)\n", + "hours_open = random.randint(4, 8) # Assume the stand can be open between 4 to 8 hours\n", + "lemon_cost = round(random.uniform(0.1, 0.5), 2) # Uncertain purchase price of lemons\n", + "special_event = random.choice([True, False])\n", + "\n", + "sales, profit, time_spent = simulate_lemonade_stand(weather, day, price, marketing_spend, hours_open, lemon_cost,\n", + " special_event)\n", + "print(\n", + " f\"Weather: {weather}, Day: {day}, Price: ${price}, Marketing Spend: ${marketing_spend}, Hours Open: {hours_open}, Lemon Cost: ${lemon_cost}, Special Event: {special_event}\")\n", + "print(f\"Sales: {sales} cups, Profit: ${profit:.2f}, Time Spent: {time_spent} hours\")" + ], + "metadata": { + "collapsed": false + }, + "id": "b25ed1889c823a00", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "## Part 1: Exploring the Scenario Space\n", + "\n", + "Now that we've laid the foundation with our lemonade stand model it's time to dive deeper into the heart of strategic decision-making: exploring the scenario space. This phase is where creativity meets analysis. By imagining various possible futures and examining how different factors interact, we can uncover insights that guide our decisions and strategies.\n", + "\n", + "### What you will learn\n", + "\n", + "Here's a snapshot of what we'll cover:\n", + "\n", + "- **Open Exploration**: We'll start by casting a wide net, considering a vast array of potential scenarios. This is about asking \"What if?\" in as many ways as we can imagine—what if it's a rainy weekend? What if a local event drives up demand? Through this exploratory process, you'll learn to identify which factors could significantly impact your lemonade stand's success.\n", + "\n", + "- **Scenario Discovery**: Once we've considered a broad set of possibilities, we'll focus on identifying the most impactful scenarios using specialized techniques like the Patient Rule Induction Method (PRIM) and Subspace Partitioning. This step is crucial for narrowing down the scenarios to those that truly matter, enabling us to concentrate our efforts and resources more effectively.\n", + "\n", + "- **Global Sensitivity Analysis**: Understanding which variables have the most significant influence on our outcomes is key. Through Global Sensitivity Analysis, we'll learn which factors (e.g., weather, pricing, marketing spend) you should focus on to improve your lemonade stand's performance. This analysis helps in prioritizing strategic adjustments and investments.\n", + "\n", + "By exploring the scenario space, you'll gain invaluable skills in navigating uncertainties and making informed decisions. You'll learn not just to react to the business environment but to anticipate and prepare for various futures, making your lemonade stand—and any other venture you undertake—more resilient and successful.\n" + ], + "metadata": { + "collapsed": false + }, + "id": "259e17e54856d57c" + }, + { + "cell_type": "markdown", + "source": [ + "### 1.1 Open Exploration\n", + "Open exploration involves systematically varying parameters of our lemonade stand model to observe how changes affect outcomes like sales and profit. It's akin to asking a series of \"what if\" questions:\n", + "\n", + "- What if it rains all week?\n", + "- What if we double our marketing efforts on weekends?\n", + "- How does changing the lemon cost impact our profit?\n", + "\n", + "- This approach not only helps us understand the dynamics of our lemonade stand but also teaches us valuable lessons about the impact of external and internal factors on any business.\n", + "\n", + "#### Why open exploration?\n", + "Before we dive into specific techniques for scenario discovery and sensitivity analysis, we must first explore freely. This unbounded exploration allows us to:\n", + "\n", + "- Identify a wide range of outcomes that our lemonade stand might face.\n", + "- Understand the impact of different variables in various combinations.\n", + "- Generate hypotheses about what might be most important for our success.\n", + "\n", + "#### How to perform open exploration\n", + "To begin, we'll simulate a variety of scenarios by varying the inputs to our lemonade stand model. We'll change one factor at a time to observe its effect, and then combine multiple changing factors to see more complex interactions. This process will give us an initial sense of which variables have the most significant impact on our outcomes.\n", + "\n", + "Let's start with a simple exploration, varying only the weather while keeping other factors constant." + ], + "metadata": { + "collapsed": false + }, + "id": "dd2ae6f88a62205c" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "# Define a list of weather conditions\n", + "weather_conditions = ['sunny', 'cloudy', 'rainy']\n", + "\n", + "# Set constants for other variables\n", + "day = 'weekend'\n", + "price = 2.50\n", + "marketing_spend = 20\n", + "hours_open = 8\n", + "lemon_cost = 0.30\n", + "special_event = False\n", + "\n", + "# Simulate and print the outcomes for different weather conditions\n", + "for weather in weather_conditions:\n", + " sales, profit, time_spent = simulate_lemonade_stand(weather, day, price, marketing_spend, hours_open, lemon_cost, special_event)\n", + " print(f\"Weather: {weather}, Sales: {sales}, Profit: ${profit:.2f}\")" + ], + "metadata": { + "collapsed": false + }, + "id": "a2dcc319d34b1767", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "Next, we'll introduce variability in another dimension—say, day type—to observe how the interaction between weather and day type affects our results." + ], + "metadata": { + "collapsed": false + }, + "id": "8bfbe4858db233b1" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "# Define a list of day types and a list to collect simulation results\n", + "day_types = ['weekday', 'weekend']\n", + "results = []\n", + "\n", + "# Run the simulation across different weather conditions and day types\n", + "for weather in weather_conditions:\n", + " for day in day_types:\n", + " sales, profit, _ = simulate_lemonade_stand(weather, day, price, marketing_spend, hours_open, lemon_cost, special_event)\n", + " results.append({'Weather': weather, 'Day': day, 'Sales': sales, 'Profit': profit})\n", + "\n", + "# Convert results into a DataFrame\n", + "df = pd.DataFrame(results)\n", + "df" + ], + "metadata": { + "collapsed": false + }, + "id": "52ba76cbf1eacc2e", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "**Visualizing the results**\n", + "Now that we have our simulation results in a DataFrame, let's create visualizations to better understand how weather conditions and day types affect sales and profits." + ], + "metadata": { + "collapsed": false + }, + "id": "392a4c5af8662041" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "# Setting up the figure and axes for the subplots\n", + "fig, axes = plt.subplots(1, 2, figsize=(20, 6)) # 1 row, 2 columns\n", + "\n", + "# Titles and variables for each subplot\n", + "titles = ['Lemonade Sales: Weather Conditions vs. Day Type', 'Lemonade Stand Profit: Weather Conditions vs. Day Type']\n", + "variables = ['Sales', 'Profit']\n", + "\n", + "for i, variable in enumerate(variables):\n", + " sns.barplot(x='Weather', y=variable, hue='Day', data=df, palette='coolwarm', ax=axes[i])\n", + " axes[i].set_title(titles[i])\n", + " axes[i].set_xlabel('Weather Condition')\n", + " axes[i].set_ylabel(variable)\n", + " axes[i].legend(title='Day Type')" + ], + "metadata": { + "collapsed": false + }, + "id": "1412b3327bfe0811", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "#### Try it yourself!\n", + "\n", + "Now is a great moment to start understanding of the lemonade stand's dynamics through open exploration yourself. For example, try experimenting with these key variables on your own:\n", + "\n", + "1. **Pricing Strategy**: Adjust the lemonade price ($1 to $5) and observe the impact on sales and profit. How do customers react to price changes on different weather days?\n", + "2. **Marketing Spend**: Experiment with varying your marketing budget ($0, $20, $50, $100) and see how it affects demand. Is marketing more effective on weekends or during special events?\n", + "3. **Operating Hours**: Change how long you're open (4 to 8 hours) and track the effect on profits. Is there a point where extra hours don't increase earnings?\n", + "4. **Lemon Cost Variability**: Simulate changes in lemon cost ($0.1 to $0.5 per lemon) to understand how input costs impact profitability. Can adjusting prices or marketing compensate for higher costs?\n", + "\n", + "Consider simple charts to visualize the effects. This approach will help you grasp how different decisions can influence your lemonade stand's success, providing insights into effective strategy adjustments." + ], + "metadata": { + "collapsed": false + }, + "id": "f00643ba1af03f1c" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "# Do some open exploration here!\n" + ], + "metadata": { + "collapsed": false + }, + "id": "a56ffc49b041ce96", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "Let's take a moment to reflect on our graphs. They show us that sunny weekends are great for lemonade sales and profits, but there's more to the story. These snapshots don't consider other important factors like lemon prices or whether there's a big game in town, which could shake things up.\n", + "\n", + "In the upcoming sections, we'll dig deeper. We'll uncover which combinations of factors, like a heatwave or a soccer tournament, really boost our sales. And we'll get savvy with our strategy, adjusting prices and planning special offers to make the most of every sunny day—or any day, for that matter. Stay tuned, as we get ready to add layers and learn how to make our lemonade stand the talk of the town, no matter the weather!" + ], + "metadata": { + "collapsed": false + }, + "id": "3bf17133f42bb44f" + }, + { + "cell_type": "markdown", + "source": [ + "### 1.2 Scenario Discovery\n", + "\n", + "After embarking on the journey of open exploration, where we cast a wide net to understand the myriad ways in which different factors impact our lemonade stand, we move on to a more focused and powerful phase: scenario discovery. This phase is where we wield sophisticated tools to sift through the vast data we've generated, pinpointing the scenarios that matter most to our success. The spotlight here is on two powerful techniques: the Patient Rule Induction Method (PRIM) and Subspace Partitioning.\n", + "\n", + "#### The Power of Scenario Discovery\n", + "\n", + "Scenario discovery allows us to go beyond simple observations, helping us identify patterns and key scenarios that could significantly impact our lemonade stand's outcomes. By applying PRIM and Subspace Partitioning, we can uncover specific combinations of conditions that lead to particularly high or low sales and profits. This focused approach enables us to prepare better and optimize our strategies for these critical scenarios.\n", + "\n", + "#### Why Scenario Discovery?\n", + "\n", + "- **Focus**: While open exploration spreads our attention across all possibilities, scenario discovery helps us focus on what truly matters, saving us time and resources.\n", + "- **Insight**: It provides deep insights into the combinations of factors that drive success or failure, offering clarity in complex decision-making landscapes.\n", + "- **Strategy Optimization**: By understanding key scenarios, we can tailor our strategies to exploit opportunities or mitigate risks, enhancing our lemonade stand's performance.\n", + "\n", + "#### How to Perform Scenario Discovery\n", + "\n", + "##### Patient Rule Induction Method (PRIM)\n", + "\n", + "PRIM helps us identify \"boxes\" in our multidimensional dataset where the outcome (e.g., high sales) is significantly more likely. It's akin to finding pockets of gold in a vast mine by systematically narrowing down where to dig based on the evidence.\n", + "\n", + "1. **Setup**: Begin with your dataset from open exploration, including all scenarios and their outcomes.\n", + "2. **Application**: Apply PRIM to search for areas within your dataset where, for example, profits are highest. PRIM will iteratively search for conditions that lead to these high-profit scenarios, such as a combination of sunny weather, weekend days, and specific pricing strategies.\n", + "\n", + "##### Subspace Partitioning\n", + "\n", + "Subspace Partitioning takes a different approach, dividing the dataset into subspaces based on the variables (e.g., weather, day type) and then analyzing each subspace to identify where outcomes like high sales occur more frequently.\n", + "\n", + "1. **Divide**: Segment your data based on key variables, creating subspaces for analysis.\n", + "2. **Analyze**: For each subspace, look for patterns or conditions that consistently lead to desired outcomes." + ], + "metadata": { + "collapsed": false + }, + "id": "79c44681b221c6f6" + }, + { + "cell_type": "markdown", + "source": [], + "metadata": { + "collapsed": false + }, + "id": "d8b570f96b4ca488" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}