import os from shiny import App, ui, render, reactive, module from shiny import experimental as x import shinyswatch import pandas as pd from modules import lead_ids, classification, ranking, support_texts # Define lead options leads_8 = lead_ids.leads_8 leads_123 = lead_ids.leads_123 leads_256 = lead_ids.leads_256 app_ui = ui.page_fluid( shinyswatch.theme.minty(), ui.panel_title("Lead Recommender System"), ui.layout_sidebar( ui.panel_sidebar( ui.input_checkbox( "explanation_select", "Show explanation", True ), ui.markdown("**Data**"), ui.input_select( "campaign_select", "Select campaign id:", choices = ["8", "123", "256"], selected = "8" ), ui.input_select( "lead_select", "Select lead id:", choices = leads_8 ), ui.HTML("
"), ui.markdown("**Classification**"), ui.input_select( "model_select", "Select classification model:", choices = ["BERT", "XGB"], selected = "BERT" ), ui.input_select( "proba_cutoff_select", "Select minimum relevance probability (%):", choices = [50, 60, 65, 70, 75, 80, 85, 90, 95], selected = 80 ), ui.HTML("
"), ui.markdown("**Ranking**"), ui.input_select( "model_select_rank", "Select ranking model:", choices = ["Light XGBM 1", "Light XGBM 2", "Light XGBM 3"], selected = "Light XGBM 3" ), ui.input_select( "rank_cutoff_select", "Select minimum prediction score (%):", choices = [50, 60, 65, 70, 75, 80, 85, 90, 95], selected = 80 ), width=2.5 ), ui.navset_tab( ui.nav("Classification", ui.panel_main( ui.panel_conditional("input.explanation_select", ui.row( ui.column( 12, x.ui.card( ui.markdown(support_texts.classification_intro_1), ui.markdown(support_texts.classification_intro_2), ui.markdown(support_texts.classification_intro_3), ), ), ), ), ui.row( ui.column( 12, x.ui.card( ui.markdown("**Model classification performance of selected lead**"), ui.output_data_frame("performance_metrics"), ), ), ), ui.row( ui.column( 12, x.ui.card( ui.markdown("**Top 3 relevant employees in selected lead**"), ui.output_data_frame("predictions_123"), ), x.ui.card( ui.markdown("**All employees in selected lead**"), ui.output_data_frame("predictions"), ), ), ), ui.row( ui.column( 12, x.ui.card( ui.markdown("**Model descriptions and testing performance**"), ui.markdown(support_texts.models_test_classification_1), ui.output_data_frame("models_test_classification"), ui.markdown(support_texts.models_test_classification_2) ), ), ), ), ), ui.nav("Ranking", ui.panel_main( ui.panel_conditional("input.explanation_select", ui.row( ui.column( 12, x.ui.card( ui.markdown(support_texts.ranking_intro_1), ui.markdown(support_texts.ranking_intro_2), ui.markdown(support_texts.ranking_intro_3), ), ), ), ), ui.row( ui.column( 12, x.ui.card( ui.markdown("**Model ranking performance of selected lead**"), ui.output_data_frame("ndcg_score") ), x.ui.card( ui.markdown("**Top 3 relevant employees in selected lead**"), ui.output_data_frame("predictions_123_rank"), ), ), ), ui.row( ui.column( 12, x.ui.card( ui.markdown("**Ranking of all employees in selected lead**"), ui.output_data_frame("predictions_rank") ), ), ), ui.row( ui.column( 12, x.ui.card( ui.markdown("**Model descriptions and testing performance**"), ui.markdown("The table below shows the model performance on a larger testing dataset (does not contain the campaigns in this dashboard)"), ui.output_data_frame("models_test_ranking"), ui.markdown(support_texts.models_test_ranking_1) ), ), ), ), ), ui.nav("Comparison", ui.panel_main( ui.row( ui.markdown("**Model performance comparison (campaign-level)**"), ui.column( 6, x.ui.card( ui.markdown("**Classification model performance**"), ui.output_data_frame("performance_metrics_campaign"), ui.markdown("

