spotify-music-clustering / src /streamlit_app.py
ESMATUGBA's picture
Update src/streamlit_app.py
9858ca0 verified
Raw
History Blame Contribute Delete
4.41 kB
import streamlit as st
import pandas as pd
import joblib
import os
import warnings
# Gereksiz uyarıları kapat / Silence warnings
warnings.filterwarnings('ignore')
# 1️⃣ Sayfa Ayarları / Page Configuration
st.set_page_config(page_title="Spotify Analysis Pro", layout="wide")
# 2️⃣ Veri ve Model Yükleme / Load Data & Models
@st.cache_data
def load_data():
if not os.path.exists("spotify_clustered.csv"): return None
return pd.read_csv("spotify_clustered.csv")
@st.cache_resource
def load_models():
try:
model = joblib.load("kmeans_music_model.pkl")
scaler = joblib.load("scaler_music.pkl")
return model, scaler
except: return None, None
df = load_data()
model, scaler = load_models()
# 3️⃣ Sol Panel (Sidebar) - YÖNETİCİ NOTLARI / EXECUTIVE NOTES
with st.sidebar:
st.title("📂 Analiz Notları / Analysis Notes")
st.success("✅ System: Active / Sistem: Aktif")
st.markdown("""
### 📊 Stratejik Özet / Strategic Summary
*TR:* Bu sistem, şarkıları karakteristik benzerliklerine göre **2 ana gruba** ayırmıştır.
*EN:* This system has categorized songs into **2 main groups** based on their characteristics.
### 🔍 Küme Yorumları / Cluster Interpretation
* **Cluster 0 (Sakin/Quiet):** - *TR:* Düşük enerji, odaklanma müzikleri.
- *EN:* Low energy, focus/chill music.
* **Cluster 1 (Dinamik/Dynamic):** - *TR:* Yüksek enerji, ritmik ve popüler.
- *EN:* High energy, rhythmic and popular.
### 📈 Teknik Onay / Technical Validation
*TR:* Silhouette skoru pozitiftir; ayrım tutarlıdır.
*EN:* Silhouette score is positive; separation is consistent.
""")
st.divider()
st.caption("Spotify Segmentation Project v2.0")
# 4️⃣ Ana Başlık / Main Title
st.title("🎵 Spotify Müzik Kümeleme Analizi | Spotify Music Clustering Analysis")
st.write("Veri madenciliği ile şarkı segmentasyonu / Song segmentation with data mining.")
st.write("---")
if df is not None:
# 📄 Veri Önizleme / Preview
st.subheader("📄 Veri Önizleme / Dataset Preview")
st.dataframe(df.head(5), use_container_width=True)
# 5️⃣ Görselleştirmeler / Visualizations
col1, col2 = st.columns(2)
with col1:
st.subheader("📊 Küme Dağılımı / Cluster Distribution")
st.bar_chart(df['cluster'].value_counts())
with col2:
st.subheader("🎯 Enerji vs Dans / Energy vs Danceability")
st.scatter_chart(df.sample(min(1000, len(df))), x='danceability', y='energy', color='cluster')
# 6️⃣ Tahmin Bölümü / Prediction Section
st.divider()
st.subheader("🤖 Yeni Şarkı Analizi / New Song Analysis")
with st.form("prediction_form"):
st.info("Özellikleri girin / Enter song features.")
c1, c2, c3 = st.columns(3)
with c1:
pop = st.slider("Popularity / Popülerlik", 0, 100, 50)
dur = st.number_input("Duration / Süre (ms)", value=200000)
with c2:
dance = st.slider("Danceability / Dans Edilebilirlik", 0.0, 1.0, 0.5)
energy = st.slider("Energy / Enerji", 0.0, 1.0, 0.5)
with c3:
loud = st.slider("Loudness / Ses (dB)", -60.0, 0.0, -10.0)
tempo = st.slider("Tempo (BPM)", 0.0, 250.0, 120.0)
submit = st.form_submit_button("Analiz Et / Analyze ✨")
if submit and model and scaler:
try:
# Model expects 6 features
input_data = [[pop, dur, dance, energy, loud, tempo]]
res = model.predict(scaler.transform(input_data))[0]
# İSTEDİĞİN ÖZEL NOT KISMI BURASI:
if res == 0:
note = "0 - SAKİN / QUIET MUSIC ☕"
else:
note = "1 - DİNAMİK / DYNAMIC MUSIC 🔥"
st.success(f"### Sonuç / Result: {note}")
st.balloons()
except Exception as e:
st.error(f"Error / Hata: {e}")
# 7️⃣ Ortalama Değerler / Means
st.divider()
st.subheader("🔍 Küme Karakteristikleri / Cluster Characteristics")
num_cols = df.select_dtypes(include=['number']).columns.tolist()
if 'cluster' in df.columns:
st.dataframe(df.groupby('cluster')[num_cols].mean(), use_container_width=True)
else:
st.error("Missing files! / Dosyalar eksik!")