import gradio as gr import pandas as pd import joblib rf_model = joblib.load("rf_model.pkl") feature_cols = joblib.load("feature_cols.pkl") gender_map = {'Female': 0, 'Male': 1} partner_map = {'No': 0, 'Yes': 1} dependents_map = {'No': 0, 'Yes': 1} contract_map = {'Month-to-month': 0, 'One year': 1, 'Two year': 2} payment_map = { 'Bank transfer (automatic)': 0, 'Credit card (automatic)': 1, 'Electronic check': 2, 'Mailed check': 3 } internet_map = {'DSL': 0, 'Fiber optic': 1, 'No': 2} tech_map = {'No': 0, 'No internet service': 1, 'Yes': 2} complaint_map = { 'Billing Issue': 0, 'Contract Dispute': 1, 'Overcharge': 2, 'Service Outage': 3, 'Speed/Performance': 4, 'Technical Failure': 5 } risk_map = {'High': 0, 'Low': 1, 'Medium': 2} def predict_churn( tenure, monthly_charges, total_charges, senior, gender, partner, dependents, contract, payment, internet, tech, support_calls, avg_call_duration, days_since_last_contact, sentiment, complaint, risk ): try: input_df = pd.DataFrame([{ 'SeniorCitizen': senior, 'tenure': tenure, 'MonthlyCharges': monthly_charges, 'TotalCharges': total_charges, 'gender_enc': gender_map[gender], 'Partner_enc': partner_map[partner], 'Dependents_enc': dependents_map[dependents], 'Contract_enc': contract_map[contract], 'PaymentMethod_enc': payment_map[payment], 'InternetService_enc': internet_map[internet], 'TechSupport_enc': tech_map[tech], 'support_calls': support_calls, 'avg_call_duration': avg_call_duration, 'days_since_last_contact': days_since_last_contact, 'sentiment_score': sentiment, 'complaint_type_enc': complaint_map[complaint], 'support_churn_risk_enc': risk_map[risk] }]) input_df = input_df[feature_cols] pred = rf_model.predict(input_df)[0] prob = rf_model.predict_proba(input_df)[0][1] if prob >= 0.75: risk_level = "High" recommendation = "Immediate retention outreach and service recovery." elif prob >= 0.40: risk_level = "Medium" recommendation = "Proactive follow-up and customer care check-in." else: risk_level = "Low" recommendation = "Maintain normal engagement and service quality." churn_label = "Yes" if pred == 1 else "No" drivers = [] if contract == "Month-to-month": drivers.append("month-to-month contract") if support_calls >= 5: drivers.append("frequent support calls") if sentiment < 0: drivers.append("negative sentiment") if tech == "No": drivers.append("lack of tech support") if monthly_charges > 80: drivers.append("higher monthly charges") if drivers: explanation = "Main risk drivers: " + ", ".join(drivers) + "." else: explanation = "Risk is based on the combined customer, billing, and support profile." return churn_label, f"{prob:.2%}", risk_level, explanation, recommendation except Exception as e: return "Error", "Error", "Error", f"Something went wrong: {str(e)}", "Please review the inputs." with gr.Blocks(title="ChurnGuard – AI Customer Retention Advisor") as demo: gr.Markdown(""" # ChurnGuard – AI Customer Retention Advisor This app turns our churn model into a decision-support tool for telecom retention strategy. It combines billing, contract, demographic, and synthetic support-interaction features to estimate churn risk. """) with gr.Row(): with gr.Column(scale=2): gr.Markdown("## Customer Profile") senior = gr.Dropdown([0, 1], value=0, label="Senior Citizen (0 = No, 1 = Yes)") gender = gr.Dropdown(['Female', 'Male'], value='Female', label="Gender") partner = gr.Dropdown(['No', 'Yes'], value='No', label="Partner") dependents = gr.Dropdown(['No', 'Yes'], value='No', label="Dependents") tenure = gr.Slider(0, 72, value=12, step=1, label="Tenure (months)") gr.Markdown("## Service & Contract") monthly_charges = gr.Slider(0, 150, value=70, step=0.1, label="Monthly Charges") total_charges = gr.Slider(0, 10000, value=1000, step=1, label="Total Charges") contract = gr.Dropdown(['Month-to-month', 'One year', 'Two year'], value='Month-to-month', label="Contract") payment = gr.Dropdown([ 'Bank transfer (automatic)', 'Credit card (automatic)', 'Electronic check', 'Mailed check' ], value='Bank transfer (automatic)', label="Payment Method") internet = gr.Dropdown(['DSL', 'Fiber optic', 'No'], value='DSL', label="Internet Service") tech = gr.Dropdown(['No', 'No internet service', 'Yes'], value='No', label="Tech Support") gr.Markdown("## Support Interaction Signals") support_calls = gr.Slider(0, 15, value=3, step=1, label="Support Calls") avg_call_duration = gr.Slider(0, 30, value=8, step=0.1, label="Average Call Duration (minutes)") days_since_last_contact = gr.Slider(0, 120, value=20, step=1, label="Days Since Last Contact") sentiment = gr.Slider(-1, 1, value=0, step=0.01, label="Sentiment Score") complaint = gr.Dropdown([ 'Billing Issue', 'Contract Dispute', 'Overcharge', 'Service Outage', 'Speed/Performance', 'Technical Failure' ], value='Billing Issue', label="Complaint Type") risk = gr.Dropdown(['High', 'Low', 'Medium'], value='Low', label="Support Churn Risk") submit_btn = gr.Button("Predict Churn Risk", variant="primary") with gr.Column(scale=1): gr.Markdown("## Prediction Results") pred_out = gr.Textbox(label="Predicted Churn") prob_out = gr.Textbox(label="Churn Probability") risk_out = gr.Textbox(label="Risk Level") explanation_out = gr.Textbox(label="Explanation") recommendation_out = gr.Textbox(label="Recommended Action") submit_btn.click( fn=predict_churn, inputs=[ tenure, monthly_charges, total_charges, senior, gender, partner, dependents, contract, payment, internet, tech, support_calls, avg_call_duration, days_since_last_contact, sentiment, complaint, risk ], outputs=[pred_out, prob_out, risk_out, explanation_out, recommendation_out] ) demo.launch()