""" MIT License Copyright (c) 2023 Khor Kean Teng, Ang Zhi Nuo, Connie Hui Kang Yi, Ling Sing Cheng, Tan Yu Jing Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ # load packages import pandas as pd import numpy as np import streamlit as st import geopandas as gpd from backend.functions import * try: from backend.configs import * except ImportError: pass import matplotlib.pyplot as plt from datetime import * import google.generativeai as palm # website settings # turn off the side bar by default st.set_page_config(layout="wide", initial_sidebar_state="auto") ## customize the side bar st.sidebar.title("๐ŸŒ Geo-Sustainable Jobs Solution") st.sidebar.caption("A Job Solution Prototype") # user input with st.sidebar: with st.expander("PaLM-2 API Configuration", expanded=True): st.caption(":red[You must enable API and input your own API key when using Streamlit web]") web_toggle = st.toggle('Enable API') api_input = st.text_input("Your Google API Token", type = "password", placeholder="Enter your API key here") st.caption("You can get your API key from https://developers.generativeai.google/") location_input = st.text_input( "Enter a location (Malaysia Only):", "University Malaya" ) state_input = st.selectbox( "Select a state:", [ "W.P Kuala Lumpur", "Johor", "Kedah", "Kelantan", "Melaka", "Negeri Sembilan", "Pahang", "Perak", "Perlis", "Pulau Pinang", "Sabah", "Sarawak", "Selangor", "Terengganu", "W.P Labuan", "W.P Putrajaya", ], ) # add exapander with st.expander("Your Job Profile", expanded=False): user_skills = st.text_input( "Enter Your Skills, Desired Sector & Qualifications:", "English, Leadership, Problem Solving, Malay, Program Planning", ) user_qualification = st.selectbox( "Enter Your Qualification:", ( "1-Skill Certificate 1", "2-Skill Certificate 2", "3-Skill Certificate 3", "4-Diploma", "5-Advanced Diploma", "6-Bachelor Degree", "7-Master Degree", "8-Doctorate Degree", ), ) user_sector = st.text_input("Enter Your Desired Sector:", "Teacher") submit = st.button("Compute", type="primary") st.subheader("๐Ÿ“ˆ OpenDOSM Statistics") st.caption("Source: Labour Market Review, 2023 Q2") # setup the layout with columns col1, col2 = st.columns(spec=[0.7, 0.3], gap="small") # load data df = gpd.read_file("data/shapefile/polbnda_mys.shp") jobdata = pd.read_csv("data/job_posting_cleaned.csv") dosm_supply = pd.ExcelFile("data/dosm_supply.xlsx") dosm_demand = pd.ExcelFile("data/dosm_demand.xlsx") airports = gpd.read_file("data/airports/hotosm_mys_airports_polygons.shp") edu_fac = gpd.read_file( "data/edu_facilities/hotosm_mys_education_facilities_polygons.shp" ) financial = gpd.read_file( "data/financial_service/hotosm_mys_financial_services_polygons.shp" ) health = gpd.read_file( "data/health_facilities/hotosm_mys_health_facilities_polygons.shp" ) point_of_interest = gpd.read_file( "data/point_of_interest/hotosm_mys_points_of_interest_polygons.shp" ) seaports = gpd.read_file("data/sea_ports/hotosm_mys_sea_ports_polygons.shp") qualification_data = pd.read_excel("data/qualification level.xlsx") sectors_data = pd.read_excel("data/skill by sector.xlsx") course_suggestions_data = pd.read_excel("data/course suggestion.xlsx") vacancy_rate = pd.read_csv("data/Vacancy Rate.csv", index_col=[0], parse_dates=[0]) unemployment_rate = pd.read_csv("data/Unemployment Rate.csv") # configure geodataframe airports = gpd.GeoDataFrame(airports, geometry=airports.geometry, crs="EPSG:4326") edu_fac = gpd.GeoDataFrame(edu_fac, geometry=edu_fac.geometry, crs="EPSG:4326") financial = gpd.GeoDataFrame(financial, geometry=financial.geometry, crs="EPSG:4326") health = gpd.GeoDataFrame(health, geometry=health.geometry, crs="EPSG:4326") point_of_interest = gpd.GeoDataFrame( point_of_interest, geometry=point_of_interest.geometry, crs="EPSG:4326" ) seaports = gpd.GeoDataFrame(seaports, geometry=seaports.geometry, crs="EPSG:4326") # tidy up the data airports = airports[["name", "aeroway", "geometry"]] edu_fac = edu_fac[["name", "amenity", "geometry"]] financial = financial[["name", "amenity", "geometry"]] health = health[["healthcare", "name", "amenity", "geometry"]] point_of_interest = point_of_interest[ ["tourism", "name", "amenity", "shop", "geometry"] ] seaports = seaports[["name", "amenity", "geometry"]] vacancy_rate = vacancy_rate.dropna(axis=1, how="all") vacancy_rate.dropna(inplace=True) unemployment_rate = unemployment_rate.dropna(axis=1, how="all") # change the type of vacancy_rate_employment as data frame unemployment_rate = pd.DataFrame(unemployment_rate) unemployment_rate.iloc[:, 1:] = unemployment_rate.iloc[:, 1:].astype(float) unemployment_rate.iloc[:, 0] = pd.to_datetime(unemployment_rate.iloc[:, 0]) unemployment_rate = unemployment_rate.set_index("Date") # temp map display placeholder = st.empty() with placeholder.container(): m = leafmap.Map(center=[3.8, 101.4], zoom=7, google_map="HYBRID") m.to_streamlit(height=700) ############################## # forecast engine def dateofforecast(data): forecast_date = [ "2023-04-01", "2023-07-01", "2023-10-01", "2024-01-01", "2024-04-01", "2024-07-01", "2024-10-01", "2025-01-01", ] forecast_date = pd.to_datetime(forecast_date) data.index = forecast_date # ETS prediction VETS_Kedah = ets_fore_a(vacancy_rate["Kedah"], 6) VETS_Melaka = ets_fore_a(vacancy_rate["Melaka"], 6) VETS_Negeri_Sembilan = ets_fore_c(vacancy_rate["Negeri Sembilan"], 6) VETS_Pahang = ets_fore_a(vacancy_rate["Pahang"], 6) VETS_Perlis = ets_fore_c(vacancy_rate["Perlis"], 6) VETS_Terengganu = ets_fore_a(vacancy_rate["Terengganu"], 6) VETS_Sabah = ets_fore_a(vacancy_rate["Sabah"], 6) VETS_Sarawak = ets_fore_a(vacancy_rate["Sarawak"], 6) VETS_Putrajaya = ets_fore_a(vacancy_rate["W.P Putrajaya"], 6) # ARIMA prediction VETS_Johor = ARIMA_fore(vacancy_rate["Johor"]) VETS_Kelantan = ARIMA_fore(vacancy_rate["Kelantan"]) VETS_Penang = ARIMA_fore(vacancy_rate["Pulau Pinang"]) VETS_Perak = ARIMA_fore(vacancy_rate["Perak"]) VETS_Selangor = ARIMA_fore(vacancy_rate["Selangor"]) VETS_Kuala_Lumpur = ARIMA_fore(vacancy_rate["W.P Kuala Lumpur"]) VETS_Labuan = ARIMA_fore(vacancy_rate["W.P Labuan"]) VETS_Total = ARIMA_fore(vacancy_rate["Total"]) # Change the Starting date of the forecast dateofforecast(VETS_Kedah) dateofforecast(VETS_Melaka) dateofforecast(VETS_Negeri_Sembilan) dateofforecast(VETS_Pahang) dateofforecast(VETS_Perlis) dateofforecast(VETS_Terengganu) dateofforecast(VETS_Sabah) dateofforecast(VETS_Sarawak) dateofforecast(VETS_Putrajaya) dateofforecast(VETS_Johor) dateofforecast(VETS_Kelantan) dateofforecast(VETS_Penang) dateofforecast(VETS_Perak) dateofforecast(VETS_Selangor) dateofforecast(VETS_Kuala_Lumpur) dateofforecast(VETS_Labuan) dateofforecast(VETS_Total) # ETS Model Johor_vpred = ets_fore_a(unemployment_rate[["Johor"]], 6) Kedah_pred = ets_fore_d(unemployment_rate[["Kedah"]], 6) Kelantan_pred = ets_fore_d(unemployment_rate[["Kelantan"]], 6) Melaka_pred = ets_fore_b(unemployment_rate[["Melaka"]], 6) Pahang_pred = ets_fore_c(unemployment_rate[["Pahang"]], 6) Perak_pred = ets_fore_c(unemployment_rate[["Perak"]], 6) Perlis_pred = ets_fore_c(unemployment_rate[["Perlis"]], 6) Sabah_pred = ets_fore_a(unemployment_rate[["Sabah"]], 6) Sarawak_pred = ets_fore_d(unemployment_rate[["Sarawak"]], 6) Selangor_pred = ets_fore_d(unemployment_rate[["Selangor"]], 6) Terengganu_pred = ets_fore_b(unemployment_rate[["Terengganu"]], 6) Labuan_pred = ets_fore_d(unemployment_rate["W.P Labuan"], 6) # ARIMA Model UARIMA_N9_pred = ARIMA_fore(unemployment_rate[["Negeri Sembilan"]]) UARIMA_Penang_pred = ARIMA_fore(unemployment_rate[["Pulau Pinang"]]) UARIMA_KL_pred = ARIMA_fore(unemployment_rate[["W.P Kuala Lumpur"]]) UARIMA_Putrajaya_pred = ARIMA_fore(unemployment_rate[["W.P Putrajaya"]]) UARIMA_Malaysia_pred = ARIMA_fore(unemployment_rate[["Total"]]) # Change the Starting date of the forecast dateofforecast(Johor_vpred) dateofforecast(Kedah_pred) dateofforecast(Kelantan_pred) dateofforecast(Melaka_pred) dateofforecast(Pahang_pred) dateofforecast(Perak_pred) dateofforecast(Perlis_pred) dateofforecast(Sabah_pred) dateofforecast(Sarawak_pred) dateofforecast(Selangor_pred) dateofforecast(Terengganu_pred) dateofforecast(Labuan_pred) dateofforecast(UARIMA_N9_pred) dateofforecast(UARIMA_Penang_pred) dateofforecast(UARIMA_KL_pred) dateofforecast(UARIMA_Putrajaya_pred) dateofforecast(UARIMA_Malaysia_pred) vacancy_rate.dateformat = vacancy_rate.index.strftime("%Y-%m-%d") unemployment_rate.dateformat = unemployment_rate.index.strftime("%Y-%d-%m") plt.rcParams["figure.figsize"] = (20, 12) def forecast_plot(state): state = state.title() if state == "Kedah": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Kedah"], label="Vacancy Rate") ax1.plot(VETS_Kedah, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot( unemployment_rate.index, unemployment_rate["Kedah"], "r", label="Unemployment Rate", ) ax2.plot(Kedah_pred, "b", label="Forecast of Unemployment Rate") ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Johor": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Johor"], label="Vacancy Rate") ax1.plot(VETS_Johor, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot( unemployment_rate.index, unemployment_rate["Johor"], "r", label="Unemployment Rate", ) ax2.plot(Johor_vpred, "b", label="Forecast of Unemployment Rate") ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Kelantan": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Kelantan"], label="Vacancy Rate") ax1.plot(VETS_Kelantan, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot( unemployment_rate.index, unemployment_rate["Kelantan"], "r", label="Unemployment Rate", ) ax2.plot(Kelantan_pred, "b", label="Forecast of Unemployment Rate") ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Melaka": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Melaka"], label="Vacancy Rate") ax1.plot(VETS_Melaka, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot( unemployment_rate.index, unemployment_rate["Melaka"], "r", label="Unemployment Rate", ) ax2.plot(Melaka_pred, "b", label="Forecast of Unemployment Rate") ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Negeri Sembilan": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot( vacancy_rate.index, vacancy_rate["Negeri Sembilan"], label="Vacancy Rate" ) ax1.plot(VETS_Negeri_Sembilan, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot( unemployment_rate.index, unemployment_rate["Negeri Sembilan"], "r", label="Unemployment Rate", ) ax2.plot(UARIMA_N9_pred, "b", label="Forecast of Unemployment Rate") ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Pahang": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Pahang"], label="Vacancy Rate") ax1.plot(VETS_Pahang, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot( unemployment_rate.index, unemployment_rate["Pahang"], "r", label="Unemployment Rate", ) ax2.plot(Pahang_pred, "b", label="Forecast of Unemployment Rate") ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Penang": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Pulau Pinang"], label="Vacancy Rate") ax1.plot(VETS_Penang, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot( unemployment_rate.index, unemployment_rate["Pulau Pinang"], "r", label="Unemployment Rate", ) ax2.plot(UARIMA_Penang_pred, "b", label="Forecast of Unemployment Rate") ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Perak": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Perak"], label="Vacancy Rate") ax1.plot(VETS_Perak, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot( unemployment_rate.index, unemployment_rate["Perak"], "r", label="Unemployment Rate", ) ax2.plot(Perak_pred, "b", label="Forecast of Unemployment Rate") ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Perlis": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Perlis"], label="Vacancy Rate") ax1.plot(VETS_Perlis, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(Perlis_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["Perlis"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Sabah": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Sabah"], label="Vacancy Rate") ax1.plot(VETS_Sabah, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(Sabah_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["Sabah"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Sarawak": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Sarawak"], label="Vacancy Rate") ax1.plot(VETS_Sarawak, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(Sarawak_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["Sarawak"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Selangor": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Selangor"], label="Vacancy Rate") ax1.plot(VETS_Selangor, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(Selangor_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["Selangor"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Terengganu": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["Terengganu"], label="Vacancy Rate") ax1.plot(VETS_Terengganu, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(Terengganu_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["Terengganu"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "W.P Kuala Lumpur": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot( vacancy_rate.index, vacancy_rate["W.P Kuala Lumpur"], label="Vacancy Rate" ) ax1.plot(VETS_Kuala_Lumpur, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(UARIMA_KL_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["W.P Kuala Lumpur"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "W.P Labuan": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot(vacancy_rate.index, vacancy_rate["W.P Labuan"], label="Vacancy Rate") ax1.plot(VETS_Labuan, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(Labuan_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["W.P Labuan"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "W.P Putrajaya": fig, ax1 = plt.subplots() plt.figure(figsize=(12, 8)) ax1.plot( vacancy_rate.index, vacancy_rate["W.P Putrajaya"], label="Vacancy Rate" ) ax1.plot(VETS_Putrajaya, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(UARIMA_Putrajaya_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["W.P Putrajaya"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) elif state == "Malaysia": fig, ax1 = plt.subplots() plt.figure(figsize=(20, 12)) ax1.plot(vacancy_rate.index, vacancy_rate["Total"], label="Vacancy Rate") ax1.plot(VETS_Total, label="Forecast of Vacancy Rate") ax1.legend(loc="upper left") ax1.set_xlabel("Date") ax1.set_ylabel("Vacancy Rate") ax2 = ax1.twinx() ax2.plot(UARIMA_Malaysia_pred, "b", label="Forecast of Unemployment Rate") ax2.plot( unemployment_rate.index, unemployment_rate["Total"], "r", label="Unemployment Rate", ) ax2.legend(loc="upper left", bbox_to_anchor=(0, 0.95)) ax2.set_ylabel("Unemployment Rate") plt.rcParams["figure.figsize"] = (20, 12) st.pyplot(fig) ############################# # visualization part for the selected state if state_input: with st.sidebar: with st.expander("Vacancy & Unemployment Rate (%) Projection", expanded=False): forecast_plot(state_input) with st.expander("State Labour Supply ('000)", expanded=False): supply_state = dosm_supply.parse("state") supply_state = supply_state[supply_state["state"] == state_input] st.dataframe(supply_state, hide_index=True) with st.expander("By Ethnic Group ('000)", expanded=False): ethnic_state = dosm_supply.parse("ethnic") st.dataframe(ethnic_state, hide_index=True) with st.expander("By Age Group ('000)", expanded=False): age_state = dosm_supply.parse("age") st.dataframe(age_state, hide_index=True) with st.expander("By Education Level ('000)", expanded=False): edu_state = dosm_supply.parse("edu") st.dataframe(edu_state, hide_index=True) with st.expander("Vacancy Ads Count", expanded=False): vacancy_ads_state = dosm_demand.parse("vacancy_ads_state") vacancy_ads_state = vacancy_ads_state[ vacancy_ads_state["state"] == state_input ] st.dataframe(vacancy_ads_state, hide_index=True) with st.expander("Sector Performance", expanded=False): sector_wage_prob = dosm_demand.parse("sector_wage_prob") st.dataframe(sector_wage_prob, hide_index=True) # submit button is clicked if submit: # clear the map placeholder.empty() with st.spinner("Hang on for a second..."): with col1: ## map generation input_df = geocoder(location_input) if input_df["Latitude"][0] == None: st.error("Location not found. Please try again.") st.stop() intersected_df = intersection_check(input_df, df) m = leafmap.Map( center=[input_df["Latitude"][0], input_df["Longitude"][0]], zoom=15, google_map="HYBRID", ) style = { "stroke": True, "color": "#0000ff", "weight": 2, "opacity": 1, "fill": True, "fillColor": "#0000ff", "fillOpacity": 0.1, } style_extras = { "stroke": True, "color": "#d82c02", "weight": 2, "opacity": 1, "fill": True, "fillColor": "#d82c02", "fillOpacity": 0.1, } m.add_points_from_xy( input_df, x="Longitude", y="Latitude", icon_names=["gear", "map", "leaf", "globe"], ) m.add_gdf(intersected_df, layer_name="Region of Interest", style=style) m.add_gdf(df, layer_name="Region of Interest", style=style) m.add_gdf(airports, layer_name="Airports", style=style_extras) m.add_gdf(edu_fac, layer_name="Education Facilities", style=style_extras) m.add_gdf(financial, layer_name="Financial Services", style=style_extras) m.add_gdf(health, layer_name="Health Facilities", style=style_extras) m.add_gdf( point_of_interest, layer_name="Point of Interest", style=style_extras ) m.add_gdf(seaports, layer_name="Sea Ports", style=style_extras) m.to_streamlit(height=700) st.sidebar.expander("โ„น๏ธ About", expanded=True) with col2: # configure the API if web_toggle: configure_api(api_key=api_input) else: configure_api(api_key=PALM_TOKEN) # get the skill list skill_list = skill_suggest_model(location_input) # get the job list job_list = job_suggest_model(skill_list) # cleaning skill_list = list_cleaning(skill_list) job_list = list_cleaning(job_list) st.subheader("๐Ÿงช Skill List:") st.write( "Based on the location of interest, we suggest the following skills:" + " " + skill_list ) st.divider() st.subheader("๐Ÿ’ผ Job List:") st.write( "Based on the skills, we suggest the following jobs:" + " " + job_list ) # job recommendation engine job_list = job_list.split(", ") result_df = [] for i in range(0, len(job_list)): job_match = job_matcher( jobdata, column="title", string_to_match=str(job_list[i]) ) if job_match.empty: continue else: job_key = job_match["title"][0] # result = job_recom_engine(jobdata, job_key=job_key) sig = job_recom_engine(jobdata) result = give_rec( titlename=job_key, sig=sig, jobdata=jobdata ).sort_values(by="View", ascending=False) result_df.append(result) # if the result is empty we will return empty dataframe if len(result_df) == 0: pass else: result_df = pd.concat([df for df in result_df], ignore_index=True) with st.expander("Job Recommendation", expanded=False): st.table(result_df) # resume recommendation engine qualification_dict = dict( zip( qualification_data["qualification"], qualification_data["mqf level"] ) ) matching_sectors = [] for _, row in sectors_data.iterrows(): sector = row["sector"] sector_skills = row["skills"] min_qualification = row["qualification"] # compute the similarity score between user skills and all sector skills similarity_score = compare_skills(user_skills, sector_skills) # check if the similarity score is above 0 and if the user's qualification is above the minimum qualification level if similarity_score > 0 and int(user_qualification[0:1]) >= int( min_qualification ): if not user_sector or user_sector.lower() in sector.lower(): matching_sectors.append(sector) # output the results with st.expander("Job Profile Analysis", expanded=False): if matching_sectors: # the matches sector could be more than one, so we need to loop through all of them for sector in matching_sectors: sector_row = sectors_data.loc[ sectors_data["sector"] == sector ].iloc[0] required_skills = set(sector_row["skills"].split(",")) user_input_skills = set(user_skills.lower().split(",")) matching_skills = user_input_skills.intersection( required_skills ) lacking_skills = required_skills.difference(user_input_skills) st.write(f"**Sector:** {sector.title()}") st.write( "**Matching Skills:**", ", ".join(matching_skills).title() ) st.write( "**Lacking Skills:**", ", ".join(lacking_skills)[2:].title() ) st.write( f"**Minimum Qualification:** MQF Level {sector_row['qualification']}" ) course_suggestions = course_suggestions_data.loc[ course_suggestions_data["sector"] == sector ] if not course_suggestions.empty: st.write("**Course Suggestions:**") for _, suggestion_row in course_suggestions.iterrows(): suggestion_row = ( pd.DataFrame(suggestion_row) .transpose() .reset_index(drop=True) ) text1 = str(suggestion_row["course suggestion 1"][0]) suggestion_link1 = f"{text1}" text2 = str(suggestion_row["course suggestion 2"][0]) suggestion_link2 = f"{text2}" text3 = str(suggestion_row["course suggestion 3"][0]) suggestion_link3 = f"{text3}" st.markdown( "- " + suggestion_link1, unsafe_allow_html=True ) st.markdown( "- " + suggestion_link2, unsafe_allow_html=True ) st.markdown( "- " + suggestion_link3, unsafe_allow_html=True ) if len(lacking_skills) > 0: st.write("**Role & Responsibilities:**") job_description = sector_row["job description"].split(";") for desc in job_description: st.write(desc.strip()) st.divider() # if no match found, output this message else: st.write( "Sorry, no matching sectors found in our database for your skills and qualification level." ) # regional analysis airport_count = [] edu_fac_count = [] financial_count = [] health_count = [] seaports_count = [] intersected_df = intersected_df.reset_index() for index in range(len(airports)): if ( intersected_df["geometry"][0].contains(airports["geometry"][index]) == True ): airport_count.append(airports["name"][index]) for index in range(len(edu_fac)): if ( intersected_df["geometry"][0].contains(edu_fac["geometry"][index]) == True ): edu_fac_count.append(edu_fac["name"][index]) for index in range(len(financial)): if ( intersected_df["geometry"][0].contains(financial["geometry"][index]) == True ): financial_count.append(financial["name"][index]) for index in range(len(health)): if ( intersected_df["geometry"][0].contains(health["geometry"][index]) == True ): health_count.append(health["name"][index]) for index in range(len(seaports)): if ( intersected_df["geometry"][0].contains(seaports["geometry"][index]) == True ): seaports_count.append(seaports["name"][index]) poi_name = [] poi_tourism = [] poi_amenity = [] poi_shop = [] for index in range(len(point_of_interest)): if ( intersected_df["geometry"][0].contains( point_of_interest["geometry"][index] ) == True ): poi_name.append(point_of_interest["name"][index]) poi_tourism.append(point_of_interest["tourism"][index]) poi_amenity.append(point_of_interest["amenity"][index]) poi_shop.append(point_of_interest["shop"][index]) # make a poi = pd.DataFrame( { "name": poi_name, "Tourism": poi_tourism, "Amenity": poi_amenity, "Shop": poi_shop, } ) # find the location of interest no_hotel = len( poi[(poi["Tourism"] == "hotel") | (poi["Tourism"] == "hostel")] ) no_theme_park = len(poi[(poi["Tourism"] == "theme_park")]) no_food_place = len( poi[ (poi["Amenity"] == "restaurant") | (poi["Amenity"] == "cafe") | (poi["Amenity"] == "fast_food") ] ) no_fuel = len(poi[(poi["Amenity"] == "fuel")]) no_marketplace = len(poi[poi["Shop"] == "marketplace"]) no_supermarket = len( poi[(poi["Shop"] == "supermarket") | (poi["Shop"] == "convenience")] ) no_cloth_jewelry = len( poi[(poi["Shop"] == "clothes") | (poi["Shop"] == "jewelry")] ) no_mall = len( poi[(poi["Shop"] == "mall") | (poi["Shop"] == "department_store")] ) no_repair = len( poi[(poi["Shop"] == "car_repair") | poi["Shop"] == "motorcycle"] ) no_hair = len(poi[poi["Shop"] == "hairdresser"]) no_telco = len( poi[ (poi["Shop"] == "telecommunication") | (poi["Shop"] == "electronics") ] ) # make a dataframe poi_df = pd.DataFrame( { "Place": [ "Airport", "Education Facilities", "Financial Facilities", "Health Facilities", "Seaports", "Hotel", "Theme Park", "Food Place", "Fuel Station", "Marketplace", "Supermarket", "Cloth & Jewelry", "Mall", "Repair Shops", "Hair Salon", "Telco", ], "Count": [ len(airport_count), len(edu_fac_count), len(financial_count), len(health_count), len(seaports), no_hotel, no_theme_park, no_food_place, no_fuel, no_marketplace, no_supermarket, no_cloth_jewelry, no_mall, no_repair, no_hair, no_telco, ], } ) with st.sidebar: st.subheader("๐Ÿ“ Location Analysis") with st.expander("Point of Interest", expanded=False): st.table(poi_df) # sidebar footer st.sidebar.caption( "MIT License 2023 ยฉ Isekai Truck: Ang Zhi Nuo, Connie Hui Kang Yi, Khor Kean Teng, Ling Sing Cheng, Tan Yu Jing" )