import streamlit as st import pandas as pd import joblib import os # 1. Page Configuration st.set_page_config(page_title="BgemBox Music Engine", layout="wide", page_icon="🎵") # Custom CSS to improve font size and table padding st.markdown(""" """, unsafe_allow_html=True) # 2. Load Scaler and Data @st.cache_resource def load_assets(): # 1. Veriyi yükle data = pd.read_pickle("final_music_data.pkl") # 2. Scaler'ı yükle scaler = joblib.load("scaler.pkl") # 3. Kümeleme sütunlarını kontrol et (Return'den ÖNCE olmalı) if 'sub_cluster' not in data.columns: if 'cluster' in data.columns: data['sub_cluster'] = data['cluster'] else: # st.error burada çalışmayabilir, konsola yazdıralım print("Critical Error: No clustering columns found!") # İki nesneyi birden döndür return data, scaler try: # Fonksiyon iki değer döndürdüğü için ikisini de ayrı ayrı almalıyız df, music_scaler = load_assets() except Exception as e: st.error(f"Asset Loading Error: {e}") st.stop() # 3. Sidebar Configuration st.sidebar.title("Music Engine Settings") st.sidebar.markdown("---") st.sidebar.write("This AI-powered engine clusters music based on technical audio features like BPM, Energy, and Acousticness.") st.sidebar.info("Developed by Elif | 2026") # 4. Cluster Labels cluster_names = { 8.0: "🌟 Mainstream Pop Hits", 1.0: "🎸 Classic Rock & Dynamic Rhythms", 2.0: "🎹 Alternative & Indie Vibes", 7.0: "📜 Nostalgic Oldies", 3.0: "🌊 Chill & Low-Fi Moods", 4.0: "⚡ High-Energy / Gym Motivation", 0.0: "💎 Unique Rare Finds", 5.0: "💎 Unique Rare Finds", 6.0: "💎 Unique Rare Finds" } # 5. Main UI st.title("🎵 BgemBox Music Recommendation System") st.subheader("Discover music through Data Science") st.markdown("---") tab1, tab2 = st.tabs(["Search by Artist", "Discover by Mood"]) # TAB 1: Recommendation by Artist with tab1: st.write("### Find Similar Artists") artist_list = sorted(df['Artist'].unique()) selected_artist = st.selectbox("Select an Artist you like:", artist_list) if st.button("Recommend Similar Music"): artist_data = df[df['Artist'] == selected_artist].iloc[0] cluster_id = artist_data['sub_cluster'] friendly_name = cluster_names.get(cluster_id, "Similar Style Tracks") st.success(f"Artist **{selected_artist}** belongs to the **{friendly_name}** segment.") recommendations = df[(df['sub_cluster'] == cluster_id) & (df['Artist'] != selected_artist)] recommendations = recommendations.sort_values(by='Popularity', ascending=False).head(5) st.write("#### Recommended for you:") # Used st.table for better readability and tighter columns st.table(recommendations[['Artist', 'Top Genre', 'Popularity']]) # TAB 2: Discover by Mood with tab2: st.write("### How are you feeling today?") selected_mood_name = st.selectbox("Select a Mood:", list(cluster_names.values())) mood_id = [k for k, v in cluster_names.items() if v == selected_mood_name][0] if st.button("Generate Playlist"): mood_list = df[df['sub_cluster'] == mood_id] if not mood_list.empty: # Taking a random sample of 10 playlist = mood_list.sample(min(len(mood_list), 10)) st.write(f"#### Your {selected_mood_name} Playlist:") # Use st.table here instead of dataframe for better font size and compact columns st.table(playlist[['Artist', 'Top Genre', 'Popularity', 'Energy', 'Beats Per Minute (BPM)']]) else: st.warning("This specific cluster is currently empty or has only one track.") # 6. Footer st.markdown("---") st.caption("© 2026 Data Science Specialization Project")