Introduction

The topics for each of our (Aditya, Varun, Tucker) CPT projects collectively came to essentially stocks/business and cooking/food. So, we found a suitable dataset of ordered items from a bakery to combine those elements of business and food/cooking/baking, deciding that our ML model would determine a food order at the bakery (ex: “Bread”, “Coffee”, “Pastry”, etc.) based on the other variables in the dataset (exact military time, general time: “Afternoon/Morning”, and day of the week: “Weekend/Weekday”).

Because our dataset of ~20 thousand total rows/orders included nearly 1/4 “Coffee” as a food item, it was extremely common to get Coffee”” rather than any other item. Therefore, we made two separate Models, APIs, and frontend input fields to include both the normal (skewed by “Coffee”) dataset/CSV file, and another identitical input field that simply used a different Model, API, and dataset and different datset/CSV file with “Coffee” filtered out. Screenshots below.

Frontend design:

Backend code:

#### Model code
    import numpy as np
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LogisticRegression
    from sklearn.preprocessing import OneHotEncoder
    # Import the required libraries for the TitanicModel class
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import accuracy_score
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import OneHotEncoder
    import pandas as pd
    import numpy as np
    import seaborn as sns

    class food:
        _instance = None
        """ _init_(self): creates changeable instances and defines variables used for prediction through self.features and defines target variable to predict through self.target"""
        def __init__(self):
            self.model = None
            self.dt = None
            self.features = ['Hour', 'DayPart', 'DayType']  # Features for prediction
            self.target = 'Items'  # Target variable to predict
            self.data = pd.read_csv('filtered_data.csv')
            
        def _clean(self):
            """_clean(self) Converts data from the csv file into more readable form for ml. In this case, it reads the DayPart column and converts """
            self.data['DayPart'] = self.data['DayPart'].apply(lambda x: 1 if x == 'Morning' else 0)
            self.data['DayType'] = self.data['DayType'].apply(lambda x: 1 if x == 'Weekend' else 0)
            self.data['Hour'] = pd.to_datetime(self.data['Time'], format='%H:%M:%S').dt.hour
            
            
        def _train(self):
            X = self.data[self.features]  # Features
            y = self.data[self.target]  # Target variable
            
            # Train a logistic regression model
            self.model = LogisticRegression(max_iter=1000)
            self.model.fit(X, y)
            
            # Train a decision tree classifier
            self.dt = DecisionTreeClassifier()
            self.dt.fit(X, y)
            
        @classmethod
        def get_instance(cls):
            """Gets, and conditionally cleans and builds, the singleton instance of the Food model."""
            if cls._instance is None:
                cls._instance = cls()
                cls._instance._clean()
                cls._instance._train()
            return cls._instance
        
        def predict(self, payload):
            """Predict the item based on the given features. It is taken from the json input and is cleaned to match previous code so it can be used to predict"""
            # Convert input to DataFrame
            payload_df = pd.DataFrame(payload, index=[0])
            # Convert categorical variables to binary
            payload_df['DayPart'] = payload_df['DayPart'].apply(lambda x: 1 if x == 'Morning' else 0)
            payload_df['DayType'] = payload_df['DayType'].apply(lambda x: 1 if x == 'Weekend' else 0)
            payload_df['Hour'] = pd.to_datetime(payload_df['Time'], format='%H:%M:%S').dt.hour
            #payload_df['Hour'] = pd.to_datetime(payload_df['Time']).dt.hour
            # Predict item using the logistic regression model
            #item = self.model.predict(payload_df)
            item = self.model.predict(payload_df[self.features]) 
            #return {'item': item}
            return {'item': item.tolist()} 
        def feature_weights(self):
            """Get the feature weights
            The weights represent the relative importance of each feature in the prediction model.

            Returns:
                dictionary: contains each feature as a key and its weight of importance as a value
            """
            # extract the feature importances from the decision tree model
            importances = self.dt.feature_importances_
            # return the feature importances as a dictionary, using dictionary comprehension
            return {feature: importance for feature, importance in zip(self.features, importances)}
    def initfood():
        food.get_instance()

modification to main.py:

  • init
    # Define a command to generate data
    @custom_cli.command('generate_data')
    def generate_data():
        initUsers()
        initPlayers()
        initfood()
        initbakery()
  • regiter api
    # setup APIs
    from api.covid import covid_api # Blueprint import api definition
    from api.joke import joke_api # Blueprint import api definition
    from api.user import user_api # Blueprint import api definition
    from api.player import player_api
    from api.titanic import titanic_api
    from api.food import food_api
    from api.bakery import bakery_api
    # database migrations
    from model.users import initUsers
    from model.players import initPlayers
    from model.foods import initfood 
    from model.bakeries import initbakery

    # setup App pages
    from projects.projects import app_projects # Blueprint directory import projects definition


    # Initialize the SQLAlchemy object to work with the Flask app instance
    db.init_app(app)

    # register URIs
    app.register_blueprint(joke_api) # register api routes
    app.register_blueprint(covid_api) # register api routes
    app.register_blueprint(user_api) # register api routes
    app.register_blueprint(player_api)
    app.register_blueprint(app_projects) # register app pages
    app.register_blueprint(titanic_api)
    app.register_blueprint(food_api)
    app.register_blueprint(bakery_api)

