Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import joblib
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import numpy as np
|
| 5 |
+
import os
|
| 6 |
+
from PIL import Image
|
| 7 |
+
|
| 8 |
+
# Load models and encoders
|
| 9 |
+
def load_models():
|
| 10 |
+
try:
|
| 11 |
+
model = joblib.load('models/churn_model.pkl')
|
| 12 |
+
encoders = joblib.load('models/label_encoders.pkl')
|
| 13 |
+
try:
|
| 14 |
+
scaler = joblib.load('models/scaler.pkl')
|
| 15 |
+
except:
|
| 16 |
+
scaler = None
|
| 17 |
+
return model, encoders, scaler
|
| 18 |
+
except Exception as e:
|
| 19 |
+
print(f"Error loading models: {e}")
|
| 20 |
+
return None, None, None
|
| 21 |
+
|
| 22 |
+
model, encoders, scaler = load_models()
|
| 23 |
+
|
| 24 |
+
# Define feature options based on the training data
|
| 25 |
+
REGIONS = ['North', 'South', 'East', 'West', 'Central']
|
| 26 |
+
PLAN_TYPES = ['Prepaid', 'Postpaid']
|
| 27 |
+
CONTRACT_TYPES = ['Month-to-month', 'One year', 'Two year']
|
| 28 |
+
COMPLAINT_STATUS = ['Open', 'Closed', 'Not Applicable']
|
| 29 |
+
|
| 30 |
+
def predict_churn(customer_id, region, plan_type, monthly_charges, total_charges,
|
| 31 |
+
tenure_months, contract_type, paperless_billing, payment_method,
|
| 32 |
+
data_usage_gb, call_minutes, sms_count, complaint_status, complaint_count):
|
| 33 |
+
|
| 34 |
+
if model is None:
|
| 35 |
+
return "Model not loaded properly", 0.0
|
| 36 |
+
|
| 37 |
+
try:
|
| 38 |
+
# Create input dataframe
|
| 39 |
+
input_data = pd.DataFrame({
|
| 40 |
+
'customer_id': [customer_id],
|
| 41 |
+
'region': [region],
|
| 42 |
+
'plan_type': [plan_type],
|
| 43 |
+
'monthly_charges': [monthly_charges],
|
| 44 |
+
'total_charges': [total_charges],
|
| 45 |
+
'tenure_months': [tenure_months],
|
| 46 |
+
'contract_type': [contract_type],
|
| 47 |
+
'paperless_billing': [1 if paperless_billing else 0],
|
| 48 |
+
'payment_method': [payment_method],
|
| 49 |
+
'data_usage_gb': [data_usage_gb],
|
| 50 |
+
'call_minutes': [call_minutes],
|
| 51 |
+
'sms_count': [sms_count],
|
| 52 |
+
'complaint_status': [complaint_status],
|
| 53 |
+
'complaint_count': [complaint_count]
|
| 54 |
+
})
|
| 55 |
+
|
| 56 |
+
# Encode categorical variables
|
| 57 |
+
categorical_columns = ['region', 'plan_type', 'contract_type', 'payment_method', 'complaint_status']
|
| 58 |
+
|
| 59 |
+
for col in categorical_columns:
|
| 60 |
+
if col in encoders:
|
| 61 |
+
try:
|
| 62 |
+
input_data[col] = encoders[col].transform(input_data[col])
|
| 63 |
+
except ValueError:
|
| 64 |
+
# Handle unseen labels by using the most frequent class
|
| 65 |
+
input_data[col] = 0
|
| 66 |
+
|
| 67 |
+
# Drop customer_id for prediction
|
| 68 |
+
prediction_data = input_data.drop(['customer_id'], axis=1)
|
| 69 |
+
|
| 70 |
+
# Scale features if scaler exists
|
| 71 |
+
if scaler is not None:
|
| 72 |
+
prediction_data = scaler.transform(prediction_data)
|
| 73 |
+
|
| 74 |
+
# Make prediction
|
| 75 |
+
churn_probability = model.predict_proba(prediction_data)[0][1]
|
| 76 |
+
churn_prediction = "HIGH RISK" if churn_probability > 0.5 else "LOW RISK"
|
| 77 |
+
|
| 78 |
+
# Create detailed result
|
| 79 |
+
risk_level = "๐ด HIGH RISK" if churn_probability > 0.7 else "๐ก MEDIUM RISK" if churn_probability > 0.4 else "๐ข LOW RISK"
|
| 80 |
+
|
| 81 |
+
result = f"""
|
| 82 |
+
**Prediction Result for Customer {customer_id}**
|
| 83 |
+
|
| 84 |
+
**Churn Risk:** {risk_level}
|
| 85 |
+
**Churn Probability:** {churn_probability:.1%}
|
| 86 |
+
**Recommendation:** {'Immediate retention action required' if churn_probability > 0.7 else 'Monitor and engage' if churn_probability > 0.4 else 'Standard service maintenance'}
|
| 87 |
+
"""
|
| 88 |
+
|
| 89 |
+
return result, churn_probability
|
| 90 |
+
|
| 91 |
+
except Exception as e:
|
| 92 |
+
return f"Error in prediction: {str(e)}", 0.0
|
| 93 |
+
|
| 94 |
+
def load_image(image_name):
|
| 95 |
+
"""Load and return image from the images folder"""
|
| 96 |
+
try:
|
| 97 |
+
img_path = f"images/{image_name}"
|
| 98 |
+
if os.path.exists(img_path):
|
| 99 |
+
return Image.open(img_path)
|
| 100 |
+
else:
|
| 101 |
+
return None
|
| 102 |
+
except Exception as e:
|
| 103 |
+
print(f"Error loading image {image_name}: {e}")
|
| 104 |
+
return None
|
| 105 |
+
|
| 106 |
+
# Create Gradio interface
|
| 107 |
+
with gr.Blocks(title="Telecom Churn Prediction - BRBRAITT Group 5", theme=gr.themes.Soft()) as app:
|
| 108 |
+
|
| 109 |
+
# Header
|
| 110 |
+
gr.Markdown("""
|
| 111 |
+
# ๐ฎ Telecom Churn Prediction System
|
| 112 |
+
|
| 113 |
+
**TIRTC Course: Advance AI/ML Training - Telecom Data Analytics (Nokia)**
|
| 114 |
+
**Institution:** BRBRAITT, Jabalpur
|
| 115 |
+
|
| 116 |
+
**Group 5 Members:**
|
| 117 |
+
- Abhay Gupta
|
| 118 |
+
- Jay Kumar
|
| 119 |
+
- Kripanshu Gupta
|
| 120 |
+
- Ruhy Namdeo
|
| 121 |
+
|
| 122 |
+
---
|
| 123 |
+
|
| 124 |
+
This AI-powered system predicts customer churn with **90% accuracy** using Random Forest ML model.
|
| 125 |
+
""")
|
| 126 |
+
|
| 127 |
+
with gr.Tabs():
|
| 128 |
+
|
| 129 |
+
# Tab 1: Prediction Interface
|
| 130 |
+
with gr.TabItem("๐ฏ Churn Prediction"):
|
| 131 |
+
gr.Markdown("### Enter Customer Details for Churn Prediction")
|
| 132 |
+
|
| 133 |
+
with gr.Row():
|
| 134 |
+
with gr.Column():
|
| 135 |
+
customer_id = gr.Textbox(label="Customer ID", placeholder="e.g., CUST001", value="CUST001")
|
| 136 |
+
region = gr.Dropdown(choices=REGIONS, label="Region", value="North")
|
| 137 |
+
plan_type = gr.Dropdown(choices=PLAN_TYPES, label="Plan Type", value="Postpaid")
|
| 138 |
+
contract_type = gr.Dropdown(choices=CONTRACT_TYPES, label="Contract Type", value="Month-to-month")
|
| 139 |
+
|
| 140 |
+
with gr.Column():
|
| 141 |
+
monthly_charges = gr.Number(label="Monthly Charges (โน)", value=1000, minimum=0)
|
| 142 |
+
total_charges = gr.Number(label="Total Charges (โน)", value=12000, minimum=0)
|
| 143 |
+
tenure_months = gr.Number(label="Tenure (Months)", value=12, minimum=0, maximum=120)
|
| 144 |
+
paperless_billing = gr.Checkbox(label="Paperless Billing", value=True)
|
| 145 |
+
|
| 146 |
+
with gr.Column():
|
| 147 |
+
payment_method = gr.Dropdown(choices=['Electronic check', 'Mailed check', 'Bank transfer', 'Credit card'],
|
| 148 |
+
label="Payment Method", value="Electronic check")
|
| 149 |
+
data_usage_gb = gr.Number(label="Data Usage (GB)", value=15, minimum=0)
|
| 150 |
+
call_minutes = gr.Number(label="Call Minutes", value=500, minimum=0)
|
| 151 |
+
sms_count = gr.Number(label="SMS Count", value=100, minimum=0)
|
| 152 |
+
|
| 153 |
+
with gr.Row():
|
| 154 |
+
complaint_status = gr.Dropdown(choices=COMPLAINT_STATUS, label="Complaint Status", value="Not Applicable")
|
| 155 |
+
complaint_count = gr.Number(label="Complaint Count", value=0, minimum=0)
|
| 156 |
+
|
| 157 |
+
predict_btn = gr.Button("๐ฎ Predict Churn Risk", variant="primary", size="lg")
|
| 158 |
+
|
| 159 |
+
with gr.Row():
|
| 160 |
+
prediction_output = gr.Markdown()
|
| 161 |
+
probability_gauge = gr.Number(label="Churn Probability", interactive=False)
|
| 162 |
+
|
| 163 |
+
predict_btn.click(
|
| 164 |
+
fn=predict_churn,
|
| 165 |
+
inputs=[customer_id, region, plan_type, monthly_charges, total_charges,
|
| 166 |
+
tenure_months, contract_type, paperless_billing, payment_method,
|
| 167 |
+
data_usage_gb, call_minutes, sms_count, complaint_status, complaint_count],
|
| 168 |
+
outputs=[prediction_output, probability_gauge]
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
# Tab 2: Business Insights
|
| 172 |
+
with gr.TabItem("๐ Business Insights"):
|
| 173 |
+
gr.Markdown("### Key Findings from Analysis")
|
| 174 |
+
|
| 175 |
+
insights = gr.Markdown("""
|
| 176 |
+
## ๐ฏ Model Performance
|
| 177 |
+
- **Accuracy:** 90%
|
| 178 |
+
- **AUC Score:** 0.95
|
| 179 |
+
- **Best Algorithm:** Random Forest Classifier
|
| 180 |
+
|
| 181 |
+
## ๐ผ Business Impact
|
| 182 |
+
- **Current Churn Rate:** 50%
|
| 183 |
+
- **Revenue at Risk:** โน12,250+ monthly
|
| 184 |
+
- **Annual Loss:** โน147,000+ potential
|
| 185 |
+
- **Savings Opportunity:** โน36,750+ with 25% churn reduction
|
| 186 |
+
|
| 187 |
+
## ๐ด Top Risk Factors
|
| 188 |
+
1. **Contract Type:** Month-to-month customers (100% churn rate)
|
| 189 |
+
2. **Tenure:** New customers (0-12 months) at highest risk
|
| 190 |
+
3. **Complaints:** Open complaints double churn likelihood
|
| 191 |
+
4. **Plan Type:** Significant differences between Prepaid/Postpaid
|
| 192 |
+
|
| 193 |
+
## ๐ Recommendations
|
| 194 |
+
### Immediate Actions
|
| 195 |
+
- Target month-to-month customers for contract upgrades
|
| 196 |
+
- Implement 90-day new customer check-in program
|
| 197 |
+
- Prioritize complaint resolution within 48 hours
|
| 198 |
+
|
| 199 |
+
### Long-term Strategy
|
| 200 |
+
- Deploy real-time churn scoring system
|
| 201 |
+
- Implement tiered retention programs
|
| 202 |
+
- A/B test retention campaigns
|
| 203 |
+
""")
|
| 204 |
+
|
| 205 |
+
# Tab 3: Visualizations
|
| 206 |
+
with gr.TabItem("๐ Data Visualizations"):
|
| 207 |
+
gr.Markdown("### Comprehensive Analysis Dashboard")
|
| 208 |
+
|
| 209 |
+
# Load and display images
|
| 210 |
+
image_files = [
|
| 211 |
+
("churn_distribution.png", "Overall Churn Distribution"),
|
| 212 |
+
("churn_by_contract.png", "Churn by Contract Type"),
|
| 213 |
+
("churn_by_plan.png", "Churn by Plan Type"),
|
| 214 |
+
("churn_by_region.png", "Regional Churn Analysis"),
|
| 215 |
+
("tenure_vs_churn.png", "Tenure vs Churn Pattern"),
|
| 216 |
+
("revenue_vs_churn.png", "Revenue Impact Analysis"),
|
| 217 |
+
("complaints_analysis.png", "Complaints Impact on Churn"),
|
| 218 |
+
("correlation_matrix.png", "Feature Correlation Matrix"),
|
| 219 |
+
("feature_coefficients.png", "Model Feature Importance")
|
| 220 |
+
]
|
| 221 |
+
|
| 222 |
+
for img_file, title in image_files:
|
| 223 |
+
img = load_image(img_file)
|
| 224 |
+
if img is not None:
|
| 225 |
+
with gr.Row():
|
| 226 |
+
gr.Markdown(f"#### {title}")
|
| 227 |
+
with gr.Row():
|
| 228 |
+
gr.Image(img, label=title, show_label=False)
|
| 229 |
+
else:
|
| 230 |
+
gr.Markdown(f"*{title} - Image not available*")
|
| 231 |
+
|
| 232 |
+
# Tab 4: About Project
|
| 233 |
+
with gr.TabItem("โน๏ธ About Project"):
|
| 234 |
+
gr.Markdown("""
|
| 235 |
+
## ๐ Academic Project Details
|
| 236 |
+
|
| 237 |
+
**Course:** TIRTC - Advance AI/ML Training - Telecom Data Analytics (Nokia)
|
| 238 |
+
**Institution:** BRBRAITT (Bharat Ratna Bhimrao Ambedkar Institute of Technology and Training), Jabalpur
|
| 239 |
+
**Project Type:** Capstone Project 1
|
| 240 |
+
|
| 241 |
+
### ๐ฅ Team Members (Group 5)
|
| 242 |
+
- **Abhay Gupta**
|
| 243 |
+
- **Jay Kumar**
|
| 244 |
+
- **Kripanshu Gupta**
|
| 245 |
+
- **Ruhy Namdeo**
|
| 246 |
+
|
| 247 |
+
### ๐ ๏ธ Technical Stack
|
| 248 |
+
- **Machine Learning:** scikit-learn, Random Forest Classifier
|
| 249 |
+
- **Data Processing:** pandas, numpy
|
| 250 |
+
- **Visualization:** matplotlib, seaborn
|
| 251 |
+
- **Interface:** Gradio
|
| 252 |
+
- **Deployment:** Hugging Face Spaces
|
| 253 |
+
|
| 254 |
+
### ๐ Project Scope
|
| 255 |
+
This end-to-end machine learning project demonstrates:
|
| 256 |
+
- Data engineering and ETL pipeline
|
| 257 |
+
- Advanced ML model development
|
| 258 |
+
- Business intelligence and insights generation
|
| 259 |
+
- Production deployment capabilities
|
| 260 |
+
|
| 261 |
+
### ๐ฏ Learning Outcomes
|
| 262 |
+
- Real-world problem solving in telecom domain
|
| 263 |
+
- Complete ML pipeline implementation
|
| 264 |
+
- Business value creation through AI/ML
|
| 265 |
+
- Model deployment and productionization
|
| 266 |
+
|
| 267 |
+
---
|
| 268 |
+
|
| 269 |
+
**๐ Project Status:** Complete | **๐
Last Updated:** October 2024 | **๐ข Version:** 1.0.0
|
| 270 |
+
""")
|
| 271 |
+
|
| 272 |
+
# Footer
|
| 273 |
+
gr.Markdown("""
|
| 274 |
+
---
|
| 275 |
+
**ยฉ 2024 BRBRAITT Group 5 | TIRTC Advance AI/ML Training | Telecom Data Analytics**
|
| 276 |
+
""")
|
| 277 |
+
|
| 278 |
+
# Launch the app
|
| 279 |
+
if __name__ == "__main__":
|
| 280 |
+
app.launch(share=True, server_name="0.0.0.0", server_port=7860)
|