steam-recsys / app.py
deppfellow's picture
end commit. To restart the spaces
23ea55b
import streamlit as st
from streamlit_option_menu import option_menu
from func import *
from easeBased_model import *
from contentBased_model import *
if "user_preferences" not in st.session_state:
st.session_state["user_preferences"] = {}
data = pd.read_pickle("data/list_of_all_titles.pkl")
ease_ids = list(pd.read_pickle("data/dict_of_ease_ids.pkl").keys())
# Games recomm() to process user's input
def games_recomm(preferences_id):
if "rs" in st.session_state:
del st.session_state["rs"]
with st.spinner("Getting recommendation..."):
pref_value = []
for id in preferences_id:
if st.session_state[id] == "Positive":
pref_value.append(1)
elif st.session_state[id] == "Negative":
pref_value.append(0)
pred_df = pd.DataFrame({
'user_id': [999999] * len(preferences_id),
'app_id': preferences_id,
'is_recommended': pref_value
})
ease_df = pred_df[pred_df['app_id'].isin(ease_ids)]
if ease_df.empty:
try:
res = cbf_model(pred_df=pred_df, k=10)['app_id'].tolist()
except:
st.error(
"Recommendation failed. Please select with at least 2 games title.")
res = None
else:
res_cbf = cbf_model(pred_df=pred_df, k=100)
res_ease = ease_model(pred_df=ease_df, k=100)
res = combine_hybrid_result(res_ease, res_cbf)
# st.write("EASE model output:", res_ease)
# st.markdown("---")
# st.write("CBF model output:", res_cbf)
# st.markdown("---")
# st.write("Hybrid model output:", res)
res = res.head(10).index.tolist()
if type(res) == [ValueError, None]:
st.error("Recommendation failed. Please select with at least 2 games title.")
return
else:
st.session_state['rs'] = res
try:
if len(st.session_state['rs']) >= 1:
st.success(
f"Go to result page to view top {len(st.session_state['rs'])} recommendations.")
else:
st.error("Recommendation failed. Please reload the session.")
except:
st.error(
"There is some error in recommendation process. Please restart the session.")
# st.write(res)
# Main Page Header. Consist of Home page, Result page, About page, and Log page
def spr_sidebar():
menu = option_menu(
menu_title=None,
options=['Home', 'Result', 'About'],
icons=['house', 'joystick', 'info-square'],
menu_icon='cast',
default_index=0,
orientation='horizontal'
)
# Change 'app_mode' state based on current page
if menu == 'Home':
st.session_state['app_mode'] = 'Home'
elif menu == 'Result':
st.session_state['app_mode'] = 'Result'
elif menu == 'About':
st.session_state['app_mode'] = 'About'
# Home page. One of the page in Main Header for user inputting their preferences
def home_page():
st.title("Steam Recommendation System")
with st.expander("Aturan input & panduan sistem"):
st.markdown("""
Mohon untuk memasukkan input yang valid, yaitu:
- Minimal 2 judul game yang dimasukkan sebagai input sistem
- Preferensi penilaian game yang dimasukkan harus memiliki setidaknya 1 rating positif
<br>
Untuk mendapatkan hasil rekomendasi, berikut langkah untuk berinteraksi dengan sistem:
1. Tekan input dropdown dibawah
2. Ketikkan judul game yang anda ketahui dan atur penilaian dari game yang bersangkutan
3. Tekan "Get recommendation" untuk mendapatkan hasil rekomendasi
4. Pindah ke tab "Result" untuk melihat judul game yang direkomendasikan
""", unsafe_allow_html=True)
st.markdown("<br>", unsafe_allow_html=True)
st.image("data/systemGuide.png")
st.markdown("<br>", unsafe_allow_html=True)
if "user_preferences" in st.session_state:
ids_list = ids_to_titles(st.session_state["user_preferences"])
preferences = st.multiselect(
label="Input games you like:",
options=list(data),
default=ids_list,
key="user_titles")
user_input = generate_app_gamebox(preferences)
else:
preferences = st.multiselect(
label="Input games you like:",
options=list(data),
key="user_titles")
user_input = generate_app_gamebox(preferences)
state = st.button("Get recommendation")
if state:
st.session_state["user_preferences"] = user_input
st.markdown("---")
games_recomm(st.session_state["user_preferences"])
# Result page. Show the list of predictions for active user
def result_page():
if "rs" not in st.session_state:
st.error('Please input preferences titles and run "Get recommendation"')
else:
st.success(f'Top {len(st.session_state["rs"])}')
user_res = generate_res_gamebox(ids=st.session_state['rs'])
# About page. Show the information of the project
def about_page():
st.header("Development")
"""
Cek [repositori](https://huggingface.co/spaces/deppfellow/steam-recsys/tree/main) untuk informasi, source code, dan metode yang digunakan. Jangan ragu Jika anda memiliki pertanyaan, terbuka melalui media sosial di bawah:
- Discord: deppfellow
- Email : raid.rafif@mail.ugm.ac.id
"""
st.subheader("Dataset")
"""
Untuk proyek ini, saya menggunakan data [*Game Recommendations on Steam*](https://www.kaggle.com/datasets/antonkozyriev/game-recommendations-on-steam), yang disediakan oleh Anton Kozyriev. Data yang digunakan dalam penelitian ini adalah informasi data per tanggal 6 Juni 2023. Berisi informasi pengguna yang dianonimkan, informasi game, serta interaksi antara pengguna dan item.
"""
st.subheader("Algoritma")
"""
[*Embarrassingly Shallow Autoencoder for Sparse Data*](https://arxiv.org/abs/1905.03375) atau EASE menjadi algoritma utama yang digunakan pada sistem rekomendasi ini. Dikembangkan oleh Harald Steck, algoritma EASE merupakan model linear yang memanfaatkan karakteristik *sparsity* dengan arsitektur menyerupai *autoencoder*, tetapi tanpa *hidden layer*. Meskipun kesederhanaan dari model linear, EASE menunjukkan performa yang baik pada data terbuka dengan:
- Peringkat ke-6 pada data [*MovieLens-20M*](https://paperswithcode.com/dataset/movielens)
- Peringkat ke-3 pada [*Netflix dataset*](https://paperswithcode.com/dataset/netflix-prize)
- *State-of-the-art* pada [*Million Song Dataset*](https://paperswithcode.com/dataset/msd)
Pada sistem rekomendasi ini, algoritma EASE digabungkan secara *hybrid* dengan algoritma *content-based filtering*.
"""
def main():
spr_sidebar()
# st.session_state
if st.session_state['app_mode'] == 'Home':
home_page()
elif st.session_state['app_mode'] == 'Result':
result_page()
elif st.session_state['app_mode'] == 'About':
about_page()
if __name__ == '__main__':
main()