ESMATUGBA commited on
Commit
cefb482
·
verified ·
1 Parent(s): 0361e4c

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +109 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,111 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
1
  import streamlit as st
2
+ import pandas as pd
3
+ import joblib
4
+ import matplotlib.pyplot as plt
5
+
6
+ # --------------------------------------
7
+ # 1️⃣ Load Files & Data Cleaning / Dosyaları Yükle ve Temizle
8
+ # --------------------------------------
9
+ @st.cache_data
10
+ def load_data():
11
+ # Kendi kaydettiğin CSV dosyan
12
+ df = pd.read_csv("spotify_clustered.csv")
13
+
14
+ # Gereksiz/Teknik sütunları temizle (Görünümü güzelleştirir)
15
+ unnecessary_cols = ['Unnamed: 0', 'track_id', 'album_name', 'explicit']
16
+ df_display = df.drop(columns=[c for c in unnecessary_cols if c in df.columns])
17
+
18
+ return df, df_display
19
+
20
+ # Dosyaları yükle
21
+ df, df_display = load_data()
22
+ model = joblib.load("kmeans_music_model.pkl")
23
+ scaler = joblib.load("scaler_music.pkl")
24
+
25
+ # --------------------------------------
26
+ # 2️⃣ Page Config / Sayfa Ayarları (Titremeyi önlemek için geniş mod)
27
+ # --------------------------------------
28
+ st.set_page_config(page_title="Spotify Clusters", layout="wide")
29
+ st.title("🎵 Spotify Music Clustering / Müzik Kümeleme Analizi")
30
+ st.markdown("---")
31
+
32
+ # --------------------------------------
33
+ # 3️⃣ Dataset Preview / Veri Seti Önizleme
34
+ # --------------------------------------
35
+ st.subheader("📄 Dataset Preview / Veri Önizleme")
36
+ st.write("Cleaned data for analysis / Analiz için temizlenmiş veri:")
37
+ st.dataframe(df_display.head(10), use_container_width=True)
38
+
39
+ # --------------------------------------
40
+ # 4️⃣ Visualizations / Görselleştirmeler (Titremeyi engelleyen yapı)
41
+ # --------------------------------------
42
+ col1, col2 = st.columns(2)
43
+
44
+ with col1:
45
+ st.subheader("📊 Cluster Distribution / Küme Dağılımı")
46
+ st.bar_chart(df['cluster'].value_counts())
47
+
48
+ with col2:
49
+ st.subheader("🎯 Feature Analysis / Özellik Analizi")
50
+ # Grafiği açıkça tanımlıyoruz ve her seferinde kapatıyoruz
51
+ fig, ax = plt.subplots(figsize=(8, 5))
52
+ scatter = ax.scatter(df['danceability'], df['energy'], c=df['cluster'], cmap='viridis', alpha=0.6)
53
+ ax.set_xlabel("Danceability / Dans Edilebilirlik")
54
+ ax.set_ylabel("Energy / Enerji")
55
+ plt.colorbar(scatter, label="Cluster / Küme")
56
+
57
+ # Titremeyi önlemek için clear_figure=True kullanıyoruz
58
+ st.pyplot(fig, clear_figure=True)
59
+ plt.close(fig) # Belleği boşalt
60
+
61
+ # --------------------------------------
62
+ # 5️⃣ Prediction Section / Tahmin Bölümü
63
+ # --------------------------------------
64
+ st.divider()
65
+ st.subheader("🤖 Predict New Song Cluster / Yeni Şarkı Tahmini")
66
+ st.info("Adjust the sliders to see which cluster a song belongs to / Şarkının hangi kümeye ait olduğunu görmek için sürgüleri ayarlayın.")
67
+
68
+ c1, c2, c3 = st.columns(3)
69
+
70
+ with c1:
71
+ pop = st.slider("Popularity / Popülerlik", 0, 100, 50)
72
+ dur = st.slider("Duration (ms) / Süre", 0, 600000, 200000)
73
+ dance = st.slider("Danceability / Dans Edilebilirlik", 0.0, 1.0, 0.5)
74
+
75
+ with c2:
76
+ energy = st.slider("Energy / Enerji", 0.0, 1.0, 0.5)
77
+ loud = st.slider("Loudness / Ses Yüksekliği", -60.0, 0.0, -10.0)
78
+ tempo = st.slider("Tempo / Tempo", 0.0, 250.0, 120.0)
79
+
80
+ with c3:
81
+ # Kaggle'da eğittiğin 7. özelliği buraya ekledik (Hata almamak için)
82
+ speech = st.slider("Speechiness / Konuşma Oranı", 0.0, 1.0, 0.1)
83
+
84
+ if st.button("Predict Cluster / Kümeyi Tahmin Et ✨"):
85
+ # SIRALAMA: Kaggle'daki modelin beklediği sırayla veriyoruz
86
+ new_data = [[pop, dur, dance, energy, loud, tempo, speech]]
87
+
88
+ try:
89
+ new_data_scaled = scaler.transform(new_data)
90
+ res = model.predict(new_data_scaled)[0]
91
+
92
+ st.success(f"### Predicted Cluster / Tahmin Edilen Küme: {res}")
93
+
94
+ # O kümeden benzer şarkı örnekleri
95
+ st.write(f"**Similar songs from this group / Bu gruptaki benzer şarkılar:**")
96
+ samples = df[df['cluster'] == res][['track_name', 'artists']].head(5)
97
+ st.table(samples)
98
+
99
+ except Exception as e:
100
+ st.error(f"Prediction Error / Tahmin Hatası: {e}")
101
 
102
+ # --------------------------------------
103
+ # 6️⃣ Cluster Characteristics / Küme Karakteristikleri
104
+ # --------------------------------------
105
+ st.divider()
106
+ st.subheader("🔍 Cluster Characteristics / Küme Özellikleri (Ortalamalar)")
107
+ # Sadece sayısal verileri grupla (Titremeyi önlemek için seçim yapıyoruz)
108
+ numeric_only = df.select_dtypes(include=['float64', 'int64'])
109
+ if 'cluster' in df.columns:
110
+ means = numeric_only.groupby(df['cluster']).mean()
111
+ st.dataframe(means, use_container_width=True)