Frontend code:

HTML:

---
permalink: /bakery
layout: nav_ml
---

    <html>
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Bakery ML</title>
            <link rel="stylesheet" href="bakery-style.css"> 
        </head>
        <body>
            <div class="container">
                <form class="signUp">
                    <h3>Bakery Ml</h3>
                    <p id="resultx" aria-hidden="true"></p>
                        <select id="TimeOfDay">
                            <option disabled selected>Time of Day</option>
                            <option value="Morning">Morning</option>
                            <option value="Afternoon">Afternoon</option>
                        </select> 
                        <select id="DayOfWeek">
                            <option disabled selected>Day of Week</option>
                            <option value="Weekend">Weekend</option>
                            <option value="Weekday">Weekday</option>
                        </select>
                        <input id="time" type="text" placeholder="Time" onfocus="(this.type='time')">
                    <button class="form-btn sx log-in" type="button">Switch</button>
                    <button class="form-btn dx"  type="button"  onclick="extra()">Predict</button>
                </form>
                <form class="signIn">
                    <h3>
                        No Coffee Ml 
                    </h3>
                    <p id="resultx1" aria-hidden="true"></p>
                        <p id="resultx" aria-hidden="true"></p>
                        <select id="TimeOfDay1">
                            <option disabled selected>Time of Day</option>
                            <option value="Morning">Morning</option>
                            <option value="Afternoon">Afternoon</option>
                        </select> 
                        <select id="DayOfWeek1">
                            <option disabled selected>Day of Week</option>
                            <option value="Weekend">Weekend</option>
                            <option value="Weekday">Weekday</option>
                        </select>
                        <input id="time1" type="text" placeholder="Time" onfocus="(this.type='time')">
                    <button class="form-btn sx back" type="button">Switch</button>
                    <button class="form-btn dx"  type="button"  onclick="extrax()">Predict</button>
                </form>
            </div>
        </body>
    </html>
  • Javascript:
    <script>
        document.querySelector(".log-in").addEventListener("click", function() {
            document.querySelector(".signIn").classList.add("active-dx");
            document.querySelector(".signUp").classList.add("inactive-sx");
            document.querySelector(".signUp").classList.remove("active-sx");
            document.querySelector(".signIn").classList.remove("inactive-dx");
        });
        document.querySelector(".back").addEventListener("click", function() {
            document.querySelector(".signUp").classList.add("active-sx");
            document.querySelector(".signIn").classList.add("inactive-dx");
            document.querySelector(".signIn").classList.remove("active-dx");
            document.querySelector(".signUp").classList.remove("inactive-sx");
        });
    </script>
    <script>
        function extra() {
                var dom = document.getElementById('resultx');
                var TOD = document.getElementById('TimeOfDay').value;
                var DOW = document.getElementById('DayOfWeek').value;
                var time = document.getElementById('time');
                var enteredTime = time.value + ":00"
                var payload = {
                    Time: enteredTime,
                    DayPart: TOD,
                    DayType: DOW,
                };
                var url = 'http://127.0.0.1:8086/api/food/predict'
                var json = JSON.stringify(payload);
                console.log(json)
                const authOptions = {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: json,
                    credentials: 'include'
                };
                fetch(url, authOptions)
                    .then(response => {
                        if (!response.ok) {
                            throw new Error(`HTTP error! Status: ${response.status}`);
                        }
                        return response.json();
                    })
                    .then(data => {
                        console.log('success', data);
                        dom.innerText = "Predicted Item: " + data["item"]
                    // Display in alert
                        alert("Predicted Item: " + data["item"]);
                    })                
                    .catch(error => {
                        console.error('error', error);
                        // Handle error
                        dom.innerText = "Error occurred";
                    });
            }
        function extrax() {
                var dom = document.getElementById('resultx1');
                var TOD = document.getElementById('TimeOfDay1').value;
                var DOW = document.getElementById('DayOfWeek1').value;
                var time = document.getElementById('time1');
                var enteredTime = time.value + ":00"
                var payload = {
                    Time: enteredTime,
                    DayPart: TOD,
                    DayType: DOW,
                };
                var url = 'http://127.0.0.1:8086/api/bakery/predict'
                var json = JSON.stringify(payload);
                console.log(json)
                const authOptions = {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: json,
                    credentials: 'include'
                };
                fetch(url, authOptions)
                    .then(response => {
                        if (!response.ok) {
                            throw new Error(`HTTP error! Status: ${response.status}`);
                        }
                        return response.json();
                    })
                    .then(data => {
                        console.log('success', data);
                        dom.innerText = "Predicted Item: " + data["item"]
                    // Display in alert
                        alert("Predicted Item: " + data["item"]);
                    })                
                    .catch(error => {
                        console.error('error', error);
                        // Handle error
                        dom.innerText = "Error occurred";
                    });
            }
    </script>