job / app.py
keanteng's picture
add password box
37d174d
"""
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"<a href='{suggestion_row['link_1'][0]}'>{text1}</a>"
text2 = str(suggestion_row["course suggestion 2"][0])
suggestion_link2 = f"<a href='{suggestion_row['link_2'][0]}'>{text2}</a>"
text3 = str(suggestion_row["course suggestion 3"][0])
suggestion_link3 = f"<a href='{suggestion_row['link_3'][0]}'>{text3}</a>"
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"
)