dararaje's picture
Update app.py
8ad1f00 verified
#!/usr/bin/env python3
"""
Streamlit App for Tourism Package Prediction
"""
%%writefile tourism_project/deployment/app.py
import streamlit as st
import pandas as pd
import joblib
from huggingface_hub import hf_hub_download
import os
# Page configuration
st.set_page_config(
page_title="Tourism Package Prediction",
page_icon="โœˆ๏ธ",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS for better styling
st.markdown("""
<style>
.main-header {
font-size: 2.5rem;
color: #1f77b4;
text-align: center;
margin-bottom: 2rem;
}
.sub-header {
font-size: 1.5rem;
color: #2c3e50;
margin-top: 1rem;
margin-bottom: 1rem;
}
.prediction-box {
padding: 2rem;
border-radius: 10px;
margin-top: 2rem;
}
.success-box {
background-color: #d4edda;
border: 2px solid #28a745;
}
.danger-box {
background-color: #f8d7da;
border: 2px solid #dc3545;
}
</style>
""", unsafe_allow_html=True)
# Cache the model loading to avoid reloading on every interaction
@st.cache_resource
def load_model_and_preprocessor():
"""Load model and preprocessor from HuggingFace"""
try:
with st.spinner("Loading model and preprocessor from HuggingFace..."):
model_path = hf_hub_download(
repo_id="dararaje/Tourism_Package_Prediction",
filename="tourism_model.pkl",
repo_type="model"
)
preprocessor_path = hf_hub_download(
repo_id="dararaje/Tourism_Package_Prediction",
filename="tourism_preprocessor.pkl",
repo_type="model"
)
model = joblib.load(model_path)
preprocessor = joblib.load(preprocessor_path)
return model, preprocessor
except Exception as e:
st.error(f"Error loading model: {str(e)}")
st.error("Make sure you have run upload_model.py to upload the model files to HuggingFace")
st.stop()
# Load model and preprocessor
model, preprocessor = load_model_and_preprocessor()
# Main title
st.markdown('<h1 class="main-header">๐ŸŒ Tourism Package Prediction</h1>', unsafe_allow_html=True)
st.markdown("### Predict if a customer will purchase the Tourism Package")
st.markdown("---")
# Create sidebar for information
with st.sidebar:
st.image("https://img.icons8.com/fluency/96/000000/around-the-world.png", width=100)
st.markdown("## About This App")
st.info(
"""
This application uses machine learning to predict whether a customer
will purchase the Tourism Package based on:
- Customer demographics
- Travel preferences
- Sales interaction quality
"""
)
st.markdown("## Model Information")
st.markdown("""
- **Algorithm**: Machine Learning Classifier
- **Features**: 18 customer attributes
- **Output**: Purchase probability
""")
st.markdown("## How to Use")
st.markdown("""
1. Fill in customer details in the form
2. Click 'Predict Purchase Likelihood'
3. View prediction results with confidence scores
""")
# Create three columns for organized input
col1, col2, col3 = st.columns(3)
with col1:
st.markdown('<p class="sub-header">๐Ÿ‘ค Customer Demographics</p>', unsafe_allow_html=True)
age = st.number_input("Age", min_value=18, max_value=100, value=30, step=1)
gender = st.selectbox("Gender", options=["Male", "Female"])
marital_status = st.selectbox(
"Marital Status",
options=["Single", "Married", "Divorced", "Unmarried"]
)
city_tier = st.selectbox(
"City Tier",
options=[1, 2, 3],
format_func=lambda x: f"Tier {x} {'(Metro)' if x==1 else '(Tier-2)' if x==2 else '(Tier-3)'}"
)
occupation = st.selectbox(
"Occupation",
options=["Salaried", "Small Business", "Large Business", "Free Lancer"]
)
designation = st.selectbox(
"Designation",
options=["Executive", "Manager", "Senior Manager", "AVP", "VP"]
)
monthly_income = st.number_input(
"Monthly Income (โ‚น)",
min_value=0,
max_value=1000000,
value=20000,
step=1000
)
with col2:
st.markdown('<p class="sub-header">๐Ÿงณ Travel Preferences</p>', unsafe_allow_html=True)
num_person_visiting = st.number_input(
"Number of Persons Visiting",
min_value=1,
max_value=10,
value=2,
step=1
)
num_children_visiting = st.number_input(
"Number of Children Visiting (below 5 years)",
min_value=0,
max_value=5,
value=0,
step=1
)
preferred_property_star = st.selectbox(
"Preferred Property Star Rating",
options=[3.0, 4.0, 5.0],
format_func=lambda x: f"{int(x)} Star"
)
num_trips = st.number_input(
"Number of Trips per Year",
min_value=0,
max_value=20,
value=2,
step=1
)
passport = st.selectbox(
"Has Passport?",
options=[1, 0],
format_func=lambda x: "Yes" if x == 1 else "No"
)
own_car = st.selectbox(
"Owns Car?",
options=[1, 0],
format_func=lambda x: "Yes" if x == 1 else "No"
)
with col3:
st.markdown('<p class="sub-header">๐Ÿ’ผ Sales Interaction Details</p>', unsafe_allow_html=True)
type_of_contact = st.selectbox(
"Type of Contact",
options=["Company Invited", "Self Inquiry"]
)
product_pitched = st.selectbox(
"Product Pitched",
options=["Basic", "Standard", "Deluxe", "Super Deluxe", "King"]
)
pitch_satisfaction_score = st.slider(
"Pitch Satisfaction Score",
min_value=1,
max_value=5,
value=3,
step=1
)
num_followups = st.number_input(
"Number of Follow-ups",
min_value=0,
max_value=10,
value=3,
step=1
)
duration_of_pitch = st.number_input(
"Duration of Pitch (minutes)",
min_value=0,
max_value=120,
value=15,
step=1
)
# Center the predict button
st.markdown("---")
col_button1, col_button2, col_button3 = st.columns([1, 1, 1])
with col_button2:
predict_button = st.button("๐Ÿ”ฎ Predict Purchase Likelihood", type="primary", use_container_width=True)
# Prediction logic
if predict_button:
try:
# Create input dataframe
input_data = pd.DataFrame({
'Age': [age],
'TypeofContact': [type_of_contact],
'CityTier': [city_tier],
'Occupation': [occupation],
'Gender': [gender],
'NumberOfPersonVisiting': [num_person_visiting],
'PreferredPropertyStar': [preferred_property_star],
'MaritalStatus': [marital_status],
'NumberOfTrips': [num_trips],
'Passport': [passport],
'OwnCar': [own_car],
'NumberOfChildrenVisiting': [num_children_visiting],
'Designation': [designation],
'MonthlyIncome': [monthly_income],
'PitchSatisfactionScore': [pitch_satisfaction_score],
'ProductPitched': [product_pitched],
'NumberOfFollowups': [num_followups],
'DurationOfPitch': [duration_of_pitch]
})
# Preprocess and predict
processed_data = preprocessor.transform(input_data)
prediction = model.predict(processed_data)
probability = model.predict_proba(processed_data)
# Display results
st.markdown("---")
if prediction[0] == 1:
st.markdown('<div class="prediction-box success-box">', unsafe_allow_html=True)
st.markdown("### โœ… Prediction: WILL PURCHASE")
st.markdown(f"#### Confidence: {probability[0][1] * 100:.2f}%")
st.markdown('</div>', unsafe_allow_html=True)
else:
st.markdown('<div class="prediction-box danger-box">', unsafe_allow_html=True)
st.markdown("### โŒ Prediction: WILL NOT PURCHASE")
st.markdown(f"#### Confidence: {probability[0][0] * 100:.2f}%")
st.markdown('</div>', unsafe_allow_html=True)
# Probability breakdown
st.markdown("### ๐Ÿ“Š Probability Breakdown")
col_prob1, col_prob2 = st.columns(2)
with col_prob1:
st.metric(
label="Purchase Probability",
value=f"{probability[0][1] * 100:.2f}%",
delta=f"{(probability[0][1] - 0.5) * 100:.2f}% from baseline"
)
with col_prob2:
st.metric(
label="No Purchase Probability",
value=f"{probability[0][0] * 100:.2f}%",
delta=f"{(probability[0][0] - 0.5) * 100:.2f}% from baseline"
)
# Progress bars for visualization
st.markdown("#### Visual Probability Distribution")
st.progress(probability[0][1], text=f"Purchase: {probability[0][1] * 100:.1f}%")
st.progress(probability[0][0], text=f"No Purchase: {probability[0][0] * 100:.1f}%")
# Recommendation
st.markdown("### ๐Ÿ’ก Recommendation")
if prediction[0] == 1:
if probability[0][1] > 0.75:
st.success("**High Priority Lead**: Strong likelihood of purchase. Recommend immediate follow-up with premium package details.")
else:
st.info("**Moderate Priority Lead**: Good potential for purchase. Consider personalized follow-up with package benefits.")
else:
if probability[0][0] > 0.75:
st.warning("**Low Priority Lead**: Low likelihood of purchase. May require additional nurturing or different product offering.")
else:
st.info("**Uncertain Lead**: Probability is borderline. Additional information or engagement might help.")
except Exception as e:
st.error(f"Error making prediction: {str(e)}")
st.exception(e)
# Footer
st.markdown("---")
st.markdown("""
<div style='text-align: center; color: #7f8c8d;'>
<p>Built with โค๏ธ using Streamlit and HuggingFace | Tourism Package Prediction MLOps Project</p>
</div>
""", unsafe_allow_html=True)