import gradio as gr import pandas as pd import numpy as np import pickle import plotly.express as px import plotly.graph_objects as go from sklearn.decomposition import PCA import os # Ensure model and data exist before loading required_files = [ 'model/kmeans.pkl', 'model/scaler.pkl', 'model/label_encoder.pkl', 'data/clustered_customers.csv' ] if any(not os.path.exists(f) for f in required_files): print("Required models or data not found. Running training...") from train import train_model train_model() # Load model, scaler, and label encoder with open('model/kmeans.pkl', 'rb') as f: kmeans = pickle.load(f) with open('model/scaler.pkl', 'rb') as f: scaler = pickle.load(f) with open('model/label_encoder.pkl', 'rb') as f: le = pickle.load(f) # Load clustered data for visualization df_clustered = pd.read_csv('data/clustered_customers.csv') # Cluster labels and descriptions CLUSTER_MAP = { 0: {"label": "Sensible Customers", "desc": "Medium income, medium spending. Stable group.", "insight": "Maintain relationship with loyalty programs."}, 1: {"label": "High Value Targets", "desc": "High income, high spending. Most profitable.", "insight": "Offer premium deals and exclusive previews."}, 2: {"label": "Budget Conscious", "desc": "Low income, low spending. Price sensitive.", "insight": "Focus on value-for-money offers and discounts."}, 3: {"label": "Impulsive Buyers", "desc": "Low income, high spending. High engagement.", "insight": "Target with flash sales and trendy items."}, 4: {"label": "Cautious High-Earners", "desc": "High income, low spending. Conservative.", "insight": "Focus on quality and long-term value marketing."} } def predict_and_visualize(gender, age, income, spending_score): # Prepare input for prediction gender_encoded = le.transform([gender])[0] input_data = np.array([[gender_encoded, age, income, spending_score]]) input_scaled = scaler.transform(input_data) # Predict cluster cluster = kmeans.predict(input_scaled)[0] info = CLUSTER_MAP[cluster] # Update data with user input for visualization user_point = pd.DataFrame({ 'Gender': [gender_encoded], 'Age': [age], 'Annual Income (k$)': [income], 'Spending Score (1-100)': [spending_score], 'Cluster': [cluster], 'Type': ['User Input'] }) temp_df = df_clustered.copy() temp_df['Type'] = 'Existing Customer' # (A) Cluster Scatter Plot (Income vs Spending) # Ensure background data is plotted first fig_scatter = px.scatter( df_clustered, x='Annual Income (k$)', y='Spending Score (1-100)', color='Cluster', title='Customer Segments: Income vs Spending', color_continuous_scale='Viridis', labels={'Cluster': 'Segment ID'}, opacity=0.6 # Make existing customers slightly transparent ) # Add user point on top with distinct styling fig_scatter.add_trace( go.Scatter( x=[income], y=[spending_score], mode='markers', marker=dict(color='red', size=18, symbol='star', line=dict(width=2, color='white')), name='YOU' ) ) fig_scatter.update_layout(legend_title_text='Segments') # (B) PCA Visualization pca = PCA(n_components=2) features = ['Gender', 'Age', 'Annual Income (k$)', 'Spending Score (1-100)'] all_features_scaled = scaler.transform(df_clustered[features]) pca_results = pca.fit_transform(all_features_scaled) df_pca = pd.DataFrame(pca_results, columns=['PC1', 'PC2']) df_pca['Cluster'] = df_clustered['Cluster'] user_pca = pca.transform(input_scaled) fig_pca = px.scatter( df_pca, x='PC1', y='PC2', color='Cluster', title='PCA: 2D Cluster Separation', color_continuous_scale='Plasma', opacity=0.6 ) fig_pca.add_trace( go.Scatter( x=[user_pca[0][0]], y=[user_pca[0][1]], mode='markers', marker=dict(color='red', size=18, symbol='star', line=dict(width=2, color='white')), name='YOU' ) ) fig_pca.update_layout(legend_title_text='Segments') result_md = f""" ### 🎯 Prediction: {info['label']} **Description:** {info['desc']} **💡 Business Insight:** *{info['insight']}* """ return result_md, fig_scatter, fig_pca # Build Gradio Interface with gr.Blocks(theme=gr.themes.Soft(), title="SmartSeg AI") as demo: gr.Markdown(""" # 🤖 SmartSeg AI – Advanced Customer Segmentation ### Analyze and categorize customers in real-time using Machine Learning. """) with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 👤 Customer Profile") gender = gr.Radio(["Male", "Female"], label="Gender", value="Female") age = gr.Slider(18, 100, step=1, label="Age", value=30) income = gr.Slider(10, 150, step=1, label="Annual Income (k$)", value=50) spending = gr.Slider(1, 100, step=1, label="Spending Score (1-100)", value=50) predict_btn = gr.Button("Predict Segment", variant="primary") output_text = gr.Markdown("### Results will appear here after prediction.") with gr.Column(scale=2): with gr.Tabs(): with gr.TabItem("Income vs Spending"): plot_scatter = gr.Plot() with gr.TabItem("PCA 2D Projection"): plot_pca = gr.Plot() # Define interaction predict_btn.click( fn=predict_and_visualize, inputs=[gender, age, income, spending], outputs=[output_text, plot_scatter, plot_pca] ) # Initialize with a default prediction demo.load(predict_and_visualize, [gender, age, income, spending], [output_text, plot_scatter, plot_pca]) if __name__ == "__main__": # Use 0.0.0.0 as server_name for Hugging Face Spaces and local access demo.launch(server_name="0.0.0.0", server_port=7860)