ElifSB commited on
Commit
71a92ec
·
verified ·
1 Parent(s): 7f3e47a

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +113 -0
  2. final_music_data.pkl +3 -0
  3. scaler.pkl +3 -0
app.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import joblib
4
+ import os
5
+
6
+ # 1. Page Configuration
7
+ st.set_page_config(page_title="BgemBox Music Engine", layout="wide", page_icon="🎵")
8
+
9
+ # Custom CSS to improve font size and table padding
10
+ st.markdown("""
11
+ <style>
12
+ .main .block-container {padding-top: 2rem;}
13
+ th {background-color: #f0f2f6 !important; font-size: 16px !important;}
14
+ td {font-size: 15px !important;}
15
+ </style>
16
+ """, unsafe_allow_html=True)
17
+
18
+ # 2. Load Scaler and Data
19
+ @st.cache_resource
20
+ def load_assets():
21
+ # 1. Veriyi yükle
22
+ data = pd.read_pickle("final_music_data.pkl")
23
+
24
+ # 2. Scaler'ı yükle
25
+ scaler = joblib.load("scaler.pkl")
26
+
27
+ # 3. Kümeleme sütunlarını kontrol et (Return'den ÖNCE olmalı)
28
+ if 'sub_cluster' not in data.columns:
29
+ if 'cluster' in data.columns:
30
+ data['sub_cluster'] = data['cluster']
31
+ else:
32
+ # st.error burada çalışmayabilir, konsola yazdıralım
33
+ print("Critical Error: No clustering columns found!")
34
+
35
+ # İki nesneyi birden döndür
36
+ return data, scaler
37
+
38
+ try:
39
+ # Fonksiyon iki değer döndürdüğü için ikisini de ayrı ayrı almalıyız
40
+ df, music_scaler = load_assets()
41
+ except Exception as e:
42
+ st.error(f"Asset Loading Error: {e}")
43
+ st.stop()
44
+
45
+ # 3. Sidebar Configuration
46
+ st.sidebar.title("Music Engine Settings")
47
+ st.sidebar.markdown("---")
48
+ st.sidebar.write("This AI-powered engine clusters music based on technical audio features like BPM, Energy, and Acousticness.")
49
+ st.sidebar.info("Developed by Elif | 2026")
50
+
51
+ # 4. Cluster Labels
52
+ cluster_names = {
53
+ 8.0: "🌟 Mainstream Pop Hits",
54
+ 1.0: "🎸 Classic Rock & Dynamic Rhythms",
55
+ 2.0: "🎹 Alternative & Indie Vibes",
56
+ 7.0: "📜 Nostalgic Oldies",
57
+ 3.0: "🌊 Chill & Low-Fi Moods",
58
+ 4.0: "⚡ High-Energy / Gym Motivation",
59
+ 0.0: "💎 Unique Rare Finds",
60
+ 5.0: "💎 Unique Rare Finds",
61
+ 6.0: "💎 Unique Rare Finds"
62
+ }
63
+
64
+ # 5. Main UI
65
+ st.title("🎵 BgemBox Music Recommendation System")
66
+ st.subheader("Discover music through Data Science")
67
+ st.markdown("---")
68
+
69
+ tab1, tab2 = st.tabs(["Search by Artist", "Discover by Mood"])
70
+
71
+ # TAB 1: Recommendation by Artist
72
+ with tab1:
73
+ st.write("### Find Similar Artists")
74
+ artist_list = sorted(df['Artist'].unique())
75
+ selected_artist = st.selectbox("Select an Artist you like:", artist_list)
76
+
77
+ if st.button("Recommend Similar Music"):
78
+ artist_data = df[df['Artist'] == selected_artist].iloc[0]
79
+ cluster_id = artist_data['sub_cluster']
80
+
81
+ friendly_name = cluster_names.get(cluster_id, "Similar Style Tracks")
82
+ st.success(f"Artist **{selected_artist}** belongs to the **{friendly_name}** segment.")
83
+
84
+ recommendations = df[(df['sub_cluster'] == cluster_id) & (df['Artist'] != selected_artist)]
85
+ recommendations = recommendations.sort_values(by='Popularity', ascending=False).head(5)
86
+
87
+ st.write("#### Recommended for you:")
88
+ # Used st.table for better readability and tighter columns
89
+ st.table(recommendations[['Artist', 'Top Genre', 'Popularity']])
90
+
91
+ # TAB 2: Discover by Mood
92
+ with tab2:
93
+ st.write("### How are you feeling today?")
94
+ selected_mood_name = st.selectbox("Select a Mood:", list(cluster_names.values()))
95
+
96
+ mood_id = [k for k, v in cluster_names.items() if v == selected_mood_name][0]
97
+
98
+ if st.button("Generate Playlist"):
99
+ mood_list = df[df['sub_cluster'] == mood_id]
100
+
101
+ if not mood_list.empty:
102
+ # Taking a random sample of 10
103
+ playlist = mood_list.sample(min(len(mood_list), 10))
104
+ st.write(f"#### Your {selected_mood_name} Playlist:")
105
+
106
+ # Use st.table here instead of dataframe for better font size and compact columns
107
+ st.table(playlist[['Artist', 'Top Genre', 'Popularity', 'Energy', 'Beats Per Minute (BPM)']])
108
+ else:
109
+ st.warning("This specific cluster is currently empty or has only one track.")
110
+
111
+ # 6. Footer
112
+ st.markdown("---")
113
+ st.caption("© 2026 Data Science Specialization Project")
final_music_data.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:46783ba5dca1b249c97f1eaf06162acb1243c4826fc397d07498406c760709ee
3
+ size 227193
scaler.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c5a84ecceac33f1e27c541c08fd306700339c6bb4879089864100c73cd965df5
3
+ size 8567