import pickle import streamlit as st import numpy as np import pandas as pd import re from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing.sequence import pad_sequences from nltk.corpus import stopwords from sklearn.preprocessing import StandardScaler import nltk import time # Download required NLTK data (for stopwords only) nltk.download('stopwords') # Load the trained model model = load_model("./best_model.keras") # Load the tokenizer with open("./tokenizer.pkl", "rb") as f: tokenizer = pickle.load(f) # Ensure the tokenizer is valid if not hasattr(tokenizer, 'texts_to_sequences'): raise ValueError("Loaded tokenizer is not a valid Keras Tokenizer object.") # Define constants MAX_SEQUENCE_LENGTH = 100 # Simple tokenizer function def simple_tokenizer(text): text = text.lower() text = re.sub(r'[^a-zA-Z\s]', '', text) tokens = text.split() # Split by whitespace return tokens # Preprocessing function for input review def preprocess_input_review(review_text): tokens = simple_tokenizer(review_text) stop_words = set(stopwords.words('english')) tokens = [word for word in tokens if word not in stop_words] processed_review = ' '.join(tokens) return processed_review # Convert simplified time strings (e.g., 2H30M or 15M) to minutes def time_to_minutes(time_str): if not time_str or pd.isna(time_str): return 0 hours, minutes = 0, 0 if 'H' in time_str: parts = time_str.split('H') hours = int(parts[0]) if parts[0].isdigit() else 0 time_str = parts[1] if len(parts) > 1 else '' if 'M' in time_str and time_str.split('M')[0].isdigit(): minutes = int(time_str.split('M')[0]) return hours * 60 + minutes # Prediction function def predict_menu_inclusion(food_name, review_text, cook_time, prep_time, total_time, protein, carbs, fat): # Preprocess the review processed_review = preprocess_input_review(review_text) # Tokenize and pad the review review_sequence = tokenizer.texts_to_sequences([processed_review]) padded_review = pad_sequences(review_sequence, maxlen=MAX_SEQUENCE_LENGTH) # Prepare numerical features numerical_features = np.array([[time_to_minutes(cook_time), time_to_minutes(prep_time), time_to_minutes(total_time), protein, carbs, fat]]) # Normalize numerical features scaler = StandardScaler() numerical_features = scaler.fit_transform(numerical_features) # Predict the rating predicted_rating = model.predict([padded_review, numerical_features]).flatten()[0] # Decide whether to include the item on the menu include_on_menu = predicted_rating > 3.5 # Threshold for inclusion return { "FoodName": food_name, "PredictedRating": round(predicted_rating, 2), "IncludeOnMenu": include_on_menu } # Streamlit app with enhanced UI st.set_page_config(page_title="Recipe Rating & Menu Optimization", layout="wide") st.title("🍲🌟 Recipe Rating & Menu Optimization 🚀") st.markdown( """ Welcome to the **Recipe Rating & Menu Optimization** app! 🎉 This tool uses cutting-edge **AI and machine learning** 🧠 to help chefs, restaurateurs, and food enthusiasts 🍽️ predict recipe ratings and decide if a dish deserves a place on the menu. 🏆 Let's get started and create culinary magic! ✨ """ ) st.sidebar.header("📋 Enter Recipe Details") food_name = st.sidebar.text_input("🍴 Food Name", value="Paneer Butter Masala") review_text = st.sidebar.text_area("📝 Review Text", value="This dish is delicious, rich in flavor, and a favorite among customers!") cook_time = st.sidebar.text_input("⏳ Cooking Time (e.g., 15M or 2H30M)", value="30M") prep_time = st.sidebar.text_input("🕒 Preparation Time (e.g., 15M or 1H15M)", value="15M") total_time = st.sidebar.text_input("📅 Total Time (e.g., 45M or 1H45M)", value="45M") protein = st.sidebar.number_input("💪 Protein (grams)", min_value=0.0, step=1.0, value=20.0) carbs = st.sidebar.number_input("🍞 Carbohydrates (grams)", min_value=0.0, step=1.0, value=10.0) fat = st.sidebar.number_input("🍟 Fat (grams)", min_value=0.0, step=1.0, value=15.0) if st.sidebar.button("🔮 Predict"): result = predict_menu_inclusion(food_name, review_text, cook_time, prep_time, total_time, protein, carbs, fat) predicted_rating = result["PredictedRating"] include_on_menu = result["IncludeOnMenu"] # Custom progress bar with color based on inclusion bar_color = "green" if include_on_menu else "red" progress_percentage = int(predicted_rating * 20) # Convert rating (0-5) to percentage (0-100) # Display animated progress bar st.markdown( f"""