Spaces:
Runtime error
Runtime error
first version
Browse files
app.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import streamlit as st
|
4 |
+
|
5 |
+
from utils import get_index, get_movie_info
|
6 |
+
|
7 |
+
MAX_OVERVIEW_LENGTH = 280
|
8 |
+
IMAGE_WIDTH = 170
|
9 |
+
|
10 |
+
|
11 |
+
@st.cache()
|
12 |
+
def init() -> None:
|
13 |
+
movies = pd.read_csv("movies.csv")
|
14 |
+
st.session_state["movies"] = movies
|
15 |
+
st.session_state["titles"] = movies["original_title"].values
|
16 |
+
st.session_state["sim_matrix"] = np.load("sim.npy")
|
17 |
+
|
18 |
+
|
19 |
+
def run() -> None:
|
20 |
+
st.title("Movie Recommender")
|
21 |
+
with st.form("search"):
|
22 |
+
title = st.selectbox("Recommend movies based on:", st.session_state["titles"])
|
23 |
+
num_recommendations = st.number_input(
|
24 |
+
"Number of recommendations:", min_value=1, max_value=20, value=6
|
25 |
+
)
|
26 |
+
search = st.form_submit_button("Search")
|
27 |
+
if search:
|
28 |
+
recommend(title, num_recommendations)
|
29 |
+
|
30 |
+
|
31 |
+
def recommend(based_on: str, num_recommendations: int) -> None:
|
32 |
+
movie_index = get_index(based_on)
|
33 |
+
similarities = list(enumerate(st.session_state["sim_matrix"][movie_index]))
|
34 |
+
similarities.pop(movie_index)
|
35 |
+
sorted_similarities = sorted(similarities, key=lambda x: x[1], reverse=True)
|
36 |
+
recommendations = sorted_similarities[:num_recommendations]
|
37 |
+
st.markdown("---")
|
38 |
+
for idx, _ in recommendations:
|
39 |
+
show_movie_info(idx)
|
40 |
+
|
41 |
+
|
42 |
+
def show_movie_info(movie_index: str) -> None:
|
43 |
+
info = get_movie_info(movie_index)
|
44 |
+
im_col, info_col = st.columns([2, 4])
|
45 |
+
im_col.image(
|
46 |
+
f"https://a.ltrbxd.com/resized/{info['image_url']}.jpg", width=IMAGE_WIDTH
|
47 |
+
)
|
48 |
+
info_col.markdown(
|
49 |
+
f"### {info['original_title']} ({info['release_date'].split('-')[0]})"
|
50 |
+
)
|
51 |
+
info_col.markdown(f"*{int(info['runtime'])} min*")
|
52 |
+
short_overview = (
|
53 |
+
f"{info['overview'][:MAX_OVERVIEW_LENGTH]} ..."
|
54 |
+
if len(info["overview"]) > MAX_OVERVIEW_LENGTH
|
55 |
+
else info["overview"]
|
56 |
+
)
|
57 |
+
info_col.markdown(short_overview)
|
58 |
+
info_col.caption(", ".join(eval(info["genres"])))
|
59 |
+
st.markdown("---")
|
60 |
+
|
61 |
+
|
62 |
+
if __name__ == "__main__":
|
63 |
+
init()
|
64 |
+
run()
|
movies.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
sim.npy
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4b80ed1781ba5b653ff99a95c67a14aa040265fe5a4fc2b89162219154ba8cc8
|
3 |
+
size 168838816
|
utils.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
|
4 |
+
def get_index(title: str) -> int:
|
5 |
+
movies = st.session_state["movies"]
|
6 |
+
return movies[movies["original_title"] == title].index.values[0]
|
7 |
+
|
8 |
+
|
9 |
+
def get_movie_info(movie_index: int) -> dict:
|
10 |
+
return st.session_state["movies"].iloc[movie_index].to_dict()
|