File size: 5,580 Bytes
a2d0e0e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# Streamlit application
# Import necessary libraries
import streamlit as st
import pandas as pd
from openai import OpenAI
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
# Import data
music_data = pd.read_csv("Spotify_Youtube.csv")
# Specify api key for OpenAIs API
client = OpenAI(api_key="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")
# Function that calls OpenAIs API
def parse_user_input(user_input):
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{
"role": "system",
"content": """You will be provided with an input: '{user_input}', and your task is to determine the following:
- Valence: a number that is equal to the mood. Positive moods are closer to 1 and negative moods are closer to 0.
- Number of songs: the number of songs the user requests.
- Tempo: the tempo of the songs.
- Danceability: the danceability of the songs.
Provide this information in the following format with each value separated by a space:
'valence number_of_songs tempo danceability'
Example: '0.5 20 120 0.8'
"""
},
{
"role": "user",
"content": user_input
},
{
"role": "assistant",
"content": "0.5 20, 120, 0.8"
}
],
temperature=0.5,
max_tokens=64,
top_p=1
)
return response.choices[0].message.content
# Function create new dataframe from music dataframe based on valence, number of tracks, tempo an danceability
def get_tracks_by_artist_and_danceability(music_data, valence, num_tracks, tempo, danceability):
filtered_tracks = music_data[
(music_data['Valence'].between(valence - 0.1, valence + 0.1)) &
(music_data['Tempo'].between(tempo - 30, tempo + 30)) &
(music_data['Danceability'].between(danceability - 0.2, danceability + 0.2))
]
return filtered_tracks.head(num_tracks)[['Track', 'Artist']]
# Function the recommends tracks by using tfidVectoricer and cosine_similarities
def recommend_tracks(track_names, track_ids, top_k=20):
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(track_names)
similarities = cosine_similarity(tfidf_matrix)
avg_similarity = similarities.mean(axis=0)
top_indices = avg_similarity.argsort()[-top_k:][::-1]
return track_ids.iloc[top_indices]
# Streamlit Application
logo = "music_logo.png"
# Sidebar
with st.sidebar:
st.image(logo, width=100)
st.header("Navigation")
tab_selection = st.sidebar.radio("Go to", ["Music Generator", "Browse Music", "About Us"])
# Music generator page
if tab_selection == "Music Generator":
st.header("Mood Playlist Generator", divider='rainbow')
st.write("Enter your music preferences in a detailed format and recieve a personalized playlist based on your mood:")
user_prompt = st.text_input("Example: 'I want 20 happy songs with a lot of tempo that i can dance to!'")
if st.button("Generate Playlist"):
try:
with st.spinner("Processing your request..."):
parsed_input = parse_user_input(user_prompt)
#st.write(f"Parsed input: {parsed_input}")
# Extract valence and number of songs from the parsed input
valence, num_tracks, tempo, danceability = parsed_input.split()
valence = float(valence)
num_tracks = int(num_tracks)
tempo = int(tempo)
danceability = (float(danceability))
#st.write(f"Number of tracks: {num_tracks}, Valence: {valence}, Tempo: {tempo}, Danceability: {danceability}")
tracks = get_tracks_by_artist_and_danceability(music_data, valence, num_tracks, tempo, danceability)
#st.write(f"Found {len(tracks)} tracks.")
if tracks.empty:
st.write("No tracks found. Please try a different query.")
else:
track_names = tracks['Track'].tolist()
track_ids = tracks[['Track', 'Artist']]
#st.write("Track names:", track_names)
recommended_tracks = recommend_tracks(track_names, track_ids, top_k=int(num_tracks))
st.write("Here are your recommended playlist:")
st.table(recommended_tracks)
st.button("Add playlist to Spotify")
except ValueError:
st.write("Error: Unable to parse the input. Please make sure the format is correct.")
# Browse music page
elif tab_selection == "Browse Music":
st.header("Browse Music", divider='rainbow')
st.write("Explore the music data used for generating your playlists.")
df = pd.read_csv("Spotify_Youtube.csv")
st.dataframe(df)
# About us page
elif tab_selection == "About Us":
st.header("About Us", divider='rainbow')
st.write("""
This App is developed by 4 ambitious university students, whose goals are to create playlists and music experiences which you can emotionally connect with.
""")
st.image("group_photo.jpg", caption="Our Team", use_column_width=True)
# Add custom CSS
st.markdown(
"""
<style>
.css-18e3th9 {
padding-top: 2rem;
}
.css-1d391kg {
padding-top: 1.5rem;
}
.css-1d2jrlv {
padding-bottom: 1rem;
}
.css-1v3fvcr {
padding-top: 1rem;
padding-bottom: 1rem;
}
</style>
""",
unsafe_allow_html=True
)
|