|
|
import streamlit as st |
|
|
import pandas as pd |
|
|
import numpy as np |
|
|
import matplotlib.pyplot as plt |
|
|
import seaborn as sns |
|
|
import altair as alt |
|
|
import plotly.express as px |
|
|
from sklearn.model_selection import train_test_split |
|
|
import joblib |
|
|
import shap as shap |
|
|
from xgboost import XGBClassifier |
|
|
from sklearn.preprocessing import OneHotEncoder |
|
|
from streamlit_shap import st_shap |
|
|
|
|
|
|
|
|
@st.cache |
|
|
def load_data(): |
|
|
data = pd.read_csv('data_cleaned_new.csv') |
|
|
return data |
|
|
|
|
|
@st.cache_resource |
|
|
def load_model_and_encoder(): |
|
|
xgb_model = joblib.load('xgb_model.joblib') |
|
|
ohe = joblib.load('ohe.joblib') |
|
|
return xgb_model, ohe |
|
|
|
|
|
xgb_model, ohe = load_model_and_encoder() |
|
|
|
|
|
|
|
|
|
|
|
data = load_data() |
|
|
|
|
|
|
|
|
st.sidebar.title("Explore Financial Insights") |
|
|
option = st.sidebar.radio( |
|
|
"Select an analysis section:", |
|
|
("Home", 'Description of Variables', "Regional-Based Analysis", "Income-Based Analysis", "Gender-Based Analysis", "Financial Recommender Engine", "SML Classification") |
|
|
) |
|
|
|
|
|
|
|
|
st.sidebar.markdown("### What is Findex?") |
|
|
st.sidebar.write(""" |
|
|
The Global Findex database provides comprehensive data on how adults worldwide save, borrow, make payments, and manage risk. |
|
|
Launched with support from the Bill & Melinda Gates Foundation, the database is updated every three years and is the world’s most |
|
|
detailed dataset on how adults use formal and informal financial services. It offers insights into the financial behaviors and |
|
|
access to financial systems globally. |
|
|
|
|
|
For more information, visit the [Global Findex website](https://www.worldbank.org/en/publication/globalfindex). |
|
|
""") |
|
|
|
|
|
|
|
|
if option == "Home": |
|
|
|
|
|
|
|
|
economy_data = data['Country_Economy'].value_counts(normalize=True) * 100 |
|
|
economy_df = economy_data.reset_index() |
|
|
economy_df.columns = ['Country_Economy', 'percentage'] |
|
|
|
|
|
|
|
|
economy_df['percentage'] = economy_df['percentage'].round(2) |
|
|
|
|
|
|
|
|
fig = px.choropleth( |
|
|
economy_df, |
|
|
locations='Country_Economy', |
|
|
locationmode='country names', |
|
|
color='percentage', |
|
|
hover_name='Country_Economy', |
|
|
hover_data={'percentage': ':.2f'}, |
|
|
color_continuous_scale='Greens', |
|
|
) |
|
|
|
|
|
|
|
|
fig.update_traces( |
|
|
hovertemplate="<b>%{hovertext}</b><br>" + |
|
|
"percentage=%{z:.2f}%<extra></extra>", |
|
|
hovertext=economy_df['Country_Economy'] |
|
|
) |
|
|
|
|
|
|
|
|
fig.update_layout( |
|
|
title=dict( |
|
|
text="FINDEX 2021 Data Visualizer", |
|
|
font=dict(size=49, color='black', family="Raleway, sans-serif"), |
|
|
x=0.5, |
|
|
xanchor='center', |
|
|
y=0.95, |
|
|
yanchor='top', |
|
|
pad=dict(t=20), |
|
|
), |
|
|
geo=dict( |
|
|
showframe=True, |
|
|
framecolor="black", |
|
|
showcoastlines=True, |
|
|
coastlinecolor="Black", |
|
|
projection_type='orthographic', |
|
|
projection_scale=0.85, |
|
|
center=dict(lat=10, lon=0), |
|
|
lataxis_range=[-85, 85], |
|
|
lonaxis_range=[-180, 180], |
|
|
oceancolor='lightblue', |
|
|
showocean=True, |
|
|
), |
|
|
coloraxis_colorbar=dict( |
|
|
title="Participation (%)", |
|
|
len=0.5, |
|
|
thickness=15, |
|
|
tickvals=[0.5, 1, 1.5, 2], |
|
|
ticks="outside", |
|
|
), |
|
|
width=1000, |
|
|
height=800, |
|
|
margin={"r":50,"t":50,"l":0,"b":0} |
|
|
) |
|
|
|
|
|
|
|
|
st.plotly_chart(fig, use_container_width=True, config={'displayModeBar': False}) |
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
This application leverages the Global Findex 2021 dataset with over 140,000 participants to explore financial inclusion and behavior across various economies worldwide. |
|
|
|
|
|
Key features of this application include: |
|
|
- **Quick Visualization**: Instantly visualize the percentage of respondents from each country who participate in various financial services. |
|
|
- **Regional Analysis**: Explore financial trends and behaviors by country and region, identifying disparities in access to financial systems. |
|
|
- **Income-Based Analysis**: Analyze financial behaviors like savings, borrowing, and digital payments across different income levels. |
|
|
- **Gender-Based Analysis**: Compare financial inclusion patterns between genders, looking into variables such as account ownership, borrowing, and savings behavior. |
|
|
""") |
|
|
|
|
|
elif option == "Description of Variables": |
|
|
st.markdown("<h2 style='text-align: center;'>Descripton of Variables</h2>", unsafe_allow_html=True) |
|
|
st.markdown(""" |
|
|
- **Country_Economy**: The name of the country or economy. |
|
|
- **Country_Code**: ISO 3-digit code representing each economy. |
|
|
- **WorldBank_Region**: World Bank region classification (e.g., Sub-Saharan Africa, East Asia, etc.). |
|
|
- **Adult_Population**: The population of adults (aged 15+) in the economy. |
|
|
- **Respondent_ID**: A unique identifier for each respondent in the dataset. |
|
|
- **Survey_Weight**: Survey weight for each respondent, used to make the sample representative of the population. |
|
|
- **Gender**: Gender of the respondent (1 if female, 2 if male). |
|
|
- **Respondent_Age**: Age of the respondent. |
|
|
- **Education_Level**: Respondent’s education level from level 1 to 3. |
|
|
- **Income_Quintile**: Income quintile of the respondent’s household. |
|
|
- **Employment_Status**: Employment status of the respondent. |
|
|
- **Account_At_Financial_Or_Mobile_Money_Provider**: Whether the respondent has an account at a financial institution or with a mobile money service provider. |
|
|
- **Account_At_Formal_Financial_Institution**: Whether the respondent has an account at a formal financial institution. |
|
|
- **Has_Debit_Card**: Has a debit card. |
|
|
- **Used_Mobile_Money**: Whether the respondent used mobile money. |
|
|
- **Paid_Bills_Online**: Made bill payments online using the Internet. |
|
|
- **Sent_Money_To_Relative_Friend_Online**: Sent money to a relative or friend online using the Internet. |
|
|
- **Bought_Something_Online**: Bought something online using the Internet. |
|
|
- **Saved_For_Old_Age**: Saved for old age. |
|
|
- **Saved_At_Formal_Financial_Institution**: Saved using an account at a financial institution. |
|
|
- **Borrowed_For_Medical_Purposes**: Borrowed for medical purposes. |
|
|
- **Borrowed_From_Formal_Financial_Institution**: Borrowed from a financial institution. |
|
|
- **Borrowed_From_Family_Or_Friends**: Borrowed from family or friends. |
|
|
- **Main_Source_Of_Emergency_Funds_30_Days**: Main source of emergency funds in 30 days. |
|
|
- **Paid_Utility_Bill**: Paid a utility bill. |
|
|
- **Received_Wage_Payments**: Received wage payments. |
|
|
- **Received_Government_Transfer**: Received a government transfer. |
|
|
- **Received_Government_Pension**: Received a government pension. |
|
|
- **Financial_Worry_Old_Age**: Financially worried: old age. |
|
|
- **Financial_Worry_Medical_Cost**: Financially worried: medical cost. |
|
|
- **Financial_Worry_Bills**: Financially worried: bills. |
|
|
- **Financial_Worry_Education**: Financially worried: education. |
|
|
- **Saved_Money_Past_12_Months**: Saved money in the past 12 months. |
|
|
- **Borrowed_Money_Past_12_Months**: Borrowed money in the past 12 months. |
|
|
- **Received_Wage_Payment_And_Method**: Received a wage payment and method. |
|
|
- **Received_Gov_Transfer_Or_Aid_And_Method**: Received government transfers or aid payments and method. |
|
|
- **Received_Gov_Pension_Payments_And_Method**: Received government pension payments and method. |
|
|
- **Paid_Utility_Bills_And_Method**: Paid utility bills and method. |
|
|
- **Owns_Mobile_Phone**: Whether the respondent owns a mobile phone. |
|
|
- **Has_Internet_Access**: Whether the respondent has access to the internet. |
|
|
- **Made_Digital_Payment**: Whether the respondent made any digital payment. |
|
|
- **Data_Collection_Year**: The year of the data collection. |
|
|
""") |
|
|
|
|
|
|
|
|
if option == "Regional-Based Analysis": |
|
|
st.markdown("<h2 style='text-align: center;'>Regional-Based Analysis</h2>", unsafe_allow_html=True) |
|
|
st.write("This section allows you to explore financial trends and behaviors, including savings, borrowing, and digital payments, across various regions. You can compare how access to financial systems differs between regions and examine disparities in financial inclusion globally.") |
|
|
|
|
|
|
|
|
variable_labels = { |
|
|
'Account_At_Financial_Or_Mobile_Money_Provider': 'Account at Financial or Mobile Money Provider', |
|
|
'Saved_Money_Past_12_Months': 'Saved Money Past 12 Months', |
|
|
'Borrowed_Money_Past_12_Months': 'Borrowed Money Past 12 Months', |
|
|
'Paid_Bills_Online': 'Paid Bills Online', |
|
|
'Financial_Worry_Old_Age': 'Financial Worry Old Age', |
|
|
'Owns_Mobile_Phone': 'Owns Mobile Phone', |
|
|
'Has_Internet_Access': 'Has Internet Access', |
|
|
'Made_Digital_Payment': 'Made Digital Payment' |
|
|
} |
|
|
|
|
|
|
|
|
regions = data['WorldBank_Region'].unique() |
|
|
|
|
|
|
|
|
selected_regions = st.multiselect("Select regions to compare", options=regions, default=regions[0]) |
|
|
|
|
|
|
|
|
regional_data = data[data['WorldBank_Region'].isin(selected_regions)] |
|
|
|
|
|
|
|
|
variable_to_compare = st.selectbox( |
|
|
"Select variable to analyze:", |
|
|
options=list(variable_labels.keys()), |
|
|
format_func=lambda x: variable_labels[x] |
|
|
) |
|
|
|
|
|
|
|
|
summary = regional_data.groupby(['WorldBank_Region', 'educ_label'])[variable_to_compare].mean().reset_index() |
|
|
summary.columns = ['WorldBank_Region', 'Education_Level', f'Average {variable_to_compare}'] |
|
|
|
|
|
|
|
|
summary[f'Average {variable_to_compare}'] = summary[f'Average {variable_to_compare}'].mul(100).round(2) |
|
|
|
|
|
|
|
|
fig = px.bar(summary, x='WorldBank_Region', y=f'Average {variable_to_compare}', |
|
|
color='Education_Level', |
|
|
title=f"Comparison of {variable_labels[variable_to_compare]} Across Selected Regions and Education Levels", |
|
|
labels={'WorldBank_Region': 'Region', f'Average {variable_to_compare}': f'Average {variable_labels[variable_to_compare]} (%)'}, |
|
|
barmode='group') |
|
|
|
|
|
|
|
|
fig.update_layout( |
|
|
xaxis_title="Region", |
|
|
yaxis_title=f"Average {variable_labels[variable_to_compare]} (%)", |
|
|
showlegend=True, |
|
|
width=800, |
|
|
height=500, |
|
|
margin={"r":0,"t":50,"l":0,"b":50}, |
|
|
) |
|
|
|
|
|
|
|
|
st.plotly_chart(fig) |
|
|
|
|
|
|
|
|
st.markdown(f"### Summary of Regional and Educational Insights") |
|
|
st.write(f"The analysis above shows how {variable_labels[variable_to_compare]} differs across regions and education levels.") |
|
|
st.write("Key takeaways:") |
|
|
for region in selected_regions: |
|
|
region_data = summary[summary['WorldBank_Region'] == region] |
|
|
for educ_level in region_data['Education_Level'].unique(): |
|
|
avg_value = region_data[region_data['Education_Level'] == educ_level][f'Average {variable_to_compare}'].values[0] |
|
|
st.write(f"- In {region}, individuals with {educ_level} have an average {variable_labels[variable_to_compare].lower()} of {avg_value:.0f}%.") |
|
|
|
|
|
|
|
|
elif option == "Income-Based Analysis": |
|
|
st.markdown("<h2 style='text-align: center;'>Income-Based Analysis</h2>", unsafe_allow_html=True) |
|
|
st.write("This section allows you to analyze financial behaviors such as savings, borrowing, and digital payments across different income levels.") |
|
|
|
|
|
|
|
|
variable_labels_income = { |
|
|
'Account_At_Financial_Or_Mobile_Money_Provider': 'Account at Financial or Mobile Money Provider', |
|
|
'Saved_Money_Past_12_Months': 'Saved Money Past 12 Months', |
|
|
'Borrowed_Money_Past_12_Months': 'Borrowed Money Past 12 Months', |
|
|
'Made_Digital_Payment': 'Made Digital Payment' |
|
|
} |
|
|
|
|
|
|
|
|
income_quintile = st.selectbox("Select Income Quintile:", data['Income_Quintile'].unique()) |
|
|
|
|
|
|
|
|
filtered_data_income = data[data['Income_Quintile'] == income_quintile] |
|
|
|
|
|
|
|
|
selected_indicators_income = st.multiselect( |
|
|
"Select Financial Indicators to Analyze:", |
|
|
options=list(variable_labels_income.keys()), |
|
|
format_func=lambda x: variable_labels_income[x], |
|
|
default='Account_At_Financial_Or_Mobile_Money_Provider' |
|
|
) |
|
|
|
|
|
st.markdown(f"### Analysis for Income Quintile {income_quintile}") |
|
|
|
|
|
|
|
|
income_summary_dict = {} |
|
|
|
|
|
|
|
|
for indicator in selected_indicators_income: |
|
|
|
|
|
income_indicator_chart = filtered_data_income[indicator].value_counts(normalize=True).mul(100).reset_index() |
|
|
income_indicator_chart.columns = [indicator, 'Percentage'] |
|
|
|
|
|
|
|
|
has_indicator_income = income_indicator_chart[income_indicator_chart[indicator] == 1]['Percentage'].values[0] if 1 in income_indicator_chart[indicator].values else 0 |
|
|
income_summary_dict[indicator] = has_indicator_income |
|
|
|
|
|
|
|
|
fig_income = px.bar( |
|
|
income_indicator_chart, |
|
|
x=indicator, |
|
|
y='Percentage', |
|
|
title=f"{variable_labels_income[indicator]} for Income Quintile {income_quintile}", |
|
|
labels={indicator: variable_labels_income[indicator]}, |
|
|
color=indicator, |
|
|
color_continuous_scale='Blues' |
|
|
) |
|
|
|
|
|
st.plotly_chart(fig_income) |
|
|
|
|
|
|
|
|
st.markdown("### Summary") |
|
|
for indicator, percentage in income_summary_dict.items(): |
|
|
st.write(f"**{percentage:.1f}% of respondents in Income Quintile {income_quintile} have {variable_labels_income[indicator]}**.") |
|
|
|
|
|
|
|
|
elif option == "Gender-Based Analysis": |
|
|
st.markdown("<h2 style='text-align: center;'>Gender-Based Analysis</h2>", unsafe_allow_html=True) |
|
|
st.write("Here you can analyze financial behaviors such as savings, borrowing, and digital payments for selected gender and age groups.") |
|
|
|
|
|
|
|
|
variable_labels_gender = { |
|
|
'Account_At_Financial_Or_Mobile_Money_Provider': 'Account at Financial or Mobile Money Provider', |
|
|
'Saved_Money_Past_12_Months': 'Saved Money Past 12 Months', |
|
|
'Borrowed_Money_Past_12_Months': 'Borrowed Money Past 12 Months', |
|
|
'Made_Digital_Payment': 'Made Digital Payment' |
|
|
} |
|
|
|
|
|
|
|
|
gender = st.radio("Select Gender:", ("Female", "Male")) |
|
|
|
|
|
|
|
|
age_group = st.selectbox("Select Age Group:", data['age_group'].unique()) |
|
|
|
|
|
|
|
|
gender_code = 1 if gender == "Female" else 2 |
|
|
|
|
|
|
|
|
filtered_data = data[(data['Gender'] == gender_code) & (data['age_group'] == age_group)] |
|
|
|
|
|
|
|
|
selected_indicators = st.multiselect( |
|
|
"Select Financial Indicators to Analyze:", |
|
|
options=list(variable_labels_gender.keys()), |
|
|
format_func=lambda x: variable_labels_gender[x], |
|
|
default=['Account_At_Financial_Or_Mobile_Money_Provider'] |
|
|
) |
|
|
|
|
|
st.markdown(f"### Analysis for {gender}s in {age_group} Age Group") |
|
|
|
|
|
|
|
|
summary_dict = {} |
|
|
|
|
|
|
|
|
for indicator in selected_indicators: |
|
|
|
|
|
indicator_chart = filtered_data[indicator].value_counts(normalize=True).mul(100).reset_index() |
|
|
indicator_chart.columns = [indicator, 'Percentage'] |
|
|
|
|
|
|
|
|
has_indicator = indicator_chart[indicator_chart[indicator] == 1]['Percentage'].values[0] if 1 in indicator_chart[indicator].values else 0 |
|
|
summary_dict[indicator] = has_indicator |
|
|
|
|
|
|
|
|
fig = px.bar( |
|
|
indicator_chart, |
|
|
x=indicator, |
|
|
y='Percentage', |
|
|
title=f"{variable_labels_gender[indicator]} for {gender}s in {age_group} Age Group", |
|
|
labels={indicator: variable_labels_gender[indicator]}, |
|
|
color=indicator, |
|
|
color_continuous_scale='Viridis' |
|
|
) |
|
|
|
|
|
st.plotly_chart(fig) |
|
|
|
|
|
|
|
|
st.markdown("### Summary") |
|
|
for indicator, percentage in summary_dict.items(): |
|
|
st.write(f"**{percentage:.1f}% of {gender}s in the {age_group} age group have {variable_labels_gender[indicator]}**.") |
|
|
|
|
|
elif option == "Financial Recommender Engine": |
|
|
st.markdown("<h2 style='text-align: center;'>Financial Recommender Engine</h2>", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
def enhanced_recommender(age, income_quintile, has_debit_card, uses_mobile_money, financial_goal, savings_habit, investment_interest): |
|
|
recommendations = [] |
|
|
|
|
|
|
|
|
if has_debit_card == "No": |
|
|
recommendations.append("Consider getting a debit card. Debit cards offer secure, convenient access to your money and can help you manage day-to-day transactions.") |
|
|
|
|
|
if uses_mobile_money == "No": |
|
|
recommendations.append("Mobile money services are a great way to manage transactions remotely and even save small amounts. Consider trying them for increased financial flexibility.") |
|
|
|
|
|
|
|
|
if age < 30: |
|
|
recommendations.append("Starting early is key to long-term financial success! Focus on building a savings habit and avoid unnecessary debt.") |
|
|
elif 30 <= age <= 50: |
|
|
recommendations.append("This is the perfect time to focus on increasing savings and planning for long-term goals like buying a home or preparing for children's education.") |
|
|
elif age > 50: |
|
|
recommendations.append("As you near retirement, focus on low-risk investments and savings. Consider discussing retirement plans with a financial advisor.") |
|
|
|
|
|
|
|
|
if income_quintile < 3: |
|
|
recommendations.append("You might be eligible for government support programs or financial assistance tailored to lower-income groups. Explore these options to improve your financial stability.") |
|
|
else: |
|
|
recommendations.append("With a higher income level, consider diversifying your investments, including retirement savings and possibly high-return investments like stocks or real estate.") |
|
|
|
|
|
|
|
|
if financial_goal == "Retirement": |
|
|
recommendations.append("It's important to have a solid retirement plan. Focus on long-term, stable investments like pension funds or bonds.") |
|
|
elif financial_goal == "Home Ownership": |
|
|
recommendations.append("Buying a home is a big goal. Consider saving aggressively or exploring mortgage options to make your goal achievable.") |
|
|
elif financial_goal == "Education": |
|
|
recommendations.append("Education savings can benefit from high-interest savings accounts or tax-advantaged education accounts.") |
|
|
|
|
|
|
|
|
if savings_habit == "No": |
|
|
recommendations.append("Starting a savings habit, even if it's a small amount each month, can build your financial security over time.") |
|
|
else: |
|
|
recommendations.append("Good job on saving! Consider increasing the amount or exploring higher-yield savings accounts or investments.") |
|
|
|
|
|
|
|
|
if investment_interest == "Yes": |
|
|
recommendations.append("Since you're interested in investing, explore stocks, mutual funds, or real estate. A financial advisor can help you find the right options.") |
|
|
else: |
|
|
recommendations.append("If you're unsure about investing, start small with safer options like government bonds or index funds.") |
|
|
|
|
|
return recommendations |
|
|
|
|
|
|
|
|
age = st.slider("Your Age", 18, 70, 30) |
|
|
income_quintile = st.slider("Income Quintile (1 = Lowest, 5 = Highest)", 1, 5, 3) |
|
|
has_debit_card = st.radio("Do you have a debit card?", ("Yes", "No")) |
|
|
uses_mobile_money = st.radio("Have you used mobile money?", ("Yes", "No")) |
|
|
financial_goal = st.radio("What is your main financial goal?", ("Retirement", "Home Ownership", "Education")) |
|
|
savings_habit = st.radio("Do you have a savings habit?", ("Yes", "No")) |
|
|
investment_interest = st.radio("Are you interested in investing?", ("Yes", "No")) |
|
|
|
|
|
|
|
|
recommendations = [] |
|
|
|
|
|
if st.button("Get Recommendations"): |
|
|
|
|
|
recommendations = enhanced_recommender(age, income_quintile, has_debit_card, uses_mobile_money, financial_goal, savings_habit, investment_interest) |
|
|
|
|
|
|
|
|
if recommendations: |
|
|
st.markdown("### Recommendations:") |
|
|
for rec in recommendations: |
|
|
st.write(f"- {rec}") |
|
|
else: |
|
|
st.write("Click the 'Get Recommendations' button to receive personalized financial recommendations.") |
|
|
|
|
|
elif option == "SML Classification": |
|
|
st.title("SML Classification - Financial Prediction") |
|
|
|
|
|
|
|
|
st.markdown("### Provide the details to predict the financial product:") |
|
|
age = st.slider("Your Age", 18, 70, 30) |
|
|
income_bracket = st.selectbox("Income Bracket (1 = Lowest, 5 = Highest)", [1, 2, 3, 4, 5]) |
|
|
has_internet_access = st.radio("Do you have Internet Access?", ["Yes", "No"]) |
|
|
employed = st.radio("Are you employed?", ["Yes", "No"]) |
|
|
high_income_region = st.radio("Are you in a High Income Region?", ["Yes", "No"]) |
|
|
|
|
|
|
|
|
input_data = pd.DataFrame({ |
|
|
'Age': [age], |
|
|
'Income Bracket': [income_bracket], |
|
|
'Has Internet Access': [1 if has_internet_access == "Yes" else 0], |
|
|
'Employed': [1 if employed == "Yes" else 0], |
|
|
'High Income Region': [1 if high_income_region == "Yes" else 0] |
|
|
}) |
|
|
|
|
|
|
|
|
input_data_encoded = ohe.transform(input_data) |
|
|
|
|
|
|
|
|
if st.button("Predict"): |
|
|
prediction = xgb_model.predict(input_data_encoded) |
|
|
st.write(f"Prediction: {prediction[0]}") |