| import streamlit as st |
| import pandas as pd |
| from sklearn.preprocessing import StandardScaler |
| from sklearn.neighbors import NearestNeighbors |
|
|
| st.set_page_config(page_title="DNA Sonoro: Filtro de Elite", page_icon="🧬") |
| st.title("🧬 DNA Sonoro: Precisão Máxima") |
|
|
| @st.cache_data |
| def carregar_dados(): |
| df = pd.read_csv("tracks_features.csv") |
| |
| df = df[['name', 'artists', 'danceability', 'energy', 'acousticness', 'instrumentalness', 'valence', 'tempo']].dropna() |
| |
| df['name_clean'] = df['name'].str.lower().str.strip() |
| df['artists_clean'] = df['artists'].str.lower().str.strip() |
| return df |
|
|
| try: |
| df = carregar_dados() |
| |
| |
| features = ['danceability', 'energy', 'acousticness', 'instrumentalness', 'valence', 'tempo'] |
| scaler = StandardScaler() |
| df_scaled = scaler.fit_transform(df[features]) |
| model = NearestNeighbors(n_neighbors=11, metric='cosine') |
| model.fit(df_scaled) |
|
|
| st.markdown("### 🔎 Busca Refinada") |
| col1, col2 = st.columns(2) |
| with col1: |
| musica_input = st.text_input("Nome da música:", placeholder="Ex: Spring Day") |
| with col2: |
| artista_input = st.text_input("Nome do artista (Opcional):", placeholder="Ex: BTS") |
|
|
| if musica_input: |
| |
| termo_musica = musica_input.lower().strip() |
| termo_artista = artista_input.lower().strip() if artista_input else "" |
| |
| |
| if termo_artista: |
| match = df[(df['name_clean'].str.contains(termo_musica)) & (df['artists_clean'].str.contains(termo_artista))] |
| else: |
| match = df[df['name_clean'] == termo_musica] |
| if match.empty: |
| match = df[df['name_clean'].str.contains(termo_musica)].head(1) |
|
|
| if not match.empty: |
| idx = match.index[0] |
| track = df.iloc[idx] |
| st.success(f"🎯 **Identificada:** {track['name']} — {track['artists']}") |
| |
| |
| distances, indices = model.kneighbors([df_scaled[idx]]) |
| |
| st.subheader("💡 Recomendações com DNA idêntico:") |
| for i in indices[0]: |
| if i != idx: |
| res = df.iloc[i] |
| st.write(f"✨ **{res['name']}** — {res['artists']}") |
| simil = int((1 - distances[0][list(indices[0]).index(i)]) * 100) |
| st.caption(f"Compatibilidade: {simil}%") |
| else: |
| st.error("Não achei essa combinação na base. Tente apenas uma palavra-chave da música.") |
|
|
| except Exception as e: |
| st.error(f"Erro no motor: {e}") |