Spaces:
Sleeping
Sleeping
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("<br>"), | |
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("<br>"), | |
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("<br><br>") | |
), | |
), | |
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 | |
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 | |
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 | |
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 | |
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") | |
def predictions_123(): | |
try: | |
df, df_123, df_performance_metrics = get_lead_predictions() | |
return df_123 | |
except TypeError: | |
pass | |
def predictions(): | |
try: | |
df, df_123, df_performance_metrics = get_lead_predictions() | |
return df | |
except TypeError: | |
pass | |
def performance_metrics(): | |
try: | |
df, df_123, df_performance_metrics = get_lead_predictions() | |
return df_performance_metrics | |
except TypeError: | |
pass | |
def performance_metrics_campaign(): | |
try: | |
df, df_123, df_performance_metrics = get_campaign_predictions() | |
return df_performance_metrics | |
except TypeError: | |
pass | |
def predictions_123_rank(): | |
try: | |
df, df_123, ndcg, df_campaign_rank = get_lead_ranking() | |
return df_123 | |
except TypeError: | |
pass | |
def predictions_rank(): | |
try: | |
df, df_123, ndcg, df_campaign_rank = get_lead_ranking() | |
return df | |
except TypeError: | |
pass | |
def ndcg_score(): | |
try: | |
df, df_123, ndcg, df_campaign_rank = get_lead_ranking() | |
return ndcg | |
except TypeError: | |
pass | |
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) | |
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 | |
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) |