") ), ), ui.column( 6, x.ui.card( ui.markdown("**Ranking model performance**"), ui.output_data_frame("campaign_rank") ), ), ), ui.row( ui.column( 12, x.ui.card( ui.markdown(support_texts.comparison_1) ), ), ), ui.row( ui.column( 12, x.ui.card( ui.markdown(support_texts.ranking_ndcg) ), ), ), ), ), ), ), ) def server(input, output, session): # Updating lead id selection list @reactive.Effect() def _(): if input.campaign_select() == "8": lead_options = leads_8 elif input.campaign_select() == "123": lead_options = leads_123 elif input.campaign_select() == "256": lead_options = leads_256 ui.update_select("lead_select", label="Select lead id:", choices=lead_options ) ui.update_switch # Get classification data single lead @reactive.Calc def get_lead_predictions(): try: df, df_123, df_performance_metrics = classification.classify(CAMPAIGN_ID=int(input.campaign_select()), LEAD_ID=int(input.lead_select()), proba_cutoff=int(input.proba_cutoff_select()), model_type=input.model_select()) return df, df_123, df_performance_metrics except TypeError: pass except Exception: ui.notification_show("Data is still loading or something went wrong", duration=3, type="error") # Get classification data single lead @reactive.Calc def get_campaign_predictions(): try: df, df_123, df_performance_metrics = classification.classify(CAMPAIGN_ID=int(input.campaign_select()), LEAD_ID=int(input.lead_select()), proba_cutoff=int(input.proba_cutoff_select()), model_type=input.model_select(), full_campaign=True) return df, df_123, df_performance_metrics except TypeError: pass except Exception: ui.notification_show("Data is still loading or something went wrong", duration=3, type="error") # Get ranking data @reactive.Calc def get_lead_ranking(): try: df, df_123, ndcg, df_campaign_rank = ranking.rank_single_lead(CAMPAIGN_ID=int(input.campaign_select()), LEAD_ID=int(input.lead_select()), rank_cutoff=int(input.rank_cutoff_select()), ranker=input.model_select_rank()) return df, df_123, ndcg, df_campaign_rank except TypeError: pass except Exception: ui.notification_show("Data is still loading or something went wrong", duration=3, type="error") @output @render.data_frame def predictions_123(): try: df, df_123, df_performance_metrics = get_lead_predictions() return df_123 except TypeError: pass @output @render.data_frame def predictions(): try: df, df_123, df_performance_metrics = get_lead_predictions() return df except TypeError: pass @output @render.data_frame def performance_metrics(): try: df, df_123, df_performance_metrics = get_lead_predictions() return df_performance_metrics except TypeError: pass @output @render.data_frame def performance_metrics_campaign(): try: df, df_123, df_performance_metrics = get_campaign_predictions() return df_performance_metrics except TypeError: pass @output @render.data_frame def predictions_123_rank(): try: df, df_123, ndcg, df_campaign_rank = get_lead_ranking() return df_123 except TypeError: pass @output @render.data_frame def predictions_rank(): try: df, df_123, ndcg, df_campaign_rank = get_lead_ranking() return df except TypeError: pass @output @render.data_frame def ndcg_score(): try: df, df_123, ndcg, df_campaign_rank = get_lead_ranking() return ndcg except TypeError: pass @output @render.data_frame def campaign_rank(): try: df, df_123, ndcg, df_campaign_rank = get_lead_ranking() return df_campaign_rank except TypeError: pass # Model performance tables (test set) @output @render.data_frame def models_test_classification(): try: models_test_classification_data = {'Model': ['BERT', 'XGB'], 'F1 weighted': [0.84, 0.81], 'F1': [0.35, 0.35], 'Accuracy': [0.80, 0.76], 'Recall': [0.65, 0.78], 'Precision': [0.24, 0.22]} df_models_test_classification = pd.DataFrame.from_dict(data=models_test_classification_data, orient='index', columns=models_test_classification_data['Model']) df_models_test_classification = df_models_test_classification.iloc[1:] df_models_test_classification.reset_index(inplace=True, names=['Metric']) return df_models_test_classification except TypeError: pass @output @render.data_frame def models_test_ranking(): try: models_test_ranking_data = {'Model': ['Light XGBM 1', 'Light XGBM 2', 'Light XGBM 3'], 'NDCG@k score': [0.652, 0.2, 0.948], 'k': [3,3,3]} df_models_test_ranking = pd.DataFrame.from_dict(data=models_test_ranking_data, orient='index', columns=models_test_ranking_data['Model']) df_models_test_ranking = df_models_test_ranking.iloc[1:] df_models_test_ranking.reset_index(inplace=True, names=['Metric']) return df_models_test_ranking except TypeError: pass app = App(app_ui, server)