Delete pages/Recommender.py
Browse files- pages/Recommender.py +0 -175
pages/Recommender.py
DELETED
@@ -1,175 +0,0 @@
|
|
1 |
-
import streamlit as st
|
2 |
-
|
3 |
-
# Configure Streamlit page
|
4 |
-
st.set_page_config(
|
5 |
-
page_title="Find the Song that You Like🎸", page_icon="🎸", layout="wide"
|
6 |
-
)
|
7 |
-
|
8 |
-
import pandas as pd
|
9 |
-
import plotly.express as px
|
10 |
-
import streamlit.components.v1 as components
|
11 |
-
from sklearn.neighbors import NearestNeighbors
|
12 |
-
|
13 |
-
|
14 |
-
@st.cache(allow_output_mutation=True)
|
15 |
-
def data_import():
|
16 |
-
"""Function for loading in cleaned data csv file."""
|
17 |
-
df = pd.read_csv("data/clean_data.csv")
|
18 |
-
df["genres"] = df.genres.apply(
|
19 |
-
lambda x: [i[1:-1] for i in str(x)[1:-1].split(", ")]
|
20 |
-
)
|
21 |
-
df_explode = df.explode("genres")
|
22 |
-
return df_explode
|
23 |
-
|
24 |
-
|
25 |
-
genre_names = [
|
26 |
-
"Dance Pop",
|
27 |
-
"Electronic",
|
28 |
-
"Electropop",
|
29 |
-
"Hip Hop",
|
30 |
-
"Jazz",
|
31 |
-
"K-pop",
|
32 |
-
"Latin",
|
33 |
-
"Pop",
|
34 |
-
"Pop Rap",
|
35 |
-
"R&B",
|
36 |
-
"Rock",
|
37 |
-
]
|
38 |
-
audio_params = [
|
39 |
-
"acousticness",
|
40 |
-
"danceability",
|
41 |
-
"energy",
|
42 |
-
"instrumentalness",
|
43 |
-
"valence",
|
44 |
-
"tempo",
|
45 |
-
]
|
46 |
-
|
47 |
-
df_explode = data_import()
|
48 |
-
|
49 |
-
|
50 |
-
def match_song(genre, yr_start, yr_end, test_feat):
|
51 |
-
"""Function for finding similar songs with KNN algorithm."""
|
52 |
-
genre = genre.lower()
|
53 |
-
genre_data = df_explode[
|
54 |
-
(df_explode["genres"] == genre)
|
55 |
-
& (df_explode["release_year"] >= yr_start)
|
56 |
-
& (df_explode["release_year"] <= yr_end)
|
57 |
-
]
|
58 |
-
genre_data = genre_data.sort_values(by="popularity", ascending=False)[:500]
|
59 |
-
|
60 |
-
# Load KNN from SkLearn
|
61 |
-
neigh = NearestNeighbors()
|
62 |
-
neigh.fit(genre_data[audio_params].to_numpy())
|
63 |
-
|
64 |
-
n_neighbors = neigh.kneighbors(
|
65 |
-
[test_feat], n_neighbors=len(genre_data), return_distance=False
|
66 |
-
)[0]
|
67 |
-
|
68 |
-
uris = genre_data.iloc[n_neighbors]["uri"].tolist()
|
69 |
-
audios = genre_data.iloc[n_neighbors][audio_params].to_numpy()
|
70 |
-
|
71 |
-
return uris, audios
|
72 |
-
|
73 |
-
|
74 |
-
# Setup page order
|
75 |
-
def page():
|
76 |
-
title = "Find Your Song🎸"
|
77 |
-
st.title(title)
|
78 |
-
|
79 |
-
st.write(
|
80 |
-
"Get recommended songs on Spotify based on genre and key audio parameters."
|
81 |
-
)
|
82 |
-
st.markdown("##")
|
83 |
-
|
84 |
-
# Streamlit column layout
|
85 |
-
with st.container():
|
86 |
-
col1, col2, col3, col4 = st.columns((2, 0.5, 0.5, 0.5))
|
87 |
-
|
88 |
-
with col3:
|
89 |
-
st.markdown("***Select genre:***")
|
90 |
-
genre = st.radio("", genre_names, index=genre_names.index("Rock"))
|
91 |
-
|
92 |
-
with col1:
|
93 |
-
st.markdown("***Select audio parameters to customize:***")
|
94 |
-
yr_start, yr_end = st.slider(
|
95 |
-
"Select the year range", 1908, 2022, (1980, 2022)
|
96 |
-
)
|
97 |
-
acousticness = st.slider("Acousticness", 0.0, 1.0, 0.5)
|
98 |
-
danceability = st.slider("Danceability", 0.0, 1.0, 0.5)
|
99 |
-
energy = st.slider("Energy", 0.0, 1.0, 0.5)
|
100 |
-
instrumentalness = st.slider("Instrumentalness", 0.0, 1.0, 0.5)
|
101 |
-
valence = st.slider("Valence", 0.0, 1.0, 0.45)
|
102 |
-
tempo = st.slider("Tempo", 0.0, 244.0, 125.01)
|
103 |
-
|
104 |
-
pr_page_tracks = 6
|
105 |
-
test_feat = [acousticness, danceability, energy, instrumentalness, valence, tempo]
|
106 |
-
uris, audios = match_song(genre, yr_start, yr_end, test_feat)
|
107 |
-
|
108 |
-
tracks = []
|
109 |
-
for uri in uris:
|
110 |
-
track = """<iframe src="https://open.spotify.com/embed/track/{}" width="280" height="400" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>""".format(
|
111 |
-
uri
|
112 |
-
)
|
113 |
-
tracks.append(track)
|
114 |
-
|
115 |
-
if "previous_inputs" not in st.session_state:
|
116 |
-
st.session_state["previous_inputs"] = [genre, yr_start, yr_end] + test_feat
|
117 |
-
|
118 |
-
current_inputs = [genre, yr_start, yr_end] + test_feat
|
119 |
-
if current_inputs != st.session_state["previous_inputs"]:
|
120 |
-
if "start_track_i" in st.session_state:
|
121 |
-
st.session_state["start_track_i"] = 0
|
122 |
-
|
123 |
-
st.session_state["previous_inputs"] = current_inputs
|
124 |
-
|
125 |
-
if "start_track_i" not in st.session_state:
|
126 |
-
st.session_state["start_track_i"] = 0
|
127 |
-
|
128 |
-
with st.container():
|
129 |
-
col1, col2, col3 = st.columns([2, 1, 2])
|
130 |
-
if st.button("More Songs"):
|
131 |
-
if st.session_state["start_track_i"] < len(tracks):
|
132 |
-
st.session_state["start_track_i"] += pr_page_tracks
|
133 |
-
|
134 |
-
current_tracks = tracks[
|
135 |
-
st.session_state["start_track_i"] : st.session_state["start_track_i"]
|
136 |
-
+ pr_page_tracks
|
137 |
-
]
|
138 |
-
current_audios = audios[
|
139 |
-
st.session_state["start_track_i"] : st.session_state["start_track_i"]
|
140 |
-
+ pr_page_tracks
|
141 |
-
]
|
142 |
-
if st.session_state["start_track_i"] < len(tracks):
|
143 |
-
for i, (track, audio) in enumerate(zip(current_tracks, current_audios)):
|
144 |
-
if i % 2 == 0:
|
145 |
-
with col1:
|
146 |
-
components.html(
|
147 |
-
track,
|
148 |
-
height=400,
|
149 |
-
)
|
150 |
-
with st.expander("Display Chart"):
|
151 |
-
df = pd.DataFrame(dict(r=audio[:5], theta=audio_params[:5]))
|
152 |
-
fig = px.line_polar(
|
153 |
-
df, r="r", theta="theta", line_close=True
|
154 |
-
)
|
155 |
-
fig.update_layout(height=400, width=340)
|
156 |
-
st.plotly_chart(fig)
|
157 |
-
|
158 |
-
else:
|
159 |
-
with col3:
|
160 |
-
components.html(
|
161 |
-
track,
|
162 |
-
height=400,
|
163 |
-
)
|
164 |
-
with st.expander("Display Chart"):
|
165 |
-
df = pd.DataFrame(dict(r=audio[:5], theta=audio_params[:5]))
|
166 |
-
fig = px.line_polar(
|
167 |
-
df, r="r", theta="theta", line_close=True
|
168 |
-
)
|
169 |
-
fig.update_layout(height=400, width=340)
|
170 |
-
st.plotly_chart(fig)
|
171 |
-
else:
|
172 |
-
st.write("No more songs")
|
173 |
-
|
174 |
-
|
175 |
-
page()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|