Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| import pickle | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| import heapq | |
| # Load data and model | |
| df = pd.read_csv('./DATA/spotify_millsongdata.csv') | |
| # Load saved embeddings | |
| with open("./DATA/lyrics_embeddings.pkl", "rb") as f: | |
| lyrics_embeddings = pickle.load(f) | |
| # List of artists and songs | |
| artists = df['artist'].unique() | |
| song_titles = df['song'] | |
| # Recommendation logic | |
| def recommend_songs(song_index, top_n=5, batch_size=100): | |
| top_sim_scores = [] | |
| num_batches = len(df) // batch_size + 1 | |
| for i in range(num_batches): | |
| start_idx = i * batch_size | |
| end_idx = min((i + 1) * batch_size, len(df)) | |
| # Compute cosine similarity for the current batch | |
| cosine_sim_batch = cosine_similarity( | |
| lyrics_embeddings[start_idx:end_idx], | |
| [lyrics_embeddings[song_index]] | |
| ) | |
| # Select the top N most similar songs | |
| for j, sim_score in enumerate(cosine_sim_batch): | |
| global_idx = start_idx + j | |
| heapq.heappush(top_sim_scores, (sim_score[0], global_idx)) | |
| if len(top_sim_scores) > top_n + 1: | |
| heapq.heappop(top_sim_scores) | |
| # Exclude the selected song itself and return the most similar songs with their similarity scores | |
| top_sim_scores = sorted(top_sim_scores, key=lambda x: x[0], reverse=True)[1:top_n+1] | |
| recommended_songs = [(song_titles[i[1]], df['link'][i[1]], round(i[0], 2)) for i in top_sim_scores] | |
| return recommended_songs | |
| # Interface logic function | |
| def get_songs_by_artist(artist_name): | |
| filtered_songs = df[df['artist'] == artist_name]['song'].tolist() | |
| return gr.update(choices=filtered_songs, value=filtered_songs[0] if filtered_songs else None) | |
| def gradio_recommend(song_title): | |
| try: | |
| # Find the index of the selected song | |
| song_index = song_titles[song_titles == song_title].index[0] | |
| # Get recommended songs | |
| recommendations = recommend_songs(song_index) | |
| # Format the output, making song links clickable | |
| result = "<div style='text-align: left;'>" | |
| for song, link, sim_score in recommendations: | |
| result += f"<b>Song Name:</b> {song}<br>" | |
| result += f"<b>Search Link:</b> <a href='https://www.google.com/search?q={link}' target='_blank'>{link}</a><br>" | |
| result += f"<b>Lyrics Similarity:</b> {sim_score:.2f}<br><br>" | |
| result += "</div>" | |
| return result | |
| except IndexError: | |
| return "Song not found." | |
| # Create Gradio multi-page interface | |
| with gr.Blocks(css=""" | |
| @media (max-width: 768px) { | |
| .gr-container { | |
| width: 100%; | |
| padding: 10px; | |
| box-sizing: border-box; | |
| } | |
| .gr-dropdown select { | |
| width: 100%; | |
| height: 40px; /* Limit height */ | |
| font-size: 16px; | |
| padding: 5px; | |
| box-sizing: border-box; | |
| } | |
| .gr-button { | |
| width: 100%; | |
| font-size: 16px; | |
| margin-top: 10px; | |
| } | |
| .gr-html, .gr-row { | |
| width: 100%; | |
| font-size: 16px; | |
| margin: 10px 0; | |
| } | |
| h1 { | |
| font-size: 24px; | |
| } | |
| p { | |
| font-size: 14px; | |
| } | |
| .gr-dropdown::after { | |
| content: ''; | |
| width: 12px; | |
| height: 12px; | |
| border: solid black; | |
| border-width: 0 2px 2px 0; | |
| display: inline-block; | |
| transform: rotate(45deg); | |
| margin-left: 10px; | |
| } | |
| } | |
| """) as demo: | |
| gr.Markdown( | |
| """ | |
| <div style="text-align: center; padding: 20px;"> | |
| <h1 style="color: #1DB954;">Music Recommendation System</h1> | |
| <p style="font-size: 18px;">Get the most relevant song recommendations based on lyrics similarity</p> | |
| </div> | |
| """ | |
| ) | |
| # Page 1: Select artist | |
| with gr.Row(): | |
| with gr.Column(): | |
| artist_dropdown = gr.Dropdown(choices=list(artists), label="Select Artist") | |
| next_button = gr.Button("Next") | |
| # Page 2: Select song and get recommendations | |
| with gr.Row(visible=False) as song_selection_row: | |
| song_dropdown = gr.Dropdown(label="Select Song") | |
| recommend_button = gr.Button("Get Recommendations") | |
| output = gr.HTML(label="Recommended Similar Songs") | |
| # Event bindings | |
| artist_dropdown.change(get_songs_by_artist, inputs=artist_dropdown, outputs=song_dropdown) | |
| next_button.click(lambda: gr.update(visible=True), None, song_selection_row) | |
| recommend_button.click(gradio_recommend, inputs=song_dropdown, outputs=output) | |
| if __name__ == "__main__": | |
| demo.launch() | |