Rutson commited on
Commit
b0b2ee4
·
verified ·
1 Parent(s): 457028c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -29
app.py CHANGED
@@ -2,59 +2,67 @@ import streamlit as st
2
  import pandas as pd
3
  from sklearn.preprocessing import StandardScaler
4
  from sklearn.neighbors import NearestNeighbors
5
- from thefuzz import process
6
 
7
- st.set_page_config(page_title="DNA Sonoro: Database Real", page_icon="🧬")
8
- st.title("🧬 DNA Sonoro: Modo Offline")
9
 
10
- # Função para carregar o arquivo que você subiu
11
  @st.cache_data
12
- def carregar_dados_locais():
13
- # Lendo o arquivo de 346MB que você acabou de subir
14
  df = pd.read_csv("tracks_features.csv")
15
- # Limpeza básica para não pesar na memória
16
  df = df[['name', 'artists', 'danceability', 'energy', 'acousticness', 'instrumentalness', 'valence', 'tempo']].dropna()
17
- df = df.drop_duplicates(subset=['name', 'artists'])
18
- df['search_info'] = df['name'].astype(str) + " " + df['artists'].astype(str)
 
19
  return df
20
 
21
  try:
22
- with st.spinner("Analisando 1.2M de faixas... Isso pode levar um minuto na primeira vez."):
23
- df = carregar_dados_locais()
24
-
25
- # Preparando o motor matemático
26
  features = ['danceability', 'energy', 'acousticness', 'instrumentalness', 'valence', 'tempo']
27
  scaler = StandardScaler()
28
  df_scaled = scaler.fit_transform(df[features])
29
-
30
- model = NearestNeighbors(n_neighbors=7, metric='cosine')
31
  model.fit(df_scaled)
32
 
33
- query = st.text_input("Busque sua B-side ou Artista:", placeholder="Ex: Spring Day, STAYC, Enhypen...")
 
 
 
 
 
34
 
35
- if query:
36
- # Busca aproximada na sua base gigante
37
- choices = df['search_info'].tolist()
38
- # Pegamos os top matches para ser mais preciso
39
- best_match = process.extractOne(query, choices)
40
 
41
- if best_match and best_match[1] > 65:
42
- idx = df[df['search_info'] == best_match[0]].index[0]
 
 
 
 
 
 
 
 
43
  track = df.iloc[idx]
 
44
 
45
- st.success(f"🎯 **Encontrei na Base:** {track['name']} — {track['artists']}")
46
-
47
  distances, indices = model.kneighbors([df_scaled[idx]])
48
 
49
- st.subheader("💡 Recomendações Técnicas:")
50
  for i in indices[0]:
51
  if i != idx:
52
  res = df.iloc[i]
53
  st.write(f"✨ **{res['name']}** — {res['artists']}")
54
  simil = int((1 - distances[0][list(indices[0]).index(i)]) * 100)
55
- st.caption(f"DNA compatível em {simil}%")
56
  else:
57
- st.warning("Ainda não encontrei. Tente o nome exato da música.")
58
 
59
  except Exception as e:
60
- st.error(f"Erro ao ler o arquivo: {e}")
 
2
  import pandas as pd
3
  from sklearn.preprocessing import StandardScaler
4
  from sklearn.neighbors import NearestNeighbors
 
5
 
6
+ st.set_page_config(page_title="DNA Sonoro: Filtro de Elite", page_icon="🧬")
7
+ st.title("🧬 DNA Sonoro: Precisão Máxima")
8
 
 
9
  @st.cache_data
10
+ def carregar_dados():
 
11
  df = pd.read_csv("tracks_features.csv")
12
+ # Mantendo apenas o essencial para não fritar a memória
13
  df = df[['name', 'artists', 'danceability', 'energy', 'acousticness', 'instrumentalness', 'valence', 'tempo']].dropna()
14
+ # Limpeza de strings para busca não falhar por causa de espaço ou letra maiúscula
15
+ df['name_clean'] = df['name'].str.lower().str.strip()
16
+ df['artists_clean'] = df['artists'].str.lower().str.strip()
17
  return df
18
 
19
  try:
20
+ df = carregar_dados()
21
+
22
+ # Motor matemático
 
23
  features = ['danceability', 'energy', 'acousticness', 'instrumentalness', 'valence', 'tempo']
24
  scaler = StandardScaler()
25
  df_scaled = scaler.fit_transform(df[features])
26
+ model = NearestNeighbors(n_neighbors=11, metric='cosine')
 
27
  model.fit(df_scaled)
28
 
29
+ st.markdown("### 🔎 Busca Refinada")
30
+ col1, col2 = st.columns(2)
31
+ with col1:
32
+ musica_input = st.text_input("Nome da música:", placeholder="Ex: Spring Day")
33
+ with col2:
34
+ artista_input = st.text_input("Nome do artista (Opcional):", placeholder="Ex: BTS")
35
 
36
+ if musica_input:
37
+ # Busca exata ou parcial mas rigorosa
38
+ termo_musica = musica_input.lower().strip()
39
+ termo_artista = artista_input.lower().strip() if artista_input else ""
 
40
 
41
+ # Filtro direto no DataFrame (mais rápido e preciso que o Fuzzy para 1M de linhas)
42
+ if termo_artista:
43
+ match = df[(df['name_clean'].str.contains(termo_musica)) & (df['artists_clean'].str.contains(termo_artista))]
44
+ else:
45
+ match = df[df['name_clean'] == termo_musica]
46
+ if match.empty:
47
+ match = df[df['name_clean'].str.contains(termo_musica)].head(1)
48
+
49
+ if not match.empty:
50
+ idx = match.index[0]
51
  track = df.iloc[idx]
52
+ st.success(f"🎯 **Identificada:** {track['name']} — {track['artists']}")
53
 
54
+ # Cálculo da vibe
 
55
  distances, indices = model.kneighbors([df_scaled[idx]])
56
 
57
+ st.subheader("💡 Recomendações com DNA idêntico:")
58
  for i in indices[0]:
59
  if i != idx:
60
  res = df.iloc[i]
61
  st.write(f"✨ **{res['name']}** — {res['artists']}")
62
  simil = int((1 - distances[0][list(indices[0]).index(i)]) * 100)
63
+ st.caption(f"Compatibilidade: {simil}%")
64
  else:
65
+ st.error("Não achei essa combinação na base. Tente apenas uma palavra-chave da música.")
66
 
67
  except Exception as e:
68
+ st.error(f"Erro no motor: {e}")