Spaces:
Runtime error
Runtime error
| import pickle | |
| import pandas as pd | |
| import shap | |
| import gradio as gr | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| # Load the XGBoost model | |
| loaded_model = pickle.load(open("revenue_model.pkl", 'rb')) | |
| # SHAP Explainer for XGBoost | |
| explainer = shap.Explainer(loaded_model) | |
| def safe_convert(value, default, min_val, max_val): | |
| try: | |
| num = float(value) | |
| return max(min_val, min(num, max_val)) | |
| except (TypeError, ValueError): | |
| return default | |
| def main_func(InventoryBucket, Category, Product, Geography, Conference): | |
| inventory_mapping = { | |
| "Spot": 1, | |
| "Field-Level Signage": 2, | |
| "LED Ribbon Board Signage": 3, | |
| "Season Ticket": 4, | |
| "Videoboard Promotion": 5, | |
| "Field or Event Access": 6, | |
| "Program and Guide (Print)": 7, | |
| "Rotational Signage": 8, | |
| "Live Read": 9, | |
| "Parking": 10, | |
| "Ticket": 11, | |
| "Feature": 12, | |
| "Marketing Space": 13, | |
| "In-Game Promotion": 14, | |
| "PA Announcement": 15, | |
| "Scoreboard Signage": 16, | |
| "Activation": 17, | |
| "Suite": 18, | |
| "Billboard": 19, | |
| "Entitlement/Sponsorship": 20, | |
| "Game Entitlement": 21, | |
| "Club Ticket": 22, | |
| "Post Season Revenue": 23, | |
| "Display": 24, | |
| "Miscellaneous Signage": 25, | |
| "Program and Guide (Digital)": 26, | |
| "Concourse Signage": 27, | |
| "Giveaway": 28, | |
| "Tabling": 29, | |
| "Game Sponsor": 30, | |
| "Yearbook": 31, | |
| "Live Mention": 32, | |
| "Rights & Licensing": 33, | |
| "Schedule": 34, | |
| "Virtual Signage": 35, | |
| "Venue": 36, | |
| "Tailgating": 37, | |
| "Trip": 38, | |
| "Presenting Sponsor": 39, | |
| "Concession Signage": 40, | |
| "Fan Engagement Area": 41, | |
| "Venue Entitlement": 42, | |
| "Sideline Branding": 43, | |
| "Autographed Item": 44, | |
| "Post Season Ticket": 45, | |
| "Poster": 46, | |
| "Courtside Ticket": 47, | |
| "Box Ticket": 48, | |
| "Vomitory Signage": 49, | |
| "Group Tickets": 50, | |
| "Pre-Game Specialty Sponsor": 51, | |
| "Sideline Assets": 52, | |
| "Roster Card": 53, | |
| "Sideline Signage": 54, | |
| "Stair Sign": 55, | |
| "Photo & Meet and Greet": 56, | |
| "Tour": 57, | |
| "On-Field Promotion": 58 | |
| } | |
| category_mapping = { | |
| "Signage": 1, | |
| "Radio": 2, | |
| "Tickets & Hospitality": 3, | |
| "Promotion": 4, | |
| "Print": 5, | |
| "Activation": 6, | |
| "Entitlement & Sponsorship": 7, | |
| "Television": 8, | |
| "Experiential": 9, | |
| "Miscellaneous": 10, | |
| "Intellectual Property": 11 | |
| } | |
| product_mapping = { | |
| "Football": 1, | |
| "Basketball - Men's": 2, | |
| "Basketball - Women's": 3, | |
| "Baseball": 4, | |
| "Basketball": 5, | |
| "Hockey": 6, | |
| "Arena Sports": 7, | |
| "Volleyball": 8, | |
| "Lacrosse - Men's": 9, | |
| "Softball": 10, | |
| "Gymnastics": 11, | |
| "Soccer": 12, | |
| "Olympic Sports": 13, | |
| "Lacrosse": 14, | |
| "Soccer - Women's": 15, | |
| "Lacrosse - Women's": 16, | |
| "Soccer - Men's": 17, | |
| "Wrestling": 18 | |
| } | |
| geography_mapping = { | |
| "South": 1, | |
| "East Coast": 2, | |
| "Midwest": 3, | |
| "Mountain West": 4, | |
| "West Coast": 5 | |
| } | |
| conference_mapping = { | |
| "Power Four": 1, | |
| "Group of Five": 2, | |
| "Non-Power Four / Group of Five": 3, | |
| "Conference": 4 | |
| } | |
| new_row = pd.DataFrame({ | |
| 'InventoryBucket': [inventory_mapping[InventoryBucket]], | |
| 'Category': [category_mapping[Category]], | |
| 'Product': [product_mapping[Product]], | |
| 'Geography': [geography_mapping[Geography]], | |
| 'Conference': [conference_mapping[Conference]] | |
| }).astype(float) | |
| prediction = loaded_model.predict(new_row)[0] | |
| shap_values = explainer(new_row) | |
| fig, ax = plt.subplots(figsize=(8, 4)) | |
| shap.waterfall_plot(shap.Explanation( | |
| values=shap_values.values[0], | |
| base_values=shap_values.base_values[0], | |
| data=new_row.iloc[0] | |
| )) | |
| plt.tight_layout() | |
| local_plot = plt.gcf() | |
| plt.close() | |
| return f"Predicted Revenue: ${prediction:,.2f}", local_plot | |
| with gr.Blocks(title="Playfly Revenue Predictor") as demo: | |
| with gr.Row(): | |
| gr.Markdown("## Playfly Revenue Predictor & Interpreter") | |
| logo = gr.Image(label="", value="play-fly-logo.png", shape=(75, 75)) | |
| gr.Markdown("This app predicts **revenue** based on selected inventory, category, sport, geography, and conference.") | |
| gr.Markdown("---") | |
| label = gr.Label(label="Revenue Prediction") | |
| local_plot = gr.Plot(label="SHAP Waterfall Plot") | |
| with gr.Row(): | |
| InventoryBucket = gr.Dropdown(list(inventory_mapping.keys()), label="Inventory Bucket") | |
| Category = gr.Dropdown(list(category_mapping.keys()), label="Category") | |
| Product = gr.Dropdown(list(product_mapping.keys()), label="Product") | |
| Geography = gr.Dropdown(list(geography_mapping.keys()), label="Geography") | |
| Conference = gr.Dropdown(list(conference_mapping.keys()), label="Conference") | |
| analyze_btn = gr.Button("Analyze", elem_id="analyze_btn") | |
| analyze_btn.click( | |
| main_func, | |
| [InventoryBucket, Category, Product, Geography, Conference], | |
| [label, local_plot] | |
| ) | |
| gr.Markdown("---") | |
| gr.Examples( | |
| [ | |
| ["Field-Level Signage", "Signage", "Football", "East Coast", "Power Four"], | |
| ["Program and Guide (Digital)", "Print", "Basketball - Women's", "Midwest", "Group of Five"] | |
| ], | |
| [InventoryBucket, Category, Product, Geography, Conference], | |
| [label, local_plot], | |
| main_func, | |
| cache_examples=True | |
| ) | |
| demo.load(None, None, js=""" | |
| document.getElementById("analyze_btn").style.backgroundColor = "#4169E1"; | |
| document.getElementById("analyze_btn").style.color = "white"; | |
| """) | |
| demo.launch() | |