Spaces:
Sleeping
Sleeping
Upload 3 files
Browse files
main.py
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
from urllib.parse import urlencode
|
3 |
+
from utils import *
|
4 |
+
import os
|
5 |
+
|
6 |
+
# Constants
|
7 |
+
CLIENT_ID = os.getenv("CLIENT_ID")
|
8 |
+
CLIENT_SECRET = os.getenv("CLIENT_SECRET")
|
9 |
+
REDIRECT_URI = "https://huggingface.co/spaces/Add1E/SpotifyHitPrediction"
|
10 |
+
AUTH_URL = "https://accounts.spotify.com/authorize"
|
11 |
+
TOKEN_URL = "https://accounts.spotify.com/api/token"
|
12 |
+
|
13 |
+
|
14 |
+
def get_track_audio_features(track_id, access_token):
|
15 |
+
endpoint = f"https://api.spotify.com/v1/audio-features/{track_id}"
|
16 |
+
headers = {
|
17 |
+
'Authorization': f'Bearer {access_token}',
|
18 |
+
}
|
19 |
+
response = requests.get(endpoint, headers=headers)
|
20 |
+
return response.json()
|
21 |
+
|
22 |
+
|
23 |
+
def get_track_information(track_id, access_token):
|
24 |
+
endpoint = f"https://api.spotify.com/v1/tracks/{track_id}"
|
25 |
+
headers = {
|
26 |
+
'Authorization': f'Bearer {access_token}',
|
27 |
+
}
|
28 |
+
response = requests.get(endpoint, headers=headers)
|
29 |
+
return response.json()
|
30 |
+
|
31 |
+
|
32 |
+
def extract_track_id_from_url(url):
|
33 |
+
# For a Spotify URL
|
34 |
+
if 'open.spotify.com' in url and '/track/' in url:
|
35 |
+
return url.split('track/')[1]
|
36 |
+
# For a Spotify URI
|
37 |
+
elif 'spotify:track:' in url:
|
38 |
+
return url.split(':')[-1]
|
39 |
+
else:
|
40 |
+
return None # Or handle invalid URL/URI appropriately
|
41 |
+
|
42 |
+
|
43 |
+
def app():
|
44 |
+
|
45 |
+
# Step 1: User Authorization
|
46 |
+
if st.session_state.get('code') is None:
|
47 |
+
auth_params = {
|
48 |
+
'client_id': CLIENT_ID,
|
49 |
+
'response_type': 'code',
|
50 |
+
'redirect_uri': REDIRECT_URI,
|
51 |
+
'scope': 'user-read-private', # Modify as per your required scopes
|
52 |
+
}
|
53 |
+
st.code(st.session_state)
|
54 |
+
st.write('Please log in to Spotify')
|
55 |
+
st.markdown(f"[Log In]({AUTH_URL}?{urlencode(auth_params)})", unsafe_allow_html=True)
|
56 |
+
else:#
|
57 |
+
# Step 2: Request Access Token
|
58 |
+
if 'access_token' not in st.session_state or (st.session_state['access_token'] is None):
|
59 |
+
auth_code = st.session_state['code']
|
60 |
+
|
61 |
+
token_data = {
|
62 |
+
'grant_type': 'authorization_code',
|
63 |
+
'code': auth_code,
|
64 |
+
'redirect_uri': REDIRECT_URI,
|
65 |
+
'client_id': CLIENT_ID,
|
66 |
+
'client_secret': CLIENT_SECRET,
|
67 |
+
}
|
68 |
+
token_r = requests.post(TOKEN_URL, data=token_data)
|
69 |
+
token_response = token_r.json()
|
70 |
+
st.session_state['access_token'] = token_response.get('access_token')
|
71 |
+
|
72 |
+
if 'access_token' in st.session_state:
|
73 |
+
st.write("Enter a Spotify Track URL or URI to get its audio features.")
|
74 |
+
track_input = st.text_input("Spotify Track URL/URI", "")
|
75 |
+
if st.button("Get Audio Features"):
|
76 |
+
track_id = extract_track_id_from_url(track_input)
|
77 |
+
if track_id:
|
78 |
+
audio_features = get_track_audio_features(track_id, st.session_state['access_token'])
|
79 |
+
features = [None] * 9
|
80 |
+
features[0] = audio_features["tempo"] # Beats per minute
|
81 |
+
features[1] = audio_features["energy"]
|
82 |
+
features[2] = audio_features["danceability"]
|
83 |
+
features[3] = audio_features["loudness"] # Loudness in dB
|
84 |
+
features[4] = audio_features["liveness"]
|
85 |
+
features[5] = audio_features["valence"]
|
86 |
+
features[6] = audio_features["duration_ms"] / 1000 # Umrechnung von Millisekunden in Sekunden
|
87 |
+
features[7] = audio_features["acousticness"]
|
88 |
+
features[8] = audio_features["speechiness"]
|
89 |
+
feature_display = {
|
90 |
+
"tempo": features[0],
|
91 |
+
"energy" : features[1],
|
92 |
+
"danceability":features[2],
|
93 |
+
"loudness":features[3],
|
94 |
+
"liveness":features[4],
|
95 |
+
"valence":features[5],
|
96 |
+
"duration_in_s":features[6],
|
97 |
+
"acousticness":features[7],
|
98 |
+
"speechiness":features[8]
|
99 |
+
}
|
100 |
+
st.write(feature_display)
|
101 |
+
predictions = predict_popularity(features)
|
102 |
+
st.write(f"Random Forest Prediction: {predictions[0]}")
|
103 |
+
st.write(f"Regression Prediction: {predictions[1]}")
|
104 |
+
|
105 |
+
else:
|
106 |
+
st.error("Please enter a valid Spotify Track URL or URI.")
|
107 |
+
if track_id:
|
108 |
+
track_info = get_track_information(track_id, st.session_state['access_token'])
|
109 |
+
if track_info:
|
110 |
+
st.write(f"Popularität: {track_info.get('popularity', 'Nicht verfügbar')}")
|
111 |
+
else:
|
112 |
+
st.write("Track-Informationen konnten nicht abgerufen werden.")
|
113 |
+
else:
|
114 |
+
st.write("Bitte geben Sie eine gültige Track-ID ein.")
|
115 |
+
|
116 |
+
if 'code' not in st.session_state:
|
117 |
+
query_params = st.experimental_get_query_params()
|
118 |
+
st.session_state['code'] = query_params.get('code', [None])[0]
|
119 |
+
|
120 |
+
app()
|
top50.csv
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"","Track.Name","Artist.Name","Genre","Beats.Per.Minute","Energy","Danceability","Loudness..dB..","Liveness","Valence.","Length.","Acousticness..","Speechiness.","Popularity"
|
2 |
+
"1","Se�orita","Shawn Mendes","canadian pop",117,55,76,-6,8,75,191,4,3,79
|
3 |
+
"2","China","Anuel AA","reggaeton flow",105,81,79,-4,8,61,302,8,9,92
|
4 |
+
"3","boyfriend (with Social House)","Ariana Grande","dance pop",190,80,40,-4,16,70,186,12,46,85
|
5 |
+
"4","Beautiful People (feat. Khalid)","Ed Sheeran","pop",93,65,64,-8,8,55,198,12,19,86
|
6 |
+
"5","Goodbyes (Feat. Young Thug)","Post Malone","dfw rap",150,65,58,-4,11,18,175,45,7,94
|
7 |
+
"6","I Don't Care (with Justin Bieber)","Ed Sheeran","pop",102,68,80,-5,9,84,220,9,4,84
|
8 |
+
"7","Ransom","Lil Tecca","trap music",180,64,75,-6,7,23,131,2,29,92
|
9 |
+
"8","How Do You Sleep?","Sam Smith","pop",111,68,48,-5,8,35,202,15,9,90
|
10 |
+
"9","Old Town Road - Remix","Lil Nas X","country rap",136,62,88,-6,11,64,157,5,10,87
|
11 |
+
"10","bad guy","Billie Eilish","electropop",135,43,70,-11,10,56,194,33,38,95
|
12 |
+
"11","Callaita","Bad Bunny","reggaeton",176,62,61,-5,24,24,251,60,31,93
|
13 |
+
"12","Loco Contigo (feat. J. Balvin & Tyga)","DJ Snake","dance pop",96,71,82,-4,15,38,185,28,7,86
|
14 |
+
"13","Someone You Loved","Lewis Capaldi","pop",110,41,50,-6,11,45,182,75,3,88
|
15 |
+
"14","Otro Trago - Remix","Sech","panamanian pop",176,79,73,-2,6,76,288,7,20,87
|
16 |
+
"15","Money In The Grave (Drake ft. Rick Ross)","Drake","canadian hip hop",101,50,83,-4,12,10,205,10,5,92
|
17 |
+
"16","No Guidance (feat. Drake)","Chris Brown","dance pop",93,45,70,-7,16,14,261,12,15,82
|
18 |
+
"17","LA CANCI�N","J Balvin","latin",176,65,75,-6,11,43,243,15,32,90
|
19 |
+
"18","Sunflower - Spider-Man: Into the Spider-Verse","Post Malone","dfw rap",90,48,76,-6,7,91,158,56,5,91
|
20 |
+
"19","Lalala","Y2K","canadian hip hop",130,39,84,-8,14,50,161,18,8,88
|
21 |
+
"20","Truth Hurts","Lizzo","escape room",158,62,72,-3,12,41,173,11,11,91
|
22 |
+
"21","Piece Of Your Heart","MEDUZA","pop house",124,74,68,-7,7,63,153,4,3,91
|
23 |
+
"22","Panini","Lil Nas X","country rap",154,59,70,-6,12,48,115,34,8,91
|
24 |
+
"23","No Me Conoce - Remix","Jhay Cortez","reggaeton flow",92,79,81,-4,9,58,309,14,7,83
|
25 |
+
"24","Soltera - Remix","Lunay","latin",92,78,80,-4,44,80,266,36,4,91
|
26 |
+
"25","bad guy (with Justin Bieber)","Billie Eilish","electropop",135,45,67,-11,12,68,195,25,30,89
|
27 |
+
"26","If I Can't Have You","Shawn Mendes","canadian pop",124,82,69,-4,13,87,191,49,6,70
|
28 |
+
"27","Dance Monkey","Tones and I","australian pop",98,59,82,-6,18,54,210,69,10,83
|
29 |
+
"28","It's You","Ali Gatie","canadian hip hop",96,46,73,-7,19,40,213,37,3,89
|
30 |
+
"29","Con Calma","Daddy Yankee","latin",94,86,74,-3,6,66,193,11,6,91
|
31 |
+
"30","QUE PRETENDES","J Balvin","latin",93,79,64,-4,36,94,222,3,25,89
|
32 |
+
"31","Takeaway","The Chainsmokers","edm",85,51,29,-8,10,36,210,12,4,84
|
33 |
+
"32","7 rings","Ariana Grande","dance pop",140,32,78,-11,9,33,179,59,33,89
|
34 |
+
"33","0.958333333333333","Maluma","reggaeton",96,71,78,-5,9,68,176,22,28,89
|
35 |
+
"34","The London (feat. J. Cole & Travis Scott)","Young Thug","atl hip hop",98,59,80,-7,13,18,200,2,15,89
|
36 |
+
"35","Never Really Over","Katy Perry","dance pop",100,88,77,-5,32,39,224,19,6,89
|
37 |
+
"36","Summer Days (feat. Macklemore & Patrick Stump of Fall Out Boy)","Martin Garrix","big room",114,72,66,-7,14,32,164,18,6,89
|
38 |
+
"37","Otro Trago","Sech","panamanian pop",176,70,75,-5,11,62,226,14,34,91
|
39 |
+
"38","Antisocial (with Travis Scott)","Ed Sheeran","pop",152,82,72,-5,36,91,162,13,5,87
|
40 |
+
"39","Sucker","Jonas Brothers","boy band",138,73,84,-5,11,95,181,4,6,80
|
41 |
+
"40","fuck, i'm lonely (with Anne-Marie) - from �13 Reasons Why: Season 3�","Lauv","dance pop",95,56,81,-6,6,68,199,48,7,78
|
42 |
+
"41","Higher Love","Kygo","edm",104,68,69,-7,10,40,228,2,3,88
|
43 |
+
"42","You Need To Calm Down","Taylor Swift","dance pop",85,68,77,-6,7,73,171,1,5,90
|
44 |
+
"43","Shallow","Lady Gaga","dance pop",96,39,57,-6,23,32,216,37,3,87
|
45 |
+
"44","Talk","Khalid","pop",136,40,90,-9,6,35,198,5,13,84
|
46 |
+
"45","Con Altura","ROSAL�A","r&b en espanol",98,69,88,-4,5,75,162,39,12,88
|
47 |
+
"46","One Thing Right","Marshmello","brostep",88,62,66,-2,58,44,182,7,5,88
|
48 |
+
"47","Te Robar�","Nicky Jam","latin",176,75,67,-4,8,80,202,24,6,88
|
49 |
+
"48","Happier","Marshmello","brostep",100,79,69,-3,17,67,214,19,5,88
|
50 |
+
"49","Call You Mine","The Chainsmokers","edm",104,70,59,-6,41,50,218,23,3,88
|
51 |
+
"50","Cross Me (feat. Chance the Rapper & PnB Rock)","Ed Sheeran","pop",95,79,75,-6,7,61,206,21,12,82
|
utils.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sklearn.model_selection import train_test_split
|
2 |
+
from sklearn.linear_model import LinearRegression
|
3 |
+
from sklearn.metrics import mean_squared_error, r2_score
|
4 |
+
from sklearn.ensemble import RandomForestRegressor
|
5 |
+
import pandas as pd
|
6 |
+
from tqdm.auto import tqdm
|
7 |
+
import streamlit as st
|
8 |
+
tqdm.pandas()
|
9 |
+
|
10 |
+
|
11 |
+
def predict_popularity(features):
|
12 |
+
predictions = [None] * 2
|
13 |
+
predictions[0], predictions[1] = rf_model.predict([features]), model.predict([features])
|
14 |
+
return predictions
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
|
19 |
+
data = pd.read_csv('top50.csv', encoding='ISO-8859-1')
|
20 |
+
print(data.head())
|
21 |
+
|
22 |
+
# Let's also describe the data to get a sense of the distributions
|
23 |
+
print(data.describe())
|
24 |
+
# Selecting the features and the target variable
|
25 |
+
X = data.drop(['Unnamed: 0', 'Track.Name', 'Artist.Name', 'Genre', 'Popularity'], axis=1)
|
26 |
+
y = data['Popularity']
|
27 |
+
|
28 |
+
# Splitting the data into training and testing sets
|
29 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
30 |
+
|
31 |
+
# Initializing the Linear Regression model
|
32 |
+
model = LinearRegression()
|
33 |
+
|
34 |
+
# Fitting the model
|
35 |
+
model.fit(X_train, y_train)
|
36 |
+
|
37 |
+
# Making predictions
|
38 |
+
y_pred = model.predict(X_test)
|
39 |
+
|
40 |
+
# Calculating the performance metrics
|
41 |
+
mse = mean_squared_error(y_test, y_pred)
|
42 |
+
r2 = r2_score(y_test, y_pred)
|
43 |
+
# Initialize the Random Forest Regressor
|
44 |
+
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
|
45 |
+
|
46 |
+
# Fitting the model
|
47 |
+
rf_model.fit(X_train, y_train)
|
48 |
+
|
49 |
+
# Making predictions
|
50 |
+
rf_pred = rf_model.predict(X_test)
|
51 |
+
|
52 |
+
# Calculating the performance metrics
|
53 |
+
rf_mse = mean_squared_error(y_test, rf_pred)
|
54 |
+
rf_r2 = r2_score(y_test, rf_pred)
|
55 |
+
|
56 |
+
|
57 |
+
# Feature importances
|
58 |
+
feature_importances = rf_model.feature_importances_
|
59 |
+
|
60 |
+
# Create a pandas series with feature importances
|
61 |
+
importances = pd.Series(feature_importances, index=X.columns)
|
62 |
+
|
63 |
+
# Sort the feature importances in descending order
|
64 |
+
sorted_importances = importances.sort_values(ascending=False)
|