Spaces:
Runtime error
Runtime error
import plotly.express as px | |
import streamlit as st | |
import pandas as pd | |
from ai_assistant import get_ai_response | |
def get_score_rating(s): | |
if s >= 0.75: | |
return "HIGH" | |
elif 0.4 <= s < 0.75: | |
return "MEDIUM" | |
elif s < 0.4: | |
return "LOW" | |
def get_cov_rating(c): | |
if c >= 4: | |
return "Sufficient Coverage" | |
elif 2 <= c < 4: | |
return "Insufficient Coverage" | |
elif c < 2: | |
return "Significantly Insufficient Coverage" | |
def get_cust_data_dict(cust_name="Wong Ling Yit"): | |
data = pd.read_csv("data/yoda_data.csv") | |
poe_data = pd.read_csv("data/yoda_poe.csv") | |
reasons_df = pd.read_csv("data/yoda_reasonings.csv") | |
temp = data[data["cust_name"] == cust_name] | |
temp_poe = poe_data[poe_data["cust_name"] == cust_name] | |
temp_reason = reasons_df[reasons_df["cust_name"] == cust_name] | |
if len(temp) != 7 or \ | |
len(temp_poe) != 1 or \ | |
len(temp_reason) != 5: | |
temp = data[data["cust_name"] == "Wong Ling Yit"] | |
temp_poe = poe_data[poe_data["cust_name"] == "Wong Ling Yit"] | |
temp_reason = reasons_df[reasons_df["cust_name"] == "Wong Ling Yit"] | |
temp = temp.rename(columns={ | |
"prod_cat": "Product Category", | |
"cov_level": "Coverage Level", | |
"prop_score": "Score", | |
"recom_products": "Recommended Product" | |
}) | |
temp["Coverage Rating"] = temp["Coverage Level"].apply( | |
lambda c: get_cov_rating(c) | |
) | |
temp["Score Rating"] = temp["Score"].apply( | |
lambda s: get_score_rating(s) | |
) | |
cov_rating_map = dict(zip( | |
temp["Product Category"], | |
temp["Coverage Rating"] | |
)) | |
score_rating_map = dict(zip( | |
temp["Product Category"], | |
temp["Score Rating"] | |
)) | |
radar_df = pd.DataFrame({ | |
"Product Category": [ | |
"Retirement", | |
"Protection", | |
"Savings", | |
"CI", | |
"Investment", | |
"Legacy", | |
"Medical" | |
] | |
}) | |
radar_df = pd.merge(radar_df, temp, on="Product Category", how="inner") | |
temp = temp.sort_values("Score", ascending=False).reset_index(drop=True) | |
top_products = temp[:3]["Recommended Product"].tolist() | |
top_score = temp.iloc[0]["Score"] | |
score_rating = get_score_rating(top_score) | |
top_score_msg = f"{top_score:.2f} - {score_rating}" | |
poe_findings = temp_poe.iloc[0]["poe_findings"] | |
temp_reason = temp_reason.sort_values("r_index", ascending=True).reset_index(drop=True) | |
temp_reason_ls = temp_reason["reasonings"].tolist() | |
return (radar_df, temp, top_products, top_score_msg, | |
poe_findings, temp_reason_ls, | |
cov_rating_map, score_rating_map) | |
st.title("Persona: Financial Consultant - Leads follow-up") | |
st.header("Lead selection", divider="blue") | |
st.subheader("My customers - Hot Lead🔥") | |
cust_option = st.selectbox( | |
label="Customer options", | |
options=( | |
"Darek Cieslinski", "Anthony Finch", "Ariel CL Ong", | |
"Deren Meng", "Prabhavathi Bharadwaj", "Tan Li Lin", | |
"Wei Shan Chin", "Wong Chen Mey", "Wong Ling Yit"), | |
label_visibility="collapsed" | |
) | |
## "Wei Shan Chin", "Wong Chen Mey", "Tan Li Lin", "Prabhavathi Bharadwaj", | |
## "Deren Meng", "Anthony Finch", "Ariel CL Ong", "Darek Cieslinski" | |
data_pack = get_cust_data_dict(cust_name=cust_option) | |
radar_df = data_pack[0] | |
df = data_pack[1] | |
top_products = data_pack[2] | |
score_msg = data_pack[3] | |
poe_findings = data_pack[4] | |
model_reasons = data_pack[5] | |
cov_rating_map = data_pack[6] | |
score_rating_map = data_pack[7] | |
view_1, view_2 = st.columns(2, gap="medium") | |
with view_1: | |
st.subheader("Coverage level") | |
fig = px.line_polar(radar_df, r="Coverage Level", | |
theta="Product Category", line_close=True) | |
fig.update_layout( | |
margin=dict(l=60, r=40, t=20, b=20), | |
) | |
fig.update_traces(fill="toself") | |
st.plotly_chart(fig, theme="streamlit", use_container_width=True) | |
with view_2: | |
st.subheader("Propensity to buy") | |
fig = px.bar(df, x="Product Category", y="Score") | |
fig.update_layout( | |
margin=dict(l=60, r=40, t=50, b=20), | |
) | |
st.plotly_chart(fig, theme="streamlit", use_container_width=True) | |
st.write("") | |
st.write("***Expand to see more details.***") | |
with st.expander("Recent engagement.."): | |
st.subheader("Financial Needs Analysis (FNA)", divider="blue") | |
st.write("") | |
st.write("Date: 15/06/2022 - Protection need for family") | |
st.write("") | |
st.write("Date: 18/02/2019 - Critical Illness coverage gap of S$50,000") | |
st.divider() | |
st.subheader("Last policies purchased", divider="blue") | |
st.write("") | |
st.write("Date: 02/12/2017 - PRUActive LinkGuard purchased for self") | |
st.write("") | |
st.write("Date: 08/11/2013 - PRUWealth Plus (SGD) purchased for daughter") | |
st.divider() | |
st.write("") | |
st.header("Insights", divider="blue") | |
st.markdown( | |
f""" | |
**Recommended Products:** | |
- {top_products[0]} | |
- {top_products[1]} | |
- {top_products[2]} | |
**Top LIA Coverage Gap:** | |
- {poe_findings} | |
**Propensity to buy score:** | |
- {score_msg} | |
""" | |
) | |
st.header("Reasonings", divider="blue") | |
st.write("") | |
st.markdown( | |
f""" | |
**Model Reasonings:** | |
- {model_reasons[0]} | |
- {model_reasons[1]} | |
- {model_reasons[2]} | |
- {model_reasons[3]} | |
- {model_reasons[4]} | |
""" | |
) | |
st.write("") | |
st.header("Sales pitch", divider="blue") | |
list_of_cust_tabs = st.tabs(tabs=["Summary", "Assistant"]) | |
summary_tab = list_of_cust_tabs[0] | |
pitch_tab = list_of_cust_tabs[1] | |
about_this_cust = f""" | |
Opportunities | |
=============== | |
In terms of current coverage level, | |
- Retirement: {cov_rating_map["Retirement"]} | |
- Protection: {cov_rating_map["Protection"]} | |
- Savings: {cov_rating_map["Savings"]} | |
- Critical Illness: {cov_rating_map["CI"]} | |
- Investment: {cov_rating_map["Investment"]} | |
- Legacy: {cov_rating_map["Legacy"]} | |
- Medical: {cov_rating_map["Medical"]} | |
In terms of likelihood to buy, | |
- Retirement: {score_rating_map["Retirement"]} | |
- Protection: {score_rating_map["Protection"]} | |
- Savings: {score_rating_map["Savings"]} | |
- Critical Illness: {score_rating_map["CI"]} | |
- Investment: {score_rating_map["Investment"]} | |
- Legacy: {score_rating_map["Legacy"]} | |
- Medical: {score_rating_map["Medical"]} | |
Recent engagements | |
=================== | |
Financial Needs Analysis (FNA): | |
Date: 15/06/2022 - Protection need for family | |
Date: 18/02/2019 - Critical Illness coverage gap of S$50,000 | |
Last policies purchased: | |
Date: 02/12/2017 - PRUActive LinkGuard purchased for self | |
Date: 08/11/2013 - PRUWealth Plus (SGD) purchased for daughter | |
Insights | |
========= | |
Recommended Products: | |
- {top_products[0]} | |
- {top_products[1]} | |
- {top_products[2]} | |
Top LIA Coverage Gap: | |
- {poe_findings} | |
Propensity to buy score: {score_msg} | |
Predictive model reasonings | |
=========================== | |
- {model_reasons[0]} | |
- {model_reasons[1]} | |
- {model_reasons[2]} | |
- {model_reasons[3]} | |
- {model_reasons[4]} | |
""".strip() | |
with summary_tab: | |
txt = st.text_area( | |
"About this customer", | |
about_this_cust, | |
height=500 | |
) | |
with pitch_tab: | |
st.write("Suggest sales pitch for this customer") | |
generate_button = st.button("Generate") | |
if generate_button: | |
placeholder = st.empty() | |
full_response = "" | |
stream = get_ai_response(about_this_cust) | |
for chunk in stream: | |
token = chunk.choices[0].delta.content | |
if token is not None: | |
full_response += token | |
# full_response += token.replace("\n", " \n") \ | |
# .replace("$", "\$") \ | |
# .replace("\[", "$$") | |
placeholder.markdown(full_response) | |
placeholder.markdown(full_response) | |
print(full_response) |