Spaces:
Sleeping
Sleeping
Upload 15 files
Browse files- .gitattributes +1 -0
- Explanations/__pycache__/llama2.cpython-311.pyc +0 -0
- Explanations/__pycache__/mistral.cpython-311.pyc +0 -0
- Explanations/explainer.py +50 -0
- Explanations/llama2.py +194 -0
- Explanations/mistral.py +299 -0
- data/new_tracks.csv +184 -0
- data/sc.sav +0 -0
- data/streamlit.csv +3 -0
- main.py +436 -0
- model.py +606 -0
- requirements.txt +11 -0
- spotify_get_artist_url.png +0 -0
- spotify_get_playlist_url.png +0 -0
- spotify_get_song_url.png +0 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
data/streamlit.csv filter=lfs diff=lfs merge=lfs -text
|
Explanations/__pycache__/llama2.cpython-311.pyc
ADDED
Binary file (14 kB). View file
|
|
Explanations/__pycache__/mistral.cpython-311.pyc
ADDED
Binary file (21.1 kB). View file
|
|
Explanations/explainer.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
|
3 |
+
import mistral as Mistral
|
4 |
+
|
5 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
6 |
+
|
7 |
+
song = ["\"And We Run (feat. Xzibit)\" by Within Temptation and Xzibit"]
|
8 |
+
top_ten = [
|
9 |
+
"\"Angels\" by Within Temptation",
|
10 |
+
"\"Stand My Ground\" by Within Temptation",
|
11 |
+
"\"The Gathering\" by Delain",
|
12 |
+
"\"April Rain\" by Delain",
|
13 |
+
"\"Strange Machines\" by The Gathering",
|
14 |
+
"\"We Are the Others\" by Delain",
|
15 |
+
"\"See Me In Shadow\" by Delain",
|
16 |
+
"\"Leaves\" by The Gathering",
|
17 |
+
"\"Saturnine\" by The Gathering",
|
18 |
+
"\"Frozen\" by Delain"
|
19 |
+
]
|
20 |
+
next_ten = [
|
21 |
+
"\'No More\" by Nemesea",
|
22 |
+
"\"Eleanor\" by The Gathering",
|
23 |
+
"\"In Motion #1\" by The Gathering",
|
24 |
+
"\"The Evil that Men Do - Remastered\" by After Forever",
|
25 |
+
"\"In Control\" by Nemesea",
|
26 |
+
"\"Allein - Bonus Track\" by Nemasea",
|
27 |
+
"\"Colder\" by End of the Dream",
|
28 |
+
"\"Summertime Sadness\" by Within Temptation",
|
29 |
+
"\"Sinéad - Benno de Goeij Remix\" by Within Temptation and Benno De Goeij",
|
30 |
+
"\"Sinéad - Alex M.O.R.P.H. Radio Edit\" by Within Temptation and Alex M.O.R.P.H"
|
31 |
+
]
|
32 |
+
selected = [
|
33 |
+
"\"Take Me Home, Country Roads\" by John Denver",
|
34 |
+
"\"Take On Me\" by a-ha",
|
35 |
+
"\"Africa\" by Toto"
|
36 |
+
]
|
37 |
+
|
38 |
+
if __name__ == '__main__':
|
39 |
+
me = Mistral.MistralExplainer(device)
|
40 |
+
print("\n#=#=#=#=#=#\n")
|
41 |
+
me.explain_why(song, top_ten)
|
42 |
+
print(me.get_positive_explanations())
|
43 |
+
print("\n#=#=#=#=#=#\n")
|
44 |
+
me.explain_why_these_arent_top(song, top_ten, next_ten)
|
45 |
+
print(me.get_constrastive_explanations())
|
46 |
+
print("\n#=#=#=#=#=#\n")
|
47 |
+
me.explain_why_not_these_songs(song, top_ten, selected)
|
48 |
+
print(me.get_other_constrastive_explanations())
|
49 |
+
print("\n#=#=#=#=#=#\n")
|
50 |
+
##
|
Explanations/llama2.py
ADDED
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
2 |
+
import transformers
|
3 |
+
import torch
|
4 |
+
|
5 |
+
class Llama2Explainer():
|
6 |
+
def __init__(self, device) -> None:
|
7 |
+
self.__model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-chat-hf")
|
8 |
+
self.__tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat-hf")
|
9 |
+
self.__device = device
|
10 |
+
|
11 |
+
self.__results = {"pos_explain":None, "top_contrastive":None, "other_contrastive":None}
|
12 |
+
|
13 |
+
self.__pipeline = transformers.pipeline(
|
14 |
+
"text-generation",
|
15 |
+
self.__model,
|
16 |
+
torch_dtype=torch.float16,
|
17 |
+
device_map="auto",
|
18 |
+
)
|
19 |
+
##
|
20 |
+
|
21 |
+
def explain_why(self, original_songs, top_songs, explanation_limit=1):
|
22 |
+
ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0]
|
23 |
+
top10 = ' ,'.join(top_songs)
|
24 |
+
|
25 |
+
song = "song" if len(original_songs) == 1 else "songs"
|
26 |
+
was = "was" if len(original_songs) == 1 else "were"
|
27 |
+
sentence = "sentence" if explanation_limit == 1 else "sentences"
|
28 |
+
|
29 |
+
prompt = "<s>[INST] <<SYS>>\n" +\
|
30 |
+
"You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +\
|
31 |
+
"Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +\
|
32 |
+
"You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +\
|
33 |
+
f"songs. You should explain why each of the songs was chosen to the best of your ability in the order they appear in {explanation_limit} {sentence} per song.\n" +\
|
34 |
+
+ "</s><s>" +\
|
35 |
+
"[INST]" +\
|
36 |
+
"The song that was selected was \"One More Time\" by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +\
|
37 |
+
"\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +\
|
38 |
+
"\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +\
|
39 |
+
"\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n" +\
|
40 |
+
"[/INST]" +\
|
41 |
+
"[1]\"Get Lucky\" by Daft Punk was recommended as a song as \"Get Lucky\" comes from the same album as \"One More Time,\" and is by the same artist.\n" +\
|
42 |
+
"[2]\"Instant Crush\" by Daft Punk & Julian Casablancas was recommended because Daft Punk was also an artist on the song, and is in the same genre.\n" +\
|
43 |
+
"[3]\"Harder, Better, Faster, Stronger\" by Daft Punk was recommended as a song asit comes from the same album as \"One More Time,\" and is by the " +\
|
44 |
+
"same artist.\n" +\
|
45 |
+
"[4]\"Around the World\" by Daft Punk was recommended as a song asit comes from the same album as \"One More Time,\" and is by the " +\
|
46 |
+
"same artist.\n" +\
|
47 |
+
"[5]\"Je veux te void\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\
|
48 |
+
"Daft Punk, and was inspired by Daft Punk.\n" +\
|
49 |
+
"[6]\"Ce jeu\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\
|
50 |
+
"Daft Punk, and was inspired by Daft Punk.\n" +\
|
51 |
+
"[7]\"Complètement fou\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\
|
52 |
+
"Daft Punk, and was inspired by Daft Punk.\n" +\
|
53 |
+
"[8]\"À cause des garçons\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\
|
54 |
+
"Daft Punk, and was inspired by Daft Punk.\n" +\
|
55 |
+
"[9]\"Tristesse / joie\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\
|
56 |
+
"Daft Punk, and was inspired by Daft Punk.\n" +\
|
57 |
+
"[10]\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra was recommended because YELLOW MAGIC ORCHESTRA is a band in the same genre" +\
|
58 |
+
" of music as Daft Punk and served as the duo's inspiration.\n" +\
|
59 |
+
+ "</s><s>" +\
|
60 |
+
"[INST]" + f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n." + "[/INST]"
|
61 |
+
|
62 |
+
sequences = self.__pipeline(
|
63 |
+
prompt,
|
64 |
+
do_sample=True,
|
65 |
+
eos_token_id=self.__tokenizer.eos_token_id,
|
66 |
+
max_length=1024,
|
67 |
+
)
|
68 |
+
|
69 |
+
self.__results["pos_explain"] = sequences[0]['generated_text'].split("/INST] ")[-1]
|
70 |
+
##
|
71 |
+
|
72 |
+
def explain_why_not_these_songs(self, original_songs, selected_songs, other_songs, explanation_limit=1):
|
73 |
+
ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0]
|
74 |
+
top10 = ' ,'.join(selected_songs)
|
75 |
+
next10 = ' ,'.join(other_songs)
|
76 |
+
|
77 |
+
song = "song" if len(original_songs) == 1 else "songs"
|
78 |
+
song2 = "song" if len(other_songs) == 1 else "songs"
|
79 |
+
was = "was" if len(original_songs) == 1 else "were"
|
80 |
+
sentence = "sentence" if explanation_limit == 1 else "sentences"
|
81 |
+
|
82 |
+
prompt = "<s>[INST] <<SYS>>\n" +\
|
83 |
+
"You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +\
|
84 |
+
"Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +\
|
85 |
+
"You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +\
|
86 |
+
f"songs. You should explain why each of the songs was chosen to the best of your ability in the order they appear in {explanation_limit} {sentence} per song.\n" +\
|
87 |
+
+ "</s><s>" +\
|
88 |
+
"[INST]" +\
|
89 |
+
"The song that was selected was “One More Time” by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +\
|
90 |
+
"\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +\
|
91 |
+
"\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +\
|
92 |
+
"\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n" +\
|
93 |
+
"The following songs were not recommended: \"False Kings\" by Poets of the Fall, " + "\"Day Seven: Hope\" by Ayreon, " +\
|
94 |
+
"\"9 väärää kättä\" by Apulanta, K-Magg, " + "\"Simple and Clean\" by Hikaru Utada." +\
|
95 |
+
"[/INST]" +\
|
96 |
+
"[1] \"Technopolis - Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra was recommended because YELLOW MAGIC ORCHESTRA " +\
|
97 |
+
"is a band that influenced Daft Punk\'s work. Based on your song selection, we chose to recommend more songs " +\
|
98 |
+
"like Daft Punk instead of work that may be inspired by the work of Daft Punk.\n" +\
|
99 |
+
"[2] \"I Wanna Be Yours\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +\
|
100 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\
|
101 |
+
"[3] \"Thunder\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated with alt-rock than electronic music, " +\
|
102 |
+
"so they were selected to be lower on the list.\n" +\
|
103 |
+
"[4] \"Why\'d You Only Call Me When You\'re High?\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +\
|
104 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\
|
105 |
+
"[5] \"Do I Wanna Know?\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +\
|
106 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\
|
107 |
+
"[6] \"Believer\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated with alt-rock than electronic music, " +\
|
108 |
+
"so they were selected to be lower on the list.\n" +\
|
109 |
+
"[7] \"The Less I Know The Better\" by Tame Impala was selected as Tame Impala are associated with electronic-rock genres. They use a mix of rock and electronic instruments throughout "+\
|
110 |
+
"their music. Since they also use a rock genre, and Daft Punk is more electronic, they were recommended lower on the list.\n" +\
|
111 |
+
"[8] \"Stressed Out\" by Twenty One Pilots as Twenty One Pilots are associated with electronic-rock genres. They use a mix of rock and electronic instruments throughout "+\
|
112 |
+
"their music. Since they also use a rock genre, and Daft Punk is more electronic, they were recommended lower on the list." +\
|
113 |
+
"[9] \"505\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +\
|
114 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\
|
115 |
+
"[10] \"Natural\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated " +\
|
116 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\
|
117 |
+
+ "</s><s>" +\
|
118 |
+
"[INST]" + f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n. The following {song2} were not recommended: " +\
|
119 |
+
f"{next10}\n" + "[/INST]"
|
120 |
+
|
121 |
+
sequences = self.__pipeline(
|
122 |
+
prompt,
|
123 |
+
do_sample=True,
|
124 |
+
eos_token_id=self.__tokenizer.eos_token_id,
|
125 |
+
max_length=1024,
|
126 |
+
)
|
127 |
+
|
128 |
+
self.__results["top_constrastive"] = sequences[0]['generated_text'].split("/INST] ")[-1]
|
129 |
+
##
|
130 |
+
|
131 |
+
def explain_why_not_these_songs(self, original_songs, selected_songs, other_songs, explanation_limit=1):
|
132 |
+
ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0]
|
133 |
+
top10 = ' ,'.join(selected_songs)
|
134 |
+
others = ' ,'.join(other_songs)
|
135 |
+
|
136 |
+
song = "song" if len(original_songs) == 1 else "songs"
|
137 |
+
song2 = "song" if len(other_songs) == 1 else "songs"
|
138 |
+
was = "was" if len(original_songs) == 1 else "were"
|
139 |
+
sentence = "sentence" if explanation_limit == 1 else "sentences"
|
140 |
+
|
141 |
+
prompt = "<s>[INST] <<SYS>>\n" +\
|
142 |
+
"You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +\
|
143 |
+
"Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +\
|
144 |
+
"You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +\
|
145 |
+
f"songs. You should explain why each of the songs was chosen to the best of your ability in the order they appear in {explanation_limit} {sentence} per song.\n" +\
|
146 |
+
+ "</s><s>" +\
|
147 |
+
"[INST]" +\
|
148 |
+
"The song that was selected was “One More Time” by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +\
|
149 |
+
"\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +\
|
150 |
+
"\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +\
|
151 |
+
"\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n" +\
|
152 |
+
"The following songs were not recommended: \"False Kings\" by Poets of the Fall, " + "\"Day Seven: Hope\" by Ayreon, " +\
|
153 |
+
"\"9 väärää kättä\" by Apulanta, K-Magg, " + "\"Simple and Clean\" by Hikaru Utada." +\
|
154 |
+
"[/INST]" +\
|
155 |
+
"[1]\"False Kings\" by Poets of the Fall wasn't recommended as the genres are not similar. They are also from different nations, as " +\
|
156 |
+
"Daft Punk is from France and Poets of the Fall is from Finland. Their core inspirations are also different.\n" +\
|
157 |
+
"[2]\"Day Seven: Hope\" by Ayreon wasn't recommended as the genres do not align. Ayreon is a heavy metal group while Daft Punk is an " +\
|
158 |
+
"electronic group.\n" +\
|
159 |
+
"[3]\"9 väärää kättä\" by Apulanta, K-Magg wasn't recommended as the song is entirely sung in Finnish, where as Daft Punk typically " +\
|
160 |
+
"features English vocals or melodic beats only.\n"+\
|
161 |
+
"[4]\"Simple and Clean\" by Hikaru Utada was not recommended as the genres do not align. Simple and Clean is a J-Pop song, while " +\
|
162 |
+
"\"One More Time\" is an electronic song." +\
|
163 |
+
+ "</s><s>" +\
|
164 |
+
"[INST]" + f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n. The following {song2} were not recommended: " +\
|
165 |
+
f"{others}\n" + "[/INST]"
|
166 |
+
|
167 |
+
sequences = self.__pipeline(
|
168 |
+
prompt,
|
169 |
+
do_sample=True,
|
170 |
+
eos_token_id=self.__tokenizer.eos_token_id,
|
171 |
+
max_length=1024,
|
172 |
+
)
|
173 |
+
|
174 |
+
self.__results["other_constrastive"] = sequences[0]['generated_text'].split("/INST] ")[-1]
|
175 |
+
##
|
176 |
+
|
177 |
+
def get_constrastive_explanations(self):
|
178 |
+
if self.__results["top_contrastive"] is None:
|
179 |
+
return "Run the explainer first!"
|
180 |
+
return self.__results["top_contrastive"]
|
181 |
+
##
|
182 |
+
|
183 |
+
def get_other_constrastive_explanations(self):
|
184 |
+
if self.__results["other_contrastive"] is None:
|
185 |
+
return "Run the explainer first!"
|
186 |
+
return self.__results["other_contrastive"]
|
187 |
+
##
|
188 |
+
|
189 |
+
def get_positive_explanations(self):
|
190 |
+
if self.__results["pos_explain"] is None:
|
191 |
+
return "Run the explainer first!"
|
192 |
+
return self.__results["pos_explain"]
|
193 |
+
##
|
194 |
+
##
|
Explanations/mistral.py
ADDED
@@ -0,0 +1,299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
2 |
+
|
3 |
+
class MistralExplainer():
|
4 |
+
def __init__(self, device) -> None:
|
5 |
+
self.__model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.1")
|
6 |
+
self.__tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.1")
|
7 |
+
self.__device = device
|
8 |
+
|
9 |
+
self.__results = {"pos_explain":None, "top_contrastive":None, "other_contrastive":None}
|
10 |
+
##
|
11 |
+
|
12 |
+
def explain_why(self, original_songs, top_songs, explanation_limit=1):
|
13 |
+
# ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0]
|
14 |
+
# top10 = ' ,'.join(top_songs)
|
15 |
+
ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0]
|
16 |
+
|
17 |
+
formatted_string = ""
|
18 |
+
for item in top_songs:
|
19 |
+
formatted_string += '{} by {}, '.format(item['track_name'], item['artist_name'])
|
20 |
+
|
21 |
+
formatted_string = formatted_string.rstrip(', ')
|
22 |
+
top10 = formatted_string
|
23 |
+
|
24 |
+
formatted_string = ""
|
25 |
+
for item in original_songs:
|
26 |
+
formatted_string += '{} by {}, '.format(item['track_name'], item['artist_name'])
|
27 |
+
|
28 |
+
ss_str = formatted_string.rstrip(', ')
|
29 |
+
|
30 |
+
song = "song" if len(original_songs) == 1 else "songs"
|
31 |
+
was = "was" if len(original_songs) == 1 else "were"
|
32 |
+
sentence = "sentence" if explanation_limit == 1 else "sentences"
|
33 |
+
|
34 |
+
# Hey Minstral -- why were these songs recommended to me?
|
35 |
+
positive_analysis = [
|
36 |
+
{
|
37 |
+
"role": "user",
|
38 |
+
"content": "You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +
|
39 |
+
"Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +
|
40 |
+
"You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +
|
41 |
+
f"songs. You should explain why each of the songs was chosen to the best of your ability in the order they appear in {explanation_limit} {sentence} per song.\n" +
|
42 |
+
"The song that was selected was \"One More Time\" by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +
|
43 |
+
"\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +
|
44 |
+
"\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +
|
45 |
+
"\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n"
|
46 |
+
},
|
47 |
+
{
|
48 |
+
"role": "assistant",
|
49 |
+
"content": "[1]\"Get Lucky\" by Daft Punk was recommended as a song as \"Get Lucky\" comes from the same album as \"One More Time,\" and is by the same artist.\n" +
|
50 |
+
"[2]\"Instant Crush\" by Daft Punk & Julian Casablancas was recommended because Daft Punk was also an artist on the song, and is in the same genre.\n" +
|
51 |
+
"[3]\"Harder, Better, Faster, Stronger\" by Daft Punk was recommended as a song asit comes from the same album as \"One More Time,\" and is by the " +
|
52 |
+
"same artist.\n" +
|
53 |
+
"[4]\"Around the World\" by Daft Punk was recommended as a song asit comes from the same album as \"One More Time,\" and is by the " +
|
54 |
+
"same artist.\n" +
|
55 |
+
"[5]\"Je veux te void\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as "
|
56 |
+
+ "Daft Punk, and was inspired by Daft Punk.\n" +
|
57 |
+
"[6]\"Ce jeu\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as "
|
58 |
+
+ "Daft Punk, and was inspired by Daft Punk.\n" +
|
59 |
+
"[7]\"Complètement fou\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as "
|
60 |
+
+ "Daft Punk, and was inspired by Daft Punk.\n" +
|
61 |
+
"[8]\"À cause des garçons\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as "
|
62 |
+
+ "Daft Punk, and was inspired by Daft Punk.\n" +
|
63 |
+
"[9]\"Tristesse / joie\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as "
|
64 |
+
+ "Daft Punk, and was inspired by Daft Punk.\n" +
|
65 |
+
"[10]\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra was recommended because YELLOW MAGIC ORCHESTRA is a band in the same genre" +
|
66 |
+
" of music as Daft Punk and served as the duo's inspiration.\n"
|
67 |
+
},
|
68 |
+
{
|
69 |
+
"role": "user",
|
70 |
+
"content": f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n."
|
71 |
+
},
|
72 |
+
{
|
73 |
+
"role":"assistant",
|
74 |
+
"content":""
|
75 |
+
}
|
76 |
+
]
|
77 |
+
|
78 |
+
print("Encoding...")
|
79 |
+
encodeds = self.__tokenizer.apply_chat_template(positive_analysis, return_tensors="pt")
|
80 |
+
|
81 |
+
print("Transfering to model inputs...")
|
82 |
+
model_inputs = encodeds.to(self.__device)
|
83 |
+
print("Bringing it to the device...")
|
84 |
+
self.__model.to(self.__device)
|
85 |
+
|
86 |
+
print("Generating ids from the inputs...")
|
87 |
+
generated_ids = self.__model.generate(model_inputs, max_new_tokens=1000, do_sample=True)
|
88 |
+
|
89 |
+
print("Decoding...")
|
90 |
+
decoded = self.__tokenizer.batch_decode(generated_ids)
|
91 |
+
|
92 |
+
self.__results["pos_explain"] = decoded[0].split("[/INST]")[-1].replace("</s>", "").replace("\"", "").replace("\n", "").split(',')
|
93 |
+
print("=== Finished the positive explanations! ===")
|
94 |
+
##
|
95 |
+
|
96 |
+
def explain_why_these_arent_top(self, original_songs, top_songs, other_songs, explanation_limit=1):
|
97 |
+
ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0]
|
98 |
+
top10 = ' ,'.join(top_songs)
|
99 |
+
next10 = ' ,'.join(other_songs)
|
100 |
+
|
101 |
+
song = "song" if len(original_songs) == 1 else "songs"
|
102 |
+
was = "was" if len(original_songs) == 1 else "were"
|
103 |
+
sentence = "sentence" if explanation_limit == 1 else "sentences"
|
104 |
+
|
105 |
+
# Hey Minstral -- why were these songs not the top ten songs?
|
106 |
+
messages = [
|
107 |
+
{
|
108 |
+
"role": "user",
|
109 |
+
"content": "You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +
|
110 |
+
"Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +
|
111 |
+
"You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +
|
112 |
+
"songs. You will then be given 10 more recommended songs that ranked lower than the top 10 list. You must respond to each of the songs in the order they " +
|
113 |
+
f"appear in an enumerated list. You are limited to {explanation_limit} {sentence} per song.\n" +
|
114 |
+
"The song that was selected was “One More Time” by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +
|
115 |
+
"\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +
|
116 |
+
"\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +
|
117 |
+
"\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n" +
|
118 |
+
"The following songs were ranked lower than the top 10: \"Technopolis - Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra, " +
|
119 |
+
"\"I Wanna Be Yours\" by Arctic Monkeys, \"Thunder\" by Imagine Dragons, \"Why\'d You Only Call Me When You\'re High?\" by Arctic Monkeys, "+
|
120 |
+
"\"Do I Wanna Know?\" by Arctic Monkeys, \"Believer\" by Imagine Dragons, \"The Less I Know The Better\" by Tame Impala, \"Stressed Out\" by Twenty One Pilots, "+
|
121 |
+
"\"505\" by Arctic Monkeys, \"Natural\" by Imagine Dragons."
|
122 |
+
},
|
123 |
+
{
|
124 |
+
"role": "assistant",
|
125 |
+
"content": "[1] \"Technopolis - Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra was recommended because YELLOW MAGIC ORCHESTRA " +
|
126 |
+
"is a band that influenced Daft Punk\'s work. Based on your song selection, we chose to recommend more songs " +
|
127 |
+
"like Daft Punk instead of work that may be inspired by the work of Daft Punk.\n" +
|
128 |
+
"[2] \"I Wanna Be Yours\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +
|
129 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +
|
130 |
+
"[3] \"Thunder\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated with alt-rock than electronic music, " +
|
131 |
+
"so they were selected to be lower on the list.\n" +
|
132 |
+
"[4] \"Why\'d You Only Call Me When You\'re High?\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +
|
133 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +
|
134 |
+
"[5] \"Do I Wanna Know?\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +
|
135 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +
|
136 |
+
"[6] \"Believer\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated with alt-rock than electronic music, " +
|
137 |
+
"so they were selected to be lower on the list.\n" +
|
138 |
+
"[7] \"The Less I Know The Better\" by Tame Impala was selected as Tame Impala are associated with electronic-rock genres. They use a mix of rock and electronic instruments throughout "+
|
139 |
+
"their music. Since they also use a rock genre, and Daft Punk is more electronic, they were recommended lower on the list.\n" +
|
140 |
+
"[8] \"Stressed Out\" by Twenty One Pilots as Twenty One Pilots are associated with electronic-rock genres. They use a mix of rock and electronic instruments throughout "+
|
141 |
+
"their music. Since they also use a rock genre, and Daft Punk is more electronic, they were recommended lower on the list." +
|
142 |
+
"[9] \"505\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +
|
143 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n" +
|
144 |
+
"[10] \"Natural\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated " +
|
145 |
+
" with alt-rock than electronic music, so they were selected to be lower on the list.\n"
|
146 |
+
},
|
147 |
+
{
|
148 |
+
"role": "user",
|
149 |
+
"content": f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n. The following " +
|
150 |
+
f"songs were ranked lower than the top 10: {next10}"
|
151 |
+
},
|
152 |
+
{
|
153 |
+
"role":"assistant",
|
154 |
+
"content":""
|
155 |
+
}
|
156 |
+
]
|
157 |
+
|
158 |
+
print("Encoding...")
|
159 |
+
encodeds = self.__tokenizer.apply_chat_template(messages, return_tensors="pt")
|
160 |
+
|
161 |
+
print("Transfering to model inputs...")
|
162 |
+
model_inputs = encodeds.to(self.__device)
|
163 |
+
print("Bringing it to the device...")
|
164 |
+
self.__model.to(self.__device)
|
165 |
+
|
166 |
+
print("Generating ids from the inputs...")
|
167 |
+
generated_ids = self.__model.generate(model_inputs, max_new_tokens=1000, do_sample=True)
|
168 |
+
|
169 |
+
print("Decoding...")
|
170 |
+
decoded = self.__tokenizer.batch_decode(generated_ids)
|
171 |
+
|
172 |
+
self.__results["top_contrastive"] = decoded[0].split("[/INST]")[-1].replace("</s>", "").replace("\"", "").replace("\n", "").split(',')
|
173 |
+
##
|
174 |
+
|
175 |
+
def explain_why_not_these_songs(self, original_songs, selected_songs, other_songs, explanation_limit=1):
|
176 |
+
ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0]
|
177 |
+
top10 = ' ,'.join(selected_songs)
|
178 |
+
others = ' ,'.join(other_songs)
|
179 |
+
|
180 |
+
song = "song" if len(original_songs) == 1 else "songs"
|
181 |
+
song2 = "song" if len(other_songs) == 1 else "songs"
|
182 |
+
was = "was" if len(original_songs) == 1 else "were"
|
183 |
+
sentence = "sentence" if explanation_limit == 1 else "sentences"
|
184 |
+
|
185 |
+
# Hey Minstral -- why were these songs not recommended?
|
186 |
+
messages = [
|
187 |
+
{
|
188 |
+
"role": "user",
|
189 |
+
"content": "You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +
|
190 |
+
"Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +
|
191 |
+
"You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +
|
192 |
+
"songs. You will then be given a number of songs that were not part of the top recommendations. You must respond to each of the songs in the order they " +
|
193 |
+
f"appear in an enumerated list. You are limited to {explanation_limit} {sentence} per song.\n" +
|
194 |
+
"The song that was selected was “One More Time” by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +
|
195 |
+
"\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +
|
196 |
+
"\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +
|
197 |
+
"\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n" +
|
198 |
+
"The following songs were not recommended: \"False Kings\" by Poets of the Fall, " + "\"Day Seven: Hope\" by Ayreon, " +
|
199 |
+
"\"9 väärää kättä\" by Apulanta, K-Magg, " + "\"Simple and Clean\" by Hikaru Utada."
|
200 |
+
},
|
201 |
+
{
|
202 |
+
"role": "assistant",
|
203 |
+
"content": "[1]\"False Kings\" by Poets of the Fall wasn't recommended as the genres are not similar. They are also from different nations, as " +
|
204 |
+
"Daft Punk is from France and Poets of the Fall is from Finland. Their core inspirations are also different.\n" +
|
205 |
+
"[2]\"Day Seven: Hope\" by Ayreon wasn't recommended as the genres do not align. Ayreon is a heavy metal group while Daft Punk is an " +
|
206 |
+
"electronic group.\n"+
|
207 |
+
"[3]\"9 väärää kättä\" by Apulanta, K-Magg wasn't recommended as the song is entirely sung in Finnish, where as Daft Punk typically "+
|
208 |
+
"features English vocals or melodic beats only.\n"+
|
209 |
+
"[4]\"Simple and Clean\" by Hikaru Utada was not recommended as the genres do not align. Simple and Clean is a J-Pop song, while "+
|
210 |
+
"\"One More Time\" is an electronic song."
|
211 |
+
},
|
212 |
+
{
|
213 |
+
"role": "user",
|
214 |
+
"content": f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n. The following " +
|
215 |
+
f"{song2} were not recommended: {others}"
|
216 |
+
},
|
217 |
+
{
|
218 |
+
"role":"assistant",
|
219 |
+
"content":""
|
220 |
+
}
|
221 |
+
]
|
222 |
+
|
223 |
+
print("Encoding...")
|
224 |
+
encodeds = self.__tokenizer.apply_chat_template(messages, return_tensors="pt")
|
225 |
+
|
226 |
+
print("Transfering to model inputs...")
|
227 |
+
model_inputs = encodeds.to(self.__device)
|
228 |
+
print("Bringing it to the device...")
|
229 |
+
self.__model.to(self.__device)
|
230 |
+
|
231 |
+
print("Generating ids from the inputs...")
|
232 |
+
generated_ids = self.__model.generate(model_inputs, max_new_tokens=1000, do_sample=True)
|
233 |
+
|
234 |
+
print("Decoding...")
|
235 |
+
decoded = self.__tokenizer.batch_decode(generated_ids)
|
236 |
+
|
237 |
+
self.__results["other_contrastive"] = decoded[0].split("[/INST]")[-1].replace("</s>", "").replace("\"", "").replace("\n", "").split(',')
|
238 |
+
##
|
239 |
+
|
240 |
+
def get_constrastive_explanations(self):
|
241 |
+
if self.__results["top_contrastive"] is None:
|
242 |
+
return "Run the explainer first!"
|
243 |
+
return self.__results["top_contrastive"]
|
244 |
+
##
|
245 |
+
|
246 |
+
def get_other_constrastive_explanations(self):
|
247 |
+
if self.__results["other_contrastive"] is None:
|
248 |
+
return "Run the explainer first!"
|
249 |
+
return self.__results["other_contrastive"]
|
250 |
+
##
|
251 |
+
|
252 |
+
def get_positive_explanations(self):
|
253 |
+
if self.__results["pos_explain"] is None:
|
254 |
+
return "Run the explainer first!"
|
255 |
+
return self.__results["pos_explain"]
|
256 |
+
##
|
257 |
+
##
|
258 |
+
|
259 |
+
|
260 |
+
#[' 1. Take Me Home', " Country Roads by John Denver wasn't recommended as the genre is different", " it's a country rock song while And We Run (feat. Xzibit) and the
|
261 |
+
# other recommended songs are rock and metal.2. Take On Me by a-ha wasn't recommended as Within Temptation and Xzibit are metal and hip-hop", ' respectively', " while a-ha
|
262 |
+
# is a Norwegian band known for their synth-pop sound.3. Africa by Toto wasn't recommended because the genres are different. And We Run and other recommended songs are rock
|
263 |
+
# and metal while Africa is a rock song of a different nature."]
|
264 |
+
#[' 1. Angels by Within Temptation was recommended because it is a song in within the same genre of And We Run (feat. Xzibit).2. Stand My Ground by Within Temptation was recommended because both And We Run and Stand My Ground are by Within Temptation.3. The Gathering by Delain was recommended because Delain is from the same genre as Within Temptation.4. April Rain by Delain was recommended because Delain is from the same genre as Within Temptation.5. Strange Machines by The Gathering was recommended because both Strange Machines and And We Run are in the same genre.6. We Are the Others by Delain was recommended because Delain is from the same genre as Within Temptation.7. See Me In Shadow by Delain was recommended because Delain is from the same genre as Within Temptation.8. Leaves by The Gathering was recommended because The Gathering is from the same genre as Delain.9. Saturnine by The Gathering was recommended because The Gathering is from the same genre as Delain and Both Saturnine and And We Run are in the same genre10. Frozen by Delain was recommended because Delain is from the same genre as Within Temptation and Frozen is a collaborative song with both Within Temptation and Delain.']
|
265 |
+
def mistral_2_display(explanations):
|
266 |
+
import re
|
267 |
+
split = re.split(r'(\d+\.)', ''.join(explanations))
|
268 |
+
|
269 |
+
# cleanup
|
270 |
+
del split[0]
|
271 |
+
|
272 |
+
for i in range(len(split)):
|
273 |
+
if split[i][0].isdigit():
|
274 |
+
split[i] = split[i].replace('.', '')
|
275 |
+
split[i] = split[i].replace(' ', '', 1)
|
276 |
+
##
|
277 |
+
|
278 |
+
res = {}
|
279 |
+
key = None
|
280 |
+
for val in split:
|
281 |
+
if key == None:
|
282 |
+
key = val
|
283 |
+
else:
|
284 |
+
res[key] = val
|
285 |
+
key = None
|
286 |
+
##
|
287 |
+
##
|
288 |
+
|
289 |
+
return res
|
290 |
+
##
|
291 |
+
|
292 |
+
if __name__ == "__main__":
|
293 |
+
l1 = [' 1. Take Me Home', " Country Roads by John Denver wasn't recommended as the genre is different", " it's a country rock song while And We Run (feat. Xzibit) and the other recommended songs are rock and metal.2. Take On Me by a-ha wasn't recommended as Within Temptation and Xzibit are metal and hip-hop", ' respectively', " while a-ha is a Norwegian band known for their synth-pop sound.3. Africa by Toto wasn't recommended because the genres are different. And We Run and other recommended songs are rock and metal while Africa is a rock song of a different nature."]
|
294 |
+
l2 = []
|
295 |
+
l3 = [' 1. Angels by Within Temptation was recommended because it is a song in within the same genre of And We Run (feat. Xzibit).2. Stand My Ground by Within Temptation was recommended because both And We Run and Stand My Ground are by Within Temptation.3. The Gathering by Delain was recommended because Delain is from the same genre as Within Temptation.4. April Rain by Delain was recommended because Delain is from the same genre as Within Temptation.5. Strange Machines by The Gathering was recommended because both Strange Machines and And We Run are in the same genre.6. We Are the Others by Delain was recommended because Delain is from the same genre as Within Temptation.7. See Me In Shadow by Delain was recommended because Delain is from the same genre as Within Temptation.8. Leaves by The Gathering was recommended because The Gathering is from the same genre as Delain.9. Saturnine by The Gathering was recommended because The Gathering is from the same genre as Delain and Both Saturnine and And We Run are in the same genre10. Frozen by Delain was recommended because Delain is from the same genre as Within Temptation and Frozen is a collaborative song with both Within Temptation and Delain.']
|
296 |
+
|
297 |
+
print(mistral_2_display(l1))
|
298 |
+
print(mistral_2_display(l3))
|
299 |
+
##
|
data/new_tracks.csv
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
track_uri,artist_uri,album_uri,danceability,energy,key,loudness,mode,speechiness,acousticness,instrumentalness,liveness,valence,tempo,duration_ms,time_signature,Track_release_date,Track_pop,Artist_pop,Artist_genres
|
2 |
+
0SPBrxOUEMIKugXR4bFhxs,07XSN3sPlIlB2L2XNcTwJw,77opKywcxPnBu5aBMASS2b,0.409,0.868,3.0,-6.234,0.0,0.0368,0.0266,0.0357,0.276,0.704,147.2,198707.0,4.0,39,12,14,album_rock glam_rock hard_rock metal rock
|
3 |
+
0Wa5Q145xoXkfhaCRgA67U,36QJpDe2go2KgaRleHCDTp,4Q7cPyiP8cMIlUEHAqeYfd,0.483,0.615,2.0,-8.54,1.0,0.0497,0.452,0.000414,0.0512,0.594,80.56,517125.0,3.0,39,8,15,album_rock classic_rock hard_rock rock
|
4 |
+
5UdShl12E6eHEgS8lQ1bPr,36QJpDe2go2KgaRleHCDTp,4wExFfncaUIqSgoxnqa3Eh,0.552,0.791,7.0,-8.36,1.0,0.0303,0.123,1.42e-05,0.162,0.698,91.2,355893.0,4.0,40,10,15,album_rock classic_rock hard_rock rock
|
5 |
+
2GnVuaoKSkB6Xa07l1BBg8,5M52tdBnJaKSvOpJGz8mfZ,6TcPqftScGmR0aEgIb43Vv,0.476,0.556,4.0,-10.586,0.0,0.0646,0.0838,1.59e-05,0.125,0.43,103.1,364493.0,4.0,40,11,14,album_rock birmingham_metal classic_rock hard_rock metal rock stoner_rock uk_doom_metal
|
6 |
+
5SAUIWdZ04OxYfJFDchC7S,568ZhdwyaiCyOGJRtNYhWf,1EK3a0Yctg4d3nGQzE4Uty,0.632,0.586,0.0,-11.336,1.0,0.0284,0.0983,0.581,0.0535,0.89,114.25,342173.0,4.0,39,12,13,album_rock blues_rock classic_rock hard_rock metal psychedelic_rock rock
|
7 |
+
2cc9k15AifO7RfxxuEExkS,0cc6vw3VN8YlIcvr1v7tBL,23krn1eEy7o3u9laLI1PLD,0.535,0.967,2.0,-4.082,1.0,0.0678,0.000885,0.0181,0.233,0.353,111.0,291307.0,4.0,39,13,14,glam_metal hard_rock metal rock sleaze_rock
|
8 |
+
2C0hJUVjp7FSchyhYiceJq,0cc6vw3VN8YlIcvr1v7tBL,4ns4vxdkk4PdkneLNfJL52,0.395,0.777,5.0,-5.848,1.0,0.0334,0.097,5.54e-06,0.197,0.12,75.56,239080.0,4.0,39,13,14,glam_metal hard_rock metal rock sleaze_rock
|
9 |
+
0cKk8BKEi7zXbdrYdyqBP5,67ea9eGLXYMsO2eYQRui3w,5MqyhhHbT13zsloD3uHhlQ,0.394,0.622,4.0,-8.26,0.0,0.0336,0.213,4.45e-05,0.0892,0.342,126.9,221427.0,4.0,39,14,13,album_rock art_rock blues_rock british_invasion classic_rock hard_rock mellow_gold psychedelic_rock rock
|
10 |
+
1ju7EsSGvRybSNEsRvc7qY,4MVyzYMgTwdP7Z49wAZHx0,6DExt1eX4lflLacVjHHbOs,0.422,0.752,6.0,-8.68,1.0,0.0449,0.0366,0.000119,0.129,0.403,120.5,356627.0,4.0,39,14,14,album_rock blues_rock classic_rock country_rock hard_rock mellow_gold rock southern_rock
|
11 |
+
4J0kN8QS2esY6cWBsFjtW9,1dfeR4HaWDbWqFHLkxsg1d,6X9k3hSsvQck2OfKYdBbXr,0.395,0.698,2.0,-6.242,1.0,0.0573,0.334,6.44e-05,0.155,0.455,124.7,223173.0,4.0,39,9,16,classic_rock glam_rock rock
|
12 |
+
6Wx88Mv6b9ofjKMKkdwOJd,6XyY86QOPPrYVGvF9ch6wz,1fqibtpI0bwD73uQGeEnhn,0.493,0.808,5.0,-3.365,0.0,0.0362,0.000235,0.0,0.0983,0.38,118.0,268613.0,4.0,40,13,16,alternative_metal nu_metal post-grunge rap_metal
|
13 |
+
4CWhc9FaMMfBTt4ANjfbOf,6XyY86QOPPrYVGvF9ch6wz,2tlTBLz2w52rpGCLBGyGw6,0.571,0.934,3.0,-4.22,0.0,0.0531,0.00316,6.2e-06,0.197,0.409,132.6,221720.0,4.0,40,12,16,alternative_metal nu_metal post-grunge rap_metal
|
14 |
+
0sp00HSXkQyqTa6QqM0O8V,6XyY86QOPPrYVGvF9ch6wz,2tlTBLz2w52rpGCLBGyGw6,0.509,0.629,0.0,-6.434,1.0,0.0335,0.209,1.97e-06,0.369,0.237,80.0,209307.0,4.0,40,13,16,alternative_metal nu_metal post-grunge rap_metal
|
15 |
+
0OYcEfskah1egYHjYRvbg1,6XyY86QOPPrYVGvF9ch6wz,2tlTBLz2w52rpGCLBGyGw6,0.534,0.393,11.0,-7.812,1.0,0.0292,0.00479,0.0107,0.107,0.0641,110.0,290360.0,4.0,40,13,16,alternative_metal nu_metal post-grunge rap_metal
|
16 |
+
1fLlRApgzxWweF1JTf8yM5,6XyY86QOPPrYVGvF9ch6wz,2tlTBLz2w52rpGCLBGyGw6,0.655,0.885,7.0,-4.117,1.0,0.0438,0.00117,0.000473,0.0448,0.938,100.06,189293.0,4.0,40,14,16,alternative_metal nu_metal post-grunge rap_metal
|
17 |
+
7dvd3b2oz7AFgXrPBIIYxR,3nFkdlSjzX9mRTtwJOzDYB,5NH94cATqx5fjBE794xZLy,0.557,0.905,11.0,-4.508,1.0,0.267,0.0104,0.0,0.111,0.799,160.0,244693.0,4.0,40,11,16,east_coast_hip_hop hip_hop rap
|
18 |
+
2eVofaQRJvddSUBfcub7Gz,2KjAo6wVc9d2WcxdxSArpV,6kfKntjGEwjKUL7q43j5rO,0.659,0.387,6.0,-13.17,0.0,0.0335,0.467,0.692,0.0839,0.0779,115.0,279573.0,4.0,40,11,12,indie_folk
|
19 |
+
5u51UnecWzSb1ezJmDhBFw,2KjAo6wVc9d2WcxdxSArpV,2jCMxN3Ys1PCq6FQBEwM5L,0.61,0.671,1.0,-9.5,1.0,0.0361,0.441,0.0066,0.103,0.056,103.0,277633.0,4.0,40,8,12,indie_folk
|
20 |
+
4wNj7wubtz1KnGaFg2VwcU,7E3BRXV9ZbCt5lQTCXMTia,2YlB5eElaicdKaMYZVUHsO,0.628,0.0184,4.0,-22.56,0.0,0.0612,0.996,0.951,0.0993,0.232,103.8,121845.0,4.0,40,7,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
21 |
+
3m6A0Rpu03KYNyWzbCo0yO,7E3BRXV9ZbCt5lQTCXMTia,7lMrHurKbBzzHDVCblN0X3,0.159,0.0358,10.0,-26.84,0.0,0.0435,0.984,0.88,0.102,0.0391,72.7,210013.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
22 |
+
1EEJBUOORu9dLZQSeQkZOP,7E3BRXV9ZbCt5lQTCXMTia,69Q8uDA8C7EdKUo5oveufQ,0.231,0.0749,0.0,-20.97,0.0,0.0351,0.989,0.933,0.112,0.0735,134.2,256507.0,4.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
23 |
+
5RqKo9P4DLA0bVyY70cWkr,7E3BRXV9ZbCt5lQTCXMTia,6JpQGIi2he6iskzR4aLwPG,0.583,0.0238,0.0,-32.25,0.0,0.0369,0.994,0.847,0.103,0.426,108.75,131923.0,4.0,40,12,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
24 |
+
5tmtJPv2RyTqFQUC4VDgYy,7E3BRXV9ZbCt5lQTCXMTia,69Q8uDA8C7EdKUo5oveufQ,0.171,0.193,4.0,-12.984,0.0,0.0392,0.974,0.924,0.0822,0.0922,132.5,204866.0,5.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
25 |
+
7zTaLLMF9A170FfPtBaL3m,7E3BRXV9ZbCt5lQTCXMTia,3qFNuf0WssUVPXTPdrxGho,0.373,0.163,6.0,-21.81,1.0,0.0332,0.936,0.936,0.128,0.0377,94.06,137680.0,4.0,40,7,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
26 |
+
7gOi88gP4o1uv1kaL02yBB,7E3BRXV9ZbCt5lQTCXMTia,1LvZUmULkYj2c3oxIZhbkX,0.14,0.133,10.0,-15.78,0.0,0.038,0.93,0.918,0.121,0.0716,142.0,268773.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
27 |
+
5Ag8TTr1IdnqqLWJjVwpsl,7E3BRXV9ZbCt5lQTCXMTia,3kc6nAFF8njXeLUk16CXl6,0.443,0.11,6.0,-18.6,0.0,0.0955,0.996,0.959,0.0882,0.152,66.5,134714.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
28 |
+
6oVhL0lLUMswqSV3VcKwJO,7E3BRXV9ZbCt5lQTCXMTia,3GmecFBWNs4fTi0PkLF7qR,0.462,0.339,6.0,-14.305,0.0,0.0418,0.813,0.808,0.108,0.0395,115.0,272014.0,4.0,40,10,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
29 |
+
7ajRLygLieUKb5qsumndfc,7E3BRXV9ZbCt5lQTCXMTia,0DZZLQvXZzgurc5wWFgAst,0.182,0.019,4.0,-30.6,1.0,0.0435,0.988,0.971,0.0907,0.0334,95.3,114426.0,4.0,40,7,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
30 |
+
4lSsH5NXdwFbBhRrFXPVFj,7E3BRXV9ZbCt5lQTCXMTia,6NW97EFYSQ9X1CulKyL7wf,0.297,0.126,1.0,-23.8,0.0,0.0408,0.992,0.81,0.134,0.17,153.6,190284.0,1.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
31 |
+
7djcz9efRuDz8jklVJn4DC,7E3BRXV9ZbCt5lQTCXMTia,0oBmVbeJmelnhnYiacIvde,0.062,0.0249,0.0,-20.03,0.0,0.0465,0.981,0.827,0.236,0.0306,67.94,236395.0,3.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
32 |
+
42DSWZ06VzGVzuoRwZEHHe,7E3BRXV9ZbCt5lQTCXMTia,0lCyefnvL1HqQkpXl5HjC5,0.222,0.11,0.0,-18.31,0.0,0.0377,0.979,0.902,0.128,0.0638,103.25,226000.0,5.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
33 |
+
3NJy8hN4OXIMyqbskBsL8v,7E3BRXV9ZbCt5lQTCXMTia,2YlB5eElaicdKaMYZVUHsO,0.4,0.0333,8.0,-28.05,1.0,0.0389,0.994,0.881,0.0947,0.239,131.2,163861.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
34 |
+
2BeTUHecaoBWc825E3CPLK,7E3BRXV9ZbCt5lQTCXMTia,6NW97EFYSQ9X1CulKyL7wf,0.149,0.084,8.0,-21.06,1.0,0.0391,0.987,0.944,0.0726,0.0406,79.9,200965.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
35 |
+
7b44iVYyWxXXhxtfIU3NTW,7E3BRXV9ZbCt5lQTCXMTia,6JpQGIi2he6iskzR4aLwPG,0.36,0.158,6.0,-24.23,0.0,0.0359,0.988,0.927,0.104,0.04,133.4,235534.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
36 |
+
3WoFKA49Hjdoj1O9yhV62c,7E3BRXV9ZbCt5lQTCXMTia,7o4mIRr1MVq4dMgQiIsUw7,0.208,0.0847,0.0,-20.92,1.0,0.0425,0.982,0.931,0.102,0.0391,124.0,274355.0,5.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
37 |
+
0nYm42RuPWFaHWUXUdwHYm,7E3BRXV9ZbCt5lQTCXMTia,4kqcQUsGW2cJbztclbqLbO,0.4,0.128,5.0,-16.61,0.0,0.0401,0.989,0.85,0.11,0.124,123.0,251626.0,3.0,40,11,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
38 |
+
3YjTarxfHHEBUWqW5532uv,7E3BRXV9ZbCt5lQTCXMTia,6JpQGIi2he6iskzR4aLwPG,0.388,0.0103,3.0,-32.16,1.0,0.0445,0.984,0.94,0.188,0.0506,64.56,254297.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
39 |
+
5NVM9GhtQLTTyF910jfHmy,7E3BRXV9ZbCt5lQTCXMTia,69Q8uDA8C7EdKUo5oveufQ,0.288,0.0427,8.0,-19.14,1.0,0.0427,0.982,0.93,0.127,0.0938,99.6,212178.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
40 |
+
3u3SG5Mo1jGymmhEvuLA3G,7E3BRXV9ZbCt5lQTCXMTia,6NW97EFYSQ9X1CulKyL7wf,0.455,0.0951,1.0,-20.64,1.0,0.0394,0.988,0.95,0.104,0.168,121.94,242002.0,4.0,40,7,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
41 |
+
6ptovgL1si4Xn6BunkGg7t,7E3BRXV9ZbCt5lQTCXMTia,5yulSZK48ArdLPXWur0qik,0.471,0.103,3.0,-29.47,1.0,0.0337,0.993,0.914,0.106,0.174,116.5,315574.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
42 |
+
13MOQ6oQqkrZEDkZOHukCw,7E3BRXV9ZbCt5lQTCXMTia,6s61oZwe1dZuqBFi1pPo09,0.281,0.0333,6.0,-31.45,1.0,0.0348,0.994,0.959,0.0995,0.169,90.25,190500.0,1.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
43 |
+
7vbCfkJf89i4s745KbELgr,7E3BRXV9ZbCt5lQTCXMTia,5yulSZK48ArdLPXWur0qik,0.359,0.0224,3.0,-29.1,1.0,0.039,0.987,0.866,0.111,0.169,107.9,354989.0,3.0,40,11,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
44 |
+
0NVsz5lExNqzVDznhdPlU8,7E3BRXV9ZbCt5lQTCXMTia,1LvZUmULkYj2c3oxIZhbkX,0.201,0.132,3.0,-18.25,1.0,0.0342,0.992,0.942,0.132,0.141,169.9,202547.0,4.0,40,10,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
45 |
+
00L9p3dKK3ufNyua3pzVeC,7E3BRXV9ZbCt5lQTCXMTia,18Jd3iAcykSIDGTA0vanR3,0.0613,0.0285,7.0,-28.08,0.0,0.0427,0.95,0.899,0.106,0.0374,210.1,196440.0,4.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
46 |
+
6VuXB4kcwQaLxDeXOs1Nyi,7E3BRXV9ZbCt5lQTCXMTia,69Q8uDA8C7EdKUo5oveufQ,0.192,0.0777,10.0,-19.27,1.0,0.038,0.986,0.916,0.0485,0.154,87.4,138360.0,4.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
47 |
+
2BE9wLg2nyJahAecN1a6La,7E3BRXV9ZbCt5lQTCXMTia,0DZZLQvXZzgurc5wWFgAst,0.435,0.0275,1.0,-32.38,0.0,0.0382,0.991,0.955,0.082,0.0524,120.0,136996.0,4.0,40,7,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
48 |
+
4tnWEXeAgZWTRULCkJ6IGL,7E3BRXV9ZbCt5lQTCXMTia,6JpQGIi2he6iskzR4aLwPG,0.435,0.0564,5.0,-27.61,0.0,0.0369,0.99,0.943,0.113,0.127,110.0,155485.0,4.0,40,10,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
49 |
+
1ijwLR1iybtxaUbasUj7kJ,7E3BRXV9ZbCt5lQTCXMTia,3s5UDbcu9PBKBJ4xIz0zcW,0.289,0.0253,2.0,-31.44,1.0,0.0376,0.994,0.919,0.0837,0.138,99.8,150000.0,4.0,40,11,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
50 |
+
6wUU6ff7O1jlE4NOrv01gI,7E3BRXV9ZbCt5lQTCXMTia,6JpQGIi2he6iskzR4aLwPG,0.366,0.336,8.0,-17.4,1.0,0.0367,0.968,0.934,0.0898,0.0542,140.0,364648.0,4.0,40,10,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
51 |
+
5nW41zamR8GqKYUxvxo12d,7E3BRXV9ZbCt5lQTCXMTia,3YW20Fu5fMy01J2EY4Dlav,0.304,0.0903,2.0,-17.4,0.0,0.0326,0.985,0.891,0.0622,0.165,180.2,278400.0,3.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
52 |
+
6yidnXvq5fN4ULkgk8FOIU,7E3BRXV9ZbCt5lQTCXMTia,0DZZLQvXZzgurc5wWFgAst,0.541,0.0342,8.0,-35.25,0.0,0.0378,0.995,0.952,0.101,0.498,113.4,148433.0,3.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
53 |
+
2xkgm3ZHezoiW9tGblP5gi,7E3BRXV9ZbCt5lQTCXMTia,1LvZUmULkYj2c3oxIZhbkX,0.223,0.0696,5.0,-23.77,1.0,0.0314,0.991,0.933,0.0671,0.0411,81.25,242400.0,4.0,40,8,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
54 |
+
1CWCGglkuopcEsOaAXX8IN,7E3BRXV9ZbCt5lQTCXMTia,59XsnSTi3KDC8UtvOCMUSI,0.486,0.233,11.0,-25.77,1.0,0.0287,0.989,0.917,0.337,0.437,74.9,340751.0,4.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
55 |
+
2vD20Aj8Ru9NAmJl1Ca2qS,7E3BRXV9ZbCt5lQTCXMTia,6JpQGIi2he6iskzR4aLwPG,0.429,0.00693,9.0,-31.05,1.0,0.0539,0.995,0.938,0.0711,0.431,97.06,125413.0,4.0,40,11,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
56 |
+
6bcjo4kEC3bS46YbKjdywg,7E3BRXV9ZbCt5lQTCXMTia,1LvZUmULkYj2c3oxIZhbkX,0.262,0.0589,8.0,-16.56,1.0,0.0357,0.964,0.000934,0.105,0.0677,182.6,238707.0,3.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
57 |
+
0YPagAr3GhXlRX06E4nUcw,7E3BRXV9ZbCt5lQTCXMTia,69Q8uDA8C7EdKUo5oveufQ,0.437,0.0463,0.0,-25.92,1.0,0.0369,0.988,0.917,0.0845,0.139,140.5,187848.0,4.0,40,9,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
58 |
+
6Xajr512QEGAZ20bqAWkyT,7E3BRXV9ZbCt5lQTCXMTia,69Q8uDA8C7EdKUo5oveufQ,0.477,0.348,2.0,-14.586,1.0,0.0335,0.931,0.949,0.11,0.0867,117.94,208589.0,4.0,40,10,12,bow_pop compositional_ambient icelandic_classical neo-classical neoclassical_darkwave
|
59 |
+
1rpF77jsLBMG2QjCuhe0Sr,0fauHpmSHwodVYIjTqOGHz,4vtunVFmIlrxIrkOobdfDH,0.417,0.0287,7.0,-25.06,1.0,0.0714,0.994,0.889,0.079,0.285,143.2,264053.0,4.0,40,11,12,korean_instrumental neo-classical new_age_piano
|
60 |
+
5pW62tsMUPtw8k69ifpcjJ,2AcUPzkVWo81vumdzeLLRN,4emDc6rcjqJGqCj8NqEIzG,0.631,0.14,8.0,-16.38,1.0,0.0368,0.957,0.0106,0.109,0.1,140.0,254347.0,4.0,40,8,12,downtempo indie_soul indietronica shimmer_pop
|
61 |
+
4S2lJF9tqs5MRLtWzuPXx1,2i1CPudyCUjL50Wqjv8AMI,79a34uOB7jdMrSECClgqOv,0.444,0.0903,11.0,-19.28,0.0,0.0456,0.994,0.905,0.0856,0.0899,80.7,207680.0,4.0,40,9,9,british_jazz indie_jazz indie_soul uk_contemporary_jazz
|
62 |
+
3Bsyp79WSkfDruQBBo8FMO,6pSQcy8935ABNiK2qOpOlK,5xu1hee0bAPBpMmysKSmdc,0.553,0.11,11.0,-23.62,0.0,0.0307,0.966,0.931,0.0878,0.133,148.0,224736.0,4.0,40,8,9,compositional_ambient neo-classical
|
63 |
+
1n6ouOiQpRXaWVTeDOGxDW,54MsweggxTxlfYUbhZNIQ0,5KmLU0k60tDKnEhgRAqG2N,0.352,0.127,10.0,-26.31,0.0,0.0304,0.988,0.929,0.134,0.13,137.9,291000.0,4.0,40,10,9,compositional_ambient neo-classical
|
64 |
+
3yPd2RxNNcPwOV06zoexrv,21mKp7DqtSNHhCAU2ugvUw,0xVucRYJf5luWLekMGYh3i,0.403,0.636,9.0,-5.91,1.0,0.0449,0.395,0.604,0.439,0.0367,107.9,400130.0,4.0,40,10,13,chillwave edm ninja
|
65 |
+
1wb6pRSvhekFyXO5j3fXol,14YzutUdMwS9yTnI0IFBaD,27yZ8bTAOMlvnfU4vaIxvK,0.273,0.0338,1.0,-33.88,0.0,0.0343,0.984,0.878,0.105,0.134,147.6,227675.0,3.0,40,10,10,compositional_ambient neo-classical
|
66 |
+
4wCg95zm652wWBnryX9oS6,2SMBaAG61s9mtyJ0eeXSWx,79a34uOB7jdMrSECClgqOv,0.246,0.108,0.0,-18.19,0.0,0.0366,0.962,0.876,0.0782,0.0738,67.3,236999.0,4.0,40,9,9,compositional_ambient neo-classical
|
67 |
+
3uUUJo8kymUm0a9L7JSEDF,6ntwC60sylc4u0Npjoj6GM,5b7quz61hkXH51ocDuSeCp,0.658,0.591,5.0,-8.18,0.0,0.043,0.154,0.672,0.0585,0.215,105.94,238213.0,4.0,40,5,3,palestinian_alternative
|
68 |
+
1qrRl5pJWiL93EukHOMB0h,3fyyPt5BZ20BkmqVcQV6wS,09J4Y6mUcrEjkhzIAEwg1x,0.588,0.814,9.0,-5.953,0.0,0.0702,0.0398,0.0,0.0493,0.704,159.9,249750.0,4.0,40,4,7,jordanian_pop middle_east_hip_hop palestinian_hip_hop palestinian_pop
|
69 |
+
6unp5zGcRjIAyeNjiVMLHX,76G2QPGz4HBmhn0D3vr9UL,5ydSYLaBAPJIV2bn2HmkSs,0.494,0.553,11.0,-9.164,0.0,0.2,0.00601,0.0,0.0542,0.354,113.3,177388.0,5.0,40,7,8,palestinian_pop
|
70 |
+
3AQMp7f6Pgm3gHUGoTqDyL,0ezquZkJscWDhtBZwptcKT,6RMRNXNTg12KwIUIxFcYay,0.481,0.658,6.0,-6.754,0.0,0.03,0.0263,0.0282,0.132,0.513,162.0,228334.0,4.0,40,4,4,arab_alternative jordanian_pop
|
71 |
+
5FoOlTlC8pzAHV23s7gPqY,0ezquZkJscWDhtBZwptcKT,2gnn8Mwb6Njbh34OsqvoIh,0.407,0.766,4.0,-4.992,1.0,0.0365,0.0064,0.0525,0.115,0.269,140.0,336008.0,4.0,40,6,4,arab_alternative jordanian_pop
|
72 |
+
2rD1eIqfbnsCk9GJxiXQBK,0ezquZkJscWDhtBZwptcKT,6RMRNXNTg12KwIUIxFcYay,0.613,0.542,7.0,-6.29,0.0,0.025,0.132,0.0641,0.11,0.564,82.06,210778.0,4.0,40,5,4,arab_alternative jordanian_pop
|
73 |
+
6EGN0RcirTvE4HCrKNXGe0,2qi698G7BphxwdPUbQgZMU,5ntiX3s1kigHbz9WqQsxyN,0.526,0.499,10.0,-10.46,1.0,0.119,0.285,0.0,0.0872,0.71,170.1,268549.0,4.0,40,6,7,arab_alternative jordanian_pop
|
74 |
+
01g5Dl95lH5qQyjjXucOPf,2qi698G7BphxwdPUbQgZMU,0hLTpm3Xcac0uUsl1HfeQx,0.655,0.621,10.0,-7.363,0.0,0.0383,0.33,0.0,0.137,0.685,105.0,172317.0,4.0,40,3,7,arab_alternative jordanian_pop
|
75 |
+
19M24LvVumMVlcQIHusXyl,6dO0RkhFhjMwLtLQqNgL8r,41kBbSWRbStqfsrXeM5Cpo,0.701,0.655,9.0,-9.05,0.0,0.15,0.0872,0.0,0.181,0.805,147.0,181348.0,4.0,40,3,10,indonesian_viral_pop
|
76 |
+
6nIGMTqiL0cZYyNa8gzj0e,6dO0RkhFhjMwLtLQqNgL8r,1gZW7IiLxwvWx0VAR9HK3X,0.828,0.498,1.0,-10.38,0.0,0.0363,0.172,0.0,0.0727,0.439,95.0,209684.0,4.0,40,11,10,indonesian_viral_pop
|
77 |
+
6B1Fq1RpAW1dBTaCZ9WxQ2,2a1uAKszGY1wTHnbT0Y9Y8,3nm3ELWFVPTN7Iq6D7GWYj,0.687,0.688,0.0,-7.145,1.0,0.037,0.121,3.1e-06,0.0718,0.31,100.0,199200.0,4.0,40,3,3,unknown
|
78 |
+
2miXa7bxd39RSSn1VvPs7o,2a1uAKszGY1wTHnbT0Y9Y8,59al6unEUgOFKSknNugus9,0.857,0.502,5.0,-10.695,0.0,0.0356,0.11,0.0473,0.104,0.53,100.0,146400.0,4.0,40,4,3,unknown
|
79 |
+
2c2by2xH5vEW142S9zZD7G,0EQjOxeqpT2ebzA1NvT9Cu,5LC6AvKrSmynyr7o50k5OM,0.658,0.389,11.0,-8.734,0.0,0.0312,0.828,0.00104,0.0883,0.245,112.6,224000.0,4.0,40,3,3,arab_alternative jordanian_pop
|
80 |
+
4ktzD6OYjb2u2kqfecXK79,4yuZxu7joQOFtplpMAsxlf,3JNS9fh8RFw3N86GCCbZp6,0.692,0.496,10.0,-10.695,0.0,0.0683,0.153,0.334,0.42,0.488,89.94,199333.0,4.0,40,6,6,palestinian_alternative
|
81 |
+
5x7LMsSBWbQlLnmxF3U5PC,4yuZxu7joQOFtplpMAsxlf,2I2lamkjFbeLFLUEcH8SAc,0.73,0.487,11.0,-10.44,0.0,0.0571,0.054,0.00999,0.106,0.353,100.06,184800.0,4.0,40,9,6,palestinian_alternative
|
82 |
+
1DJ2pwtprG3edEU2pbVVDi,1IJJoAyxznu3orwXhlt3XO,74vATKQHUWKVc4T7uYLK3n,0.648,0.533,0.0,-8.336,0.0,0.0357,0.85,1.84e-05,0.152,0.737,148.0,211283.0,4.0,40,2,7,arab_pop jordanian_pop palestinian_pop
|
83 |
+
1hUZU0lCce1QzcaqWjwWiE,1IJJoAyxznu3orwXhlt3XO,1GOZ3S72ib2ZU1MjpeRy42,0.725,0.769,0.0,-5.46,1.0,0.0293,0.432,0.0,0.0545,0.749,98.0,189870.0,4.0,40,3,7,arab_pop jordanian_pop palestinian_pop
|
84 |
+
0y9njiG24r8Pc7iPNuY5zl,1IJJoAyxznu3orwXhlt3XO,7N0irhTBjGV5StiVTw8qTt,0.748,0.807,2.0,-4.43,0.0,0.0344,0.2,3.3e-06,0.0948,0.701,106.06,187747.0,4.0,40,5,7,arab_pop jordanian_pop palestinian_pop
|
85 |
+
4UcpiWGup7TKr1NkqaBrQ7,1IJJoAyxznu3orwXhlt3XO,77e5W1q40rJcSAJjt7GA1p,0.659,0.713,7.0,-6.82,1.0,0.0468,0.313,0.0,0.0991,0.849,179.9,175627.0,4.0,40,6,7,arab_pop jordanian_pop palestinian_pop
|
86 |
+
5aV0Vl1Fv9s9PmWklzzlvz,1IJJoAyxznu3orwXhlt3XO,0IiY9pwCRMsRdldrMpW03A,0.649,0.935,1.0,-4.766,0.0,0.0445,0.277,1.55e-06,0.0724,0.914,145.0,237453.0,4.0,40,4,7,arab_pop jordanian_pop palestinian_pop
|
87 |
+
54eiRWO1fHjuxWDptNftM8,1IJJoAyxznu3orwXhlt3XO,2mCEBE4YATciVhoaIWLc6Z,0.716,0.828,1.0,-5.453,0.0,0.0611,0.115,0.0,0.059,0.846,100.0,254395.0,4.0,40,2,7,arab_pop jordanian_pop palestinian_pop
|
88 |
+
1feYc8vSa3y6EodevhkzYB,7nQVHZnQGjMyc1HSOQW7GZ,4Aq2uHcgC4Sk13QlrzKicj,0.859,0.62,5.0,-5.06,0.0,0.0573,0.0924,0.0036,0.0908,0.628,100.0,145871.0,4.0,40,7,7,palestinian_alternative
|
89 |
+
33ZTgAaPHck9KIIOEnkSxC,1vKZWmYdp9BQAbtrX9ORuu,4J1k05sRPi0Qlez40Z8nXg,0.799,0.655,7.0,-4.816,1.0,0.102,0.122,0.0,0.106,0.555,100.0,189600.0,4.0,40,4,4,haryanvi_hip_hop jordanian_pop
|
90 |
+
4UiGACEtRM9N0PxuXzrVfQ,3faPN9ZqiY5AFpYAe8WqGE,3yqmmWNUtIMWBlFImfPhb0,0.739,0.549,3.0,-9.94,0.0,0.0499,0.487,4.5e-06,0.107,0.529,122.0,252295.0,4.0,40,4,4,arab_pop jordanian_pop
|
91 |
+
0MxeOx5YwpkXIlCmr6xOjP,0jIWKlfmD4Ew7HeVVrq03g,6fV0By80SOnUuqKt5wpk2A,0.736,0.597,8.0,-5.934,0.0,0.107,0.325,0.0,0.35,0.696,150.1,139289.0,4.0,40,8,9,palestinian_pop
|
92 |
+
62tYV2LYspoAS5vvZKB1EL,6gm05jmgIx3YvLtzl1GDas,3txVOVb4WHe4AzuvjMYrKn,0.522,0.613,9.0,-9.06,1.0,0.0979,0.722,6.14e-06,0.238,0.722,168.0,200000.0,4.0,40,2,1,reggae_maghreb
|
93 |
+
5LXmGPStiy83Tnsq96G9V6,0blZk3JXQG2roCiO6KCJWY,0y5vb7o8uCKsA858HIG2dM,0.54,0.504,1.0,-12.99,1.0,0.0424,0.727,0.000143,0.111,0.742,175.0,208560.0,4.0,40,2,5,jordanian_pop
|
94 |
+
4l7h95DV4TJimjWoZBRd9B,0blZk3JXQG2roCiO6KCJWY,3lMNn9CmmoS7oWUGUbgZ5Q,0.61,0.145,1.0,-15.02,0.0,0.0333,0.92,1.9e-06,0.114,0.184,102.4,244690.0,4.0,40,2,5,jordanian_pop
|
95 |
+
3zOixogOi4v75PI7bkws2O,7BhIlI9vRbaE1i1bYm81ZF,3pnLlR5wQ08LWbyb93clqe,0.652,0.658,9.0,-6.68,0.0,0.108,0.258,0.0,0.125,0.534,172.0,220905.0,4.0,40,3,1,jordanian_pop
|
96 |
+
3XknoC28vtiUyutxsG9ul6,409IHz2Yvi1kdUmrjein3m,3KVMPfIaR2QTJIguyhdnxh,0.697,0.881,6.0,-6.71,1.0,0.0366,0.108,0.00186,0.116,0.731,112.0,178913.0,4.0,40,5,2,palestinian_pop
|
97 |
+
2qSOhlYYwnlmTh5MNlxv6T,1LTJFwU5wuzqgYWzvkqBix,3jm2Mw7iAV31QfoRverhwL,0.489,0.342,1.0,-15.56,0.0,0.0306,0.202,4.37e-05,0.0757,0.22,82.1,222439.0,4.0,40,4,7,arab_electronic middle_east_hip_hop
|
98 |
+
7lx7KcCLJtHTCFglYQC12y,1LTJFwU5wuzqgYWzvkqBix,6W7b9RFrdBE29953myz6b7,0.376,0.398,11.0,-13.266,0.0,0.0403,0.579,5.12e-05,0.0847,0.25,138.9,167500.0,4.0,40,2,7,arab_electronic middle_east_hip_hop
|
99 |
+
7ys7eUYsciH8LefcobJ4hQ,7ekEnaplxNFP0jh9hiyeM8,2PbNvLR2MHgirCervbyo8n,0.864,0.734,1.0,-5.35,0.0,0.107,0.472,0.000305,0.0867,0.527,90.0,260597.0,4.0,40,2,3,middle_east_hip_hop palestinian_hip_hop
|
100 |
+
0KmiXlCv8005j9o340PW4e,5nxFmhSekt9Acn4tWZxGge,6fxuBrz4h4iOuW5hVoiJmc,0.593,0.871,0.0,-7.7,0.0,0.309,0.134,5.06e-05,0.271,0.728,176.0,275017.0,4.0,40,3,5,arab_alternative jordanian_pop middle_east_hip_hop palestinian_hip_hop palestinian_pop
|
101 |
+
0NWhRdPRI06ABKoOeRSgrb,5m8fc8h0xd4QfpJzcPI9NK,1h6ZfXJnDh0Vvlrv7mj7yh,0.479,0.837,4.0,-8.52,0.0,0.228,0.0861,8e-06,0.095,0.369,112.1,187643.0,5.0,40,2,5,arab_pop jordanian_pop
|
102 |
+
6gaEXyjkXtIfFcmNZSPQhL,704S90MD8gMqUNd9LsXvd1,2UYF5glGACebnFJcxzMHEO,0.756,0.657,8.0,-8.766,0.0,0.0386,0.16,0.000583,0.122,0.0859,107.94,248889.0,4.0,40,3,5,arabic_hip_hop jordanian_pop middle_east_hip_hop palestinian_hip_hop
|
103 |
+
3eFh5hiL65ylUoGAAI3Rl1,5VZr6vX1UPRRf9tneUEi2B,5UtCKCQtEMEgenYWqYmxIB,0.728,0.551,4.0,-9.984,0.0,0.0373,0.537,0.0,0.0818,0.451,97.94,211071.0,4.0,40,11,10,middle_east_hip_hop
|
104 |
+
65rWsK4Js9lGAhOQTpPTxM,0KgK0OMTh21OHyab9UDg3r,5nBnqvnnQnAsCNxX8q1Xw1,0.51,0.37,7.0,-12.96,1.0,0.138,0.801,1.07e-05,0.0929,0.452,95.06,174316.0,4.0,40,3,5,toronto_rap
|
105 |
+
5dueytCp1DWHJizVwQ34va,3zbimX3Z591csbDHH2Iuxc,0FIEcX7gSEX1h8PqsQbWhu,0.527,0.547,9.0,-7.05,0.0,0.0735,0.587,0.0,0.125,0.46,156.1,298823.0,4.0,40,3,5,arab_pop jordanian_pop
|
106 |
+
3xGfWGr12b6j86gUmhwesD,4juIELxFGt6YwXdpzGB69c,4zaWHh2zDRzOvC5ZhqOiDq,0.649,0.707,8.0,-5.934,1.0,0.0457,0.0248,0.00104,0.104,0.741,135.5,204533.0,4.0,40,6,3,indie_pop_rap
|
107 |
+
7uvT6cxtmmpLYED0uOaypM,4Svx0xgoS8UA2ldqxmxG4L,4KVKvjqBmoPlYMUsiW7O8v,0.681,0.793,11.0,-6.707,1.0,0.0751,0.0796,3.68e-05,0.456,0.485,99.06,166765.0,4.0,40,2,0,jordanian_pop
|
108 |
+
4c1JwtH7HEfIqlf0keNFGR,0x8vbV32RlTpfxsERAwena,30qPLsJugZwQXGH7iHdvkY,0.641,0.616,8.0,-9.59,1.0,0.0247,0.244,0.00353,0.131,0.496,105.0,248000.0,4.0,40,5,5,arab_alternative jordanian_pop
|
109 |
+
03OGe1S2a7i35BmuKbWaHk,4F84IBURUo98rz4r61KF70,2ntSwmOLAM0fMML87wtLKq,0.746,0.465,4.0,-7.586,0.0,0.0833,0.00637,0.511,0.237,0.29,123.9,232627.0,4.0,40,5,14,alternative_rock blues_rock detroit_rock garage_rock modern_blues_rock modern_rock permanent_wave punk_blues rock
|
110 |
+
0PdM2a6oIjqepoEfcJo0RO,6H1RjVyNruCmrBEWRbD0VZ,31oeDyCOLhgeZyktfxo0pE,0.267,0.953,1.0,-4.9,0.0,0.096,0.00211,0.0,0.283,0.568,85.0,267307.0,4.0,39,14,13,album_rock hard_rock nwobhm rock
|
111 |
+
0WoFs3EdGOx58yX5BtXvOa,1zxDewzd2j1ZdSBGaYcr0y,0EriQlp6zHpb1ThLZcandW,0.578,0.654,1.0,-12.42,0.0,0.0562,0.121,3.64e-06,0.0673,0.621,129.5,216467.0,4.0,39,15,13,album_rock power_pop
|
112 |
+
3GBApU0NuzH4hKZq4NOSdA,536BYVgOnRky0xjsPT96zl,0wNjC8d3ve2L2yaomEWUsa,0.563,0.739,6.0,-4.24,0.0,0.0416,0.00073,1.45e-05,0.0822,0.775,139.0,191707.0,4.0,40,14,13,indie_rock indietronica irish_rock modern_alternative_rock modern_rock northern_irish_indie
|
113 |
+
4BggEwLhGfrbrl7JBhC8EC,4iSKnRZAxkmqNok6tv10Se,0hdOk76DmEMYI6QV92mIin,0.736,0.811,9.0,-4.17,0.0,0.081,0.00132,0.000142,0.107,0.609,103.5,216733.0,4.0,39,14,11,alternative_metal funk_metal nu_metal post-grunge rap_rock
|
114 |
+
549Go7a66CX6k523uK9kUv,0cc6vw3VN8YlIcvr1v7tBL,2KT9tWALjIRjnaGYDYPg3k,0.599,0.931,7.0,-4.652,1.0,0.0735,0.0302,6.69e-05,0.392,0.536,140.1,270427.0,4.0,39,15,14,album_rock alternative_metal glam_metal hard_rock metal rock sleaze_rock
|
115 |
+
4JfuiOWlWCkjP6OKurHjSn,7Ey4PD4MYsKc5I2dolUwbH,6As5aOEQjfxLIChIB3fQRD,0.653,0.73,5.0,-10.61,1.0,0.0429,0.0115,1.02e-05,0.0776,0.894,108.7,220311.0,4.0,39,15,15,album_rock classic_rock hard_rock rock
|
116 |
+
7HKxTNVlkHsfMLhigmhC0I,4tpUmLEVLCGFr93o8hFFIB,18fOLsMG8Msf1DEaW0E71K,0.554,0.833,2.0,-6.668,0.0,0.0347,0.000646,0.0025,0.0737,0.773,142.6,212227.0,4.0,-56,14,13,candy_pop new_wave_pop permanent_wave power_pop rock synthpop
|
117 |
+
35ItUJlMtjOQW3SSiTCrrw,1dfeR4HaWDbWqFHLkxsg1d,6wPXUmYJ9mOWrKlLzZ5cCa,0.599,0.762,0.0,-6.887,1.0,0.0423,0.714,4.4e-06,0.35,0.715,76.94,163373.0,4.0,-58,14,16,classic_rock glam_rock rock
|
118 |
+
13NKppKoJKsqKQH7faE2my,1ikID9RZZMvkuBGDWrqajq,3fD889Y0RRNVrhStBXZ9FE,0.279,0.631,3.0,-9.4,1.0,0.0743,0.518,0.0534,0.165,0.104,99.94,263631.0,4.0,-54,5,10,future_bass pop_edm swedish_electropop vapor_twitch
|
119 |
+
080lqIGpbvzi3Zbl2whFrF,3qDMrpZHtZEtVl5i1l7hP3,58J1HN0dJl1pkTwu1YGJSq,0.723,0.643,7.0,-4.65,1.0,0.044,0.292,0.0,0.139,0.826,105.94,165249.0,4.0,-54,6,10,hopebeat
|
120 |
+
27HkyZkH0wo1Y0bvC8UxjU,7FngGIEGgN3Iwauw1MvO4P,16rbUsslYCC9NnKIwLQUnY,0.533,0.838,1.0,-5.625,0.0,0.0837,0.0251,0.0,0.318,0.722,80.06,179690.0,4.0,-54,8,10,cloud_rap emo_rap
|
121 |
+
3PDNGdhCtiQemL14eKhCup,7FngGIEGgN3Iwauw1MvO4P,16rbUsslYCC9NnKIwLQUnY,0.718,0.69,0.0,-7.3,1.0,0.0795,0.0419,0.000419,0.105,0.428,90.0,160423.0,4.0,-54,9,10,cloud_rap emo_rap
|
122 |
+
6eE0f2XF699L6EtRnRMBJD,7lZauDnRoAC3kmaYae2opv,0F0ZkON4kT4TK0SLX2T77r,0.368,0.754,1.0,-5.184,1.0,0.0502,0.00928,0.0,0.256,0.281,169.9,258679.0,4.0,-54,1,10,canadian_electronic melodic_dubstep pop_edm
|
123 |
+
5GYFceOhqamIBKHHjI3G1f,5WGPbnx9LqsQYXgpnUI3DZ,69rTPOtZEjPXRRvTm1j35v,0.651,0.626,5.0,-6.035,1.0,0.0428,0.0559,0.0,0.123,0.39,120.06,194750.0,4.0,-54,8,6,uk_pop
|
124 |
+
7fagIEAIqSPm2h9Bc3WgmL,0jNDKefhfSbLR9sFvcPLHo,3FwjVe9KTLPcAVj1EQsz8N,0.458,0.575,2.0,-5.04,1.0,0.0524,0.319,0.0,0.132,0.188,77.8,241389.0,4.0,-54,5,10,brostep edm electro_house electronic_trap future_bass pop_dance
|
125 |
+
6LJUlREHwzx1Z2BcqOdJSW,7HfUJxeVTgrvhk0eWHFzV7,5o9aTepLhqQL2gXuKPhd8g,0.481,0.265,4.0,-12.91,1.0,0.0329,0.887,0.00865,0.102,0.221,86.75,162759.0,4.0,-54,7,9,hyperpop
|
126 |
+
4L3oZ7FFTrK8Sh5hVcjIk5,5w39eY1aNDybnDGTNgVt3r,5dRqsOUEGiCFcudoeaPxM7,0.569,0.712,1.0,-4.96,1.0,0.0385,0.0746,0.0,0.096,0.31,122.0,220328.0,4.0,-54,7,8,pop_edm
|
127 |
+
0KbMjhlUH1xUGDgeIQzLsn,07UJz804RJxqNvxFXC3h9H,5Mp5iZqsRMvP3izACMnLPF,0.805,0.7,10.0,-3.064,0.0,0.155,0.0547,0.0,0.04,0.832,127.06,126701.0,4.0,-54,10,10,future_bass scottish_electronic vapor_twitch
|
128 |
+
1nv0TQDFYyW40u2odQNt5H,6LqNN22kT3074XbTVUrhzX,5hOFWwfkeWetTEnMTbX4q9,0.49,0.402,6.0,-5.555,1.0,0.0521,0.819,0.0,0.0794,0.323,77.75,168387.0,4.0,-54,9,14,dance_pop pop
|
129 |
+
3sSDCpbg9ju2bqKDfcPTzm,6LqNN22kT3074XbTVUrhzX,5hOFWwfkeWetTEnMTbX4q9,0.657,0.69,5.0,-1.78,0.0,0.312,0.0282,1.3e-06,0.511,0.583,125.94,154587.0,4.0,-54,10,14,dance_pop pop
|
130 |
+
2d2lYLXMF8KEZIrPFrFDZN,6LqNN22kT3074XbTVUrhzX,5hOFWwfkeWetTEnMTbX4q9,0.538,0.478,8.0,-4.258,0.0,0.0262,0.761,3.62e-05,0.132,0.313,136.1,262987.0,4.0,-54,8,14,dance_pop pop
|
131 |
+
1EMWN9uomtQxEw2mZKrb2C,3R80OE4RViOWbnuvqh0j8a,6oAHui1V8db4Ns78vWHJlN,0.827,0.8,7.0,-4.82,0.0,0.11,0.383,0.00164,0.102,0.514,142.6,164719.0,4.0,-108,14,12,bedroom_r&b chill_r&b
|
132 |
+
2YXGbxICUdOUJe9OPlicy1,56oDRnqbIiwx4mymNEv7dS,0BaIaHcyBXuOWeM4Aas4EW,0.861,0.611,1.0,-7.89,1.0,0.0427,0.0764,0.0,0.0763,0.803,115.0,143833.0,4.0,-108,14,14,escape_room minnesota_hip_hop pop trap_queen
|
133 |
+
13Irp51zj01BZu2XtDrnAg,56oDRnqbIiwx4mymNEv7dS,1KtDsGsSRGbnmH07v5hB1I,0.721,0.769,7.0,-4.11,1.0,0.105,0.0922,0.0,0.0817,0.915,155.9,187108.0,4.0,-108,15,14,escape_room minnesota_hip_hop pop trap_queen
|
134 |
+
3Dv1eDb0MEgF93GpLXlucZ,5cj0lLjcoR7YOSnhnX0Po5,1MmVkhiwTH0BkNOU3nw5d3,0.787,0.673,11.0,-4.582,0.0,0.159,0.264,3.34e-06,0.0904,0.779,110.94,237893.0,4.0,-109,15,17,dance_pop pop
|
135 |
+
1uNePI826aqh9uC9pgbeHU,5cj0lLjcoR7YOSnhnX0Po5,3wOMqxNHgkga91RBC7BaZU,0.822,0.654,0.0,-4.62,1.0,0.132,0.019,0.0,0.233,0.421,119.9,211013.0,4.0,-109,14,17,dance_pop pop
|
136 |
+
5ACZOGjT6I5He0pDZED56Z,5C1tex8vm00yFKTitiOnMU,5VMaKMyX5OTgrmHwvOVJZ1,0.578,0.724,6.0,-7.02,0.0,0.0865,0.192,2.38e-05,0.235,0.465,169.9,217412.0,4.0,-109,13,10,la_pop
|
137 |
+
7njDhlprmHJ1I9pM0rxMON,4GJ6xDCF5jaUqD6avOuQT6,5x9fQvlmhZqWoifJs9dVVL,0.72,0.794,6.0,-2.645,1.0,0.0862,0.378,0.0,0.122,0.856,138.1,149438.0,4.0,-108,14,13,k-pop_girl_group
|
138 |
+
3tJ4y2Zqx6gM9xOAuFfsSF,4NHQUGzhtTLFvgF5SZesLK,1tuekzsMZQOuiMejKP6t2Y,0.674,0.694,9.0,-7.074,0.0,0.109,0.313,7.15e-06,0.0752,0.203,102.0,199179.0,4.0,-109,13,14,dance_pop metropopolis pop swedish_electropop swedish_pop swedish_synthpop
|
139 |
+
1TIiWomS4i0Ikaf9EKdcLn,4NHQUGzhtTLFvgF5SZesLK,6jggnLM3SdDnjQ3GWmIZ4L,0.79,0.728,7.0,-6.523,1.0,0.0612,0.025,0.00106,0.172,0.333,110.06,223795.0,4.0,-109,12,14,dance_pop metropopolis pop swedish_electropop swedish_pop swedish_synthpop
|
140 |
+
1vQOTeTQlZ5NWX2el2RmlG,5FkMS3KgG0cjiRm250NFTJ,6r0xsy4FAx4p2Fc2WZxVR0,0.714,0.75,0.0,-4.566,1.0,0.045,0.00982,0.000898,0.248,0.425,128.0,208641.0,4.0,-108,12,10,cloud_rap
|
141 |
+
63y6xWR4gXz7bnUGOk8iI6,66CXWjxzNUsdJxJ2JdwvnR,3pdKKSqqLVIKmRTGw0x2N7,0.623,0.734,9.0,-5.95,1.0,0.107,0.0162,1.7e-06,0.145,0.37,107.9,244453.0,4.0,-109,14,17,pop
|
142 |
+
6zegtH6XXd2PDPLvy1Y0n2,66CXWjxzNUsdJxJ2JdwvnR,4NBuascXb3uK0mFUYuJ63f,0.644,0.755,1.0,-5.324,1.0,0.0448,0.00237,7.6e-06,0.0859,0.334,102.9,190067.0,4.0,-109,14,17,pop
|
143 |
+
3SexEc7om0q1awRqi8nCd1,4npEfmQ6YuiwW1GpUmaq3F,718h0CzRHO6ums1CTrB5L1,0.641,0.862,6.0,-5.164,0.0,0.0686,0.00393,2.41e-05,0.234,0.64,140.0,137514.0,4.0,-108,14,15,pop
|
144 |
+
4fkM7M4Uo5AUASnnsRC7EZ,4npEfmQ6YuiwW1GpUmaq3F,0V4a4xYECICWUCzgoxfIYF,0.745,0.642,6.0,-4.137,0.0,0.0506,0.103,0.0,0.0335,0.35,120.06,186520.0,4.0,-109,14,15,pop
|
145 |
+
6IbnUaczZBT34DhaD6S18F,6CwfuxIqcltXDGjfZsMd9A,49kf7gWWtReFwPcCNsvyUf,0.495,0.856,0.0,-5.12,0.0,0.0311,0.000219,0.0,0.103,0.609,158.0,154667.0,4.0,-110,15,14,metropopolis pop pov:_indie uk_alternative_pop
|
146 |
+
4sOX1nhpKwFWPvoMMExi3q,6CwfuxIqcltXDGjfZsMd9A,49kf7gWWtReFwPcCNsvyUf,0.66,0.689,4.0,-2.672,0.0,0.0337,0.0884,0.0,0.0922,0.427,128.0,221075.0,4.0,-110,15,14,metropopolis pop pov:_indie uk_alternative_pop
|
147 |
+
7hU3IHwjX150XLoTVmjD0q,5L1lO4eRHmJ7a0Q6csE5cT,66OYt73mqan1hWa78BhfPd,0.831,0.554,1.0,-10.0,0.0,0.218,0.161,6.12e-05,0.152,0.396,140.0,168228.0,4.0,-108,15,14,k-pop
|
148 |
+
6E11E0lT5Zy7yb6iT3y8DN,4m4SfDVbF5wxrwEjDKgi4k,16liSbjaxbH0oamsQlqJ4Z,0.694,0.891,9.0,-2.94,1.0,0.0949,0.0562,0.0,0.561,0.563,97.94,214573.0,4.0,-110,12,11,dance_pop pop post-teen_pop talent_show
|
149 |
+
7FdmHr87G79PDRGy9SPBkZ,181bsRPaVXVlUKXrxwZfHK,6B26OzQRObxAp1tbf8jeTq,0.949,0.683,9.0,-4.242,1.0,0.0946,0.0199,0.0,0.171,0.887,130.0,184635.0,4.0,-108,13,15,houston_rap pop r&b rap trap_queen
|
150 |
+
7jPdqwZug0ovtDZsY5uK4T,6kXm2YCtdUOpRYNKeKhfue,6OvDrWqXGbPBTyovcFmQO5,0.352,0.628,1.0,-6.258,1.0,0.0428,0.0264,4.74e-05,0.0952,0.387,140.4,222634.0,4.0,-108,14,12,hollywood
|
151 |
+
6EJiVf7U0p1BBfs0qqeb1f,6sFIWsNpZYqfjUpaCgueju,6S9qcfPMsqtYQXVyeC7Hip,0.71,0.909,2.0,-2.777,1.0,0.0639,0.0135,0.00123,0.303,0.648,115.0,207960.0,4.0,-109,12,13,canadian_pop dance_pop pop
|
152 |
+
3qKunud9sySc8qvQ3i84og,08PvCOlef4xdOr20jFSTPd,42C76ZnwdWqEu6zs6NFW1A,0.984,0.719,8.0,-5.117,1.0,0.0893,0.0566,9.88e-05,0.517,0.437,118.0,146855.0,4.0,-108,13,13,viral_rap
|
153 |
+
4qbEaaJ29p32GI8EWQmm6R,4adSXA1GDOxNG7Zw89YHyz,7uzmNefPoRgc5Pi9DS00CC,0.783,0.472,2.0,-8.39,1.0,0.0427,0.22,0.000458,0.0798,0.589,122.06,125256.0,4.0,-108,14,10,modern_indie_pop
|
154 |
+
0aoLgGE9S9qMjIGtTgpnNd,0CLW5934vy2XusynS1px1S,04xgq5VLo2p35E09kdKCWv,0.833,0.848,6.0,-3.703,1.0,0.222,0.069,0.0,0.335,0.934,160.1,120016.0,4.0,-108,14,10,trap_queen
|
155 |
+
4JUPEh2DVSXFGExu4Uxevz,41MozSoPIsD1dJM0CLPjZF,71O60S5gIJSIAhdnrDIh3N,0.79,0.701,9.0,-4.81,1.0,0.365,0.0317,8.06e-05,0.0311,0.91,160.0,177813.0,4.0,-108,13,16,k-pop k-pop_girl_group pop
|
156 |
+
0skYUMpS0AcbpjcGsAbRGj,41MozSoPIsD1dJM0CLPjZF,3dZBZnDa3z20uEVnxR38M1,0.798,0.697,0.0,-7.14,1.0,0.0891,0.0202,0.0,0.259,0.745,90.0,186964.0,4.0,-108,14,16,k-pop k-pop_girl_group pop
|
157 |
+
1IWNylpZ477gIVUDpJL66u,1HY2Jd0NmPuamShAr6KMms,05c49JgPmL4Uz2ZeqRx5SP,0.752,0.87,9.0,-3.812,0.0,0.0623,0.0604,1.12e-05,0.489,0.784,120.0,157707.0,4.0,-108,13,16,art_pop dance_pop pop
|
158 |
+
7DmP5W2DbhXC7uKYbYXtIm,790FomKkXshlbRYZFtlgla,1f2q2JQ3GFwIrWch2JLC0u,0.778,0.871,1.0,-3.18,1.0,0.0413,0.00528,0.000337,0.138,0.555,128.0,187671.0,4.0,-108,13,17,reggaeton reggaeton_colombiano trap_latino urbano_latino
|
159 |
+
21pySLskKIKrhDziCX5ojQ,6wPhSqRtPu1UhRCDX5yaDJ,7mDkWKTghwBDuHCJmH6qR5,0.671,0.685,11.0,-5.76,0.0,0.05,0.00165,0.0,0.398,0.368,118.44,245680.0,4.0,-111,14,13,dance_pop girl_group pop
|
160 |
+
5pNFibJLq7dvoDVIIcQBkn,2o5jDhtHVPhrJdv3cEQ99Z,1Pl9ZGXwayXPg5qRVpYo74,0.748,0.841,7.0,-5.08,1.0,0.177,0.00445,1.3e-06,0.0413,0.717,123.06,129817.0,4.0,-108,14,16,big_room brostep dutch_edm edm house pop_dance slap_house trance
|
161 |
+
0dlP9SnqQa5k1A9mReybFb,3Xt3RrJMFv5SZkCfUE8C1J,4rs52z8T5zPbsa5HM75tua,0.914,0.696,11.0,-4.48,0.0,0.134,0.00225,7.97e-05,0.0979,0.572,130.0,118154.0,4.0,-108,13,14,alt_z pop transpop
|
162 |
+
11mwFrKvLXCbcVGNxffGyP,1l7ZsJRRS8wlW3WfJfPfNS,6fpPZS13ImRVpr7Tqs6yP9,0.633,0.8,1.0,-6.945,1.0,0.166,0.209,0.000123,0.137,0.913,175.8,217573.0,4.0,-113,15,15,dance_pop pop
|
163 |
+
7cqlE9HPKAPpszcj5qlsqc,2RVvqRBon9NgaGXKfywDSs,7HCjmINu53BcKbTetdgERo,0.615,0.788,2.0,-6.285,1.0,0.117,0.143,0.0,0.231,0.434,123.06,225267.0,4.0,-108,13,12,alt_z uk_pop
|
164 |
+
3qGHAKgjQruzj6doKkyEb5,25uiPmTg16RbhZWAqwLBy5,2HIwUmdxEl7SeWa1ndH5wC,0.504,0.711,9.0,-5.863,1.0,0.0452,0.0585,1.83e-05,0.382,0.5,134.9,232933.0,4.0,-109,12,14,art_pop candy_pop metropopolis pop uk_pop
|
165 |
+
2qQpFbqqkLOGySgNK8wBXt,7n2Ycct7Beij7Dj7meI4X0,3aLpWFejbsdyafODLXRqwF,0.697,0.874,5.0,-2.15,0.0,0.0449,0.0122,0.0,0.627,0.775,132.0,213880.0,4.0,-109,15,15,k-pop k-pop_girl_group pop
|
166 |
+
7dnixpDdQlIOX1L7O0pdFM,1pBLC0qVRTB5zVMuteQ9jJ,6E3IPXh38G7UHLqVdfIY5h,0.621,0.543,9.0,-8.29,0.0,0.0401,0.0778,1.25e-06,0.148,0.23,112.0,199281.0,4.0,-108,14,14,pop
|
167 |
+
4LjfIjS8iweFCPdKxLnEoV,30ut8L4gmEz4vNr1zNhpbh,4nLyl2aEgi2qQrcPiFlmD7,0.762,0.754,0.0,-3.426,0.0,0.046,0.00022,0.0665,0.146,0.715,129.0,151983.0,4.0,-110,14,10,scandipop
|
168 |
+
6JjSoJ2laV4ZbKNb9nybvh,7tm9Tuc70geXOOyKhtZHIj,6fdfCmP6hJg0gqFobszTYB,0.758,0.944,3.0,-4.902,0.0,0.0623,0.0308,0.103,0.0438,0.826,126.0,247897.0,4.0,-108,13,11,bass_house house tech_house
|
169 |
+
3hlksXnvbKogFdPbpO9vel,0hCNtLu0JehylgoiP8L4Gh,7aADdYLiK1z7GlMFr0UIZw,0.723,0.86,11.0,-4.355,1.0,0.203,0.271,4.6e-06,0.598,0.667,127.0,200013.0,4.0,-110,16,16,hip_pop pop queens_hip_hop rap
|
170 |
+
2Y2q7PkD7lvuWr8YaZfWuv,4yiQZ8tQPux8cPriYMWUFP,3Lqn8M0QxPLIPRJ4nUKTGN,0.856,0.754,7.0,-2.729,0.0,0.0416,0.0294,1.49e-05,0.206,0.722,98.0,236213.0,4.0,-112,13,14,dance_pop pop
|
171 |
+
2bx879t8gUpxkQ0avl8xTf,4yiQZ8tQPux8cPriYMWUFP,3Lqn8M0QxPLIPRJ4nUKTGN,0.566,0.976,1.0,-3.865,1.0,0.262,0.000527,0.00265,0.114,0.354,194.0,222360.0,4.0,-112,12,14,dance_pop pop
|
172 |
+
7J1S5n6Kn4wZEu6xrBT0gk,2S9W9aSAd7e5mp8WqWxN2h,4DduywjewTFQCcshWzXhMh,0.62,0.915,0.0,-4.35,0.0,0.0525,0.0131,2.17e-05,0.329,0.793,127.0,242160.0,4.0,-108,12,10,dance_pop pop post-teen_pop
|
173 |
+
1k2pQc5i348DCHwbn5KTdc,7GlBOeep6PqTfFi59PTUUN,0EiI8ylL0FmWWpgHVTsZjZ,0.615,0.644,6.0,-6.16,1.0,0.0452,0.41,0.0,0.143,0.535,106.8,258035.0,4.0,-108,12,12,indie_pop springfield_mo_indie
|
174 |
+
2g1KggY9PKvsoEAOaiz4xx,3PyJHH2wyfQK3WZrk9rpmP,438ToDoVaJH5aTIXXrlDyI,0.834,0.663,8.0,-6.145,1.0,0.133,0.235,0.0,0.372,0.774,121.9,146523.0,4.0,-108,14,13,alt_z escape_room
|
175 |
+
6tS3XVuOyu10897O3ae7bi,6jJ0s89eD6GaHleKKya26X,5BvgP623rtvlc0HDcpzquz,0.791,0.754,0.0,-3.729,1.0,0.0569,0.00446,0.0,0.163,0.425,125.0,234653.0,4.0,-110,15,16,pop
|
176 |
+
2EYDqen8Pftl3ENvqOs6fE,4QM5QCHicznALtX885CnZC,62iTVhERPubeRu59a3HRqF,0.298,0.813,9.0,-8.52,0.0,0.107,0.2,3.46e-06,0.0842,0.234,99.6,237989.0,1.0,-108,12,11,escape_room hyperpop pink_noise proto-hyperpop
|
177 |
+
3oiMJQAWVaxSubJ7b2VUtX,5yG7ZAZafVaAlMTeBybKAL,5kfo2COwQYeYR3cE69aSgx,0.912,0.716,10.0,-4.14,0.0,0.0697,0.0904,0.0,0.0491,0.377,95.0,199938.0,4.0,-110,13,13,australian_hip_hop dance_pop pop
|
178 |
+
5R9a4t5t5O0IsznsrKPVro,6vWDO969PvNqNYHIOW5v0m,39P7VD7qlg3Z0ltq60eHp7,0.426,0.584,1.0,-5.293,1.0,0.296,0.0383,0.0,0.188,0.272,193.4,193213.0,4.0,-56,7,8,pop r&b
|
179 |
+
4dHRp03oxqJQfjGU8ECo7v,5cj0lLjcoR7YOSnhnX0Po5,5DQOvr3OGVd2Zq7C5H1089,0.841,0.558,2.0,-8.516,0.0,0.246,0.255,6.5e-06,0.0955,0.746,99.94,231750.0,4.0,-54,6,8,dance_pop pop
|
180 |
+
3YfS47QufnLDFA71FUsgCM,70cRZdQywnSFp9pnc2WTCE,0D1OzpaQEeiIMCAm3DUwKa,0.535,0.225,6.0,-13.87,1.0,0.0301,0.869,1.55e-06,0.0988,0.338,107.4,184787.0,4.0,-55,6,6,classic_rock folk folk_rock melancholia mellow_gold rock soft_rock
|
181 |
+
6l8GvAyoUZwWDgF1e4822w,1dfeR4HaWDbWqFHLkxsg1d,7C2DKB8C12LqxMkfJRwTo9,0.397,0.386,0.0,-10.41,0.0,0.0503,0.271,0.0,0.188,0.21,144.2,355400.0,4.0,-56,6,8,classic_rock glam_rock rock
|
182 |
+
61YM5SkqqeUjIBL7It56cs,7y97mc3bZRFXzT2szRM4L4,5aftlLJi5cmXRnPQjwUak2,0.446,0.0146,10.0,-31.05,1.0,0.12,0.991,0.945,0.116,0.0815,137.8,302269.0,1.0,-55,6,7,classical early_romantic_era polish_classical
|
183 |
+
4lhqb6JvbHId48OUJGwymk,1vCWHaC5f2uS3yhpwWbIA6,2H6i2CrWgXE1HookLu8Au0,0.545,0.78,7.0,-4.867,0.0,0.0436,0.0309,4.64e-05,0.0828,0.458,125.0,255093.0,4.0,-110,16,15,dance_pop edm pop pop_dance
|
184 |
+
7hm4HTk9encxT0LYC0J6oI,0epOFNiUfyON9EYx7Tpr6V,2k8KgmDp9oHrmu0MIj4XDE,0.539,0.521,9.0,-7.46,1.0,0.0299,0.00425,0.0,0.367,0.679,106.06,183440.0,4.0,-112,14,14,alternative_rock garage_rock modern_rock permanent_wave rock
|
data/sc.sav
ADDED
Binary file (1.09 kB). View file
|
|
data/streamlit.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:11ec2a21e4cfebf994cef0b99d447bdb5f1d918a217a64094cb3f97eeea8364d
|
3 |
+
size 187306088
|
main.py
ADDED
@@ -0,0 +1,436 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from streamlit_option_menu import option_menu
|
3 |
+
import streamlit.components.v1 as components
|
4 |
+
import time
|
5 |
+
from model import *
|
6 |
+
from Explanations.mistral import MistralExplainer, mistral_2_display
|
7 |
+
from Explanations.llama2 import Llama2Explainer
|
8 |
+
from streamlit_modal import Modal
|
9 |
+
|
10 |
+
if 'model' not in st.session_state:
|
11 |
+
st.session_state.model = 'Model 1'
|
12 |
+
def update_radio2():
|
13 |
+
st.session_state.explanation_length=st.session_state.radio2
|
14 |
+
if 'genre' not in st.session_state:
|
15 |
+
st.session_state.genre=3
|
16 |
+
def update_num_genre():
|
17 |
+
st.session_state.genre=st.session_state.num_genre
|
18 |
+
if 'artist' not in st.session_state:
|
19 |
+
st.session_state.artist=1
|
20 |
+
def update_same_art():
|
21 |
+
st.session_state.artist=st.session_state.same_art
|
22 |
+
if 'model2' not in st.session_state:
|
23 |
+
st.session_state.model2= 'Spotify model'
|
24 |
+
def update_radio1():
|
25 |
+
st.session_state.model2 =st.session_state.radio1
|
26 |
+
|
27 |
+
if 'Region' not in st.session_state:
|
28 |
+
st.session_state.rg="US"
|
29 |
+
def update_Region():
|
30 |
+
st.session_state.rg=st.session_state.Region
|
31 |
+
if 'radio' not in st.session_state:
|
32 |
+
st.session_state.feature="Song"
|
33 |
+
def update_radio0():
|
34 |
+
st.session_state.feature=st.session_state.radio
|
35 |
+
|
36 |
+
if 'p_url' not in st.session_state:
|
37 |
+
st.session_state.p_url = 'Example: https://open.spotify.com/playlist/37i9dQZF1DX45grRWk2ghU?si=3f2b42b40d59449d'
|
38 |
+
def update_playlist_url():
|
39 |
+
st.session_state.p_url = st.session_state.playlist_url
|
40 |
+
|
41 |
+
if 's_url' not in st.session_state:
|
42 |
+
st.session_state.s_url = 'Example: https://open.spotify.com/track/7hm4HTk9encxT0LYC0J6oI?si=cc4c8b502e2748c5'
|
43 |
+
def update_song_url():
|
44 |
+
st.session_state.s_url = st.session_state.song_url
|
45 |
+
|
46 |
+
if 'a_url' not in st.session_state:
|
47 |
+
st.session_state.a_url = 'Example: https://open.spotify.com/artist/3RNrq3jvMZxD9ZyoOZbQOD?si=UNAsX20kRpG89bxOO8o7ew'
|
48 |
+
def update_artist_url():
|
49 |
+
st.session_state.a_url = st.session_state.artist_url
|
50 |
+
if 'selected_option' not in st.session_state:
|
51 |
+
st.session_state.selected_option = None
|
52 |
+
def update_selectbox():
|
53 |
+
st.session_state.selected_option = st.session_state.select_box
|
54 |
+
|
55 |
+
if 'button_states' not in st.session_state:
|
56 |
+
st.session_state.button_states = {}
|
57 |
+
|
58 |
+
if 'track_list' not in st.session_state:
|
59 |
+
st.session_state.track_list = []
|
60 |
+
|
61 |
+
if 'radio_choice' not in st.session_state:
|
62 |
+
st.session_state.radio_choice = None
|
63 |
+
if 'explanation_length' not in st.session_state:
|
64 |
+
st.session_state.explanation_length = 'Succinct'
|
65 |
+
|
66 |
+
if 'selected_song_index' not in st.session_state:
|
67 |
+
st.session_state.selected_song_index = 0
|
68 |
+
|
69 |
+
song_list = [{"title": "The Strokes - Someday", "uri" : "https://open.spotify.com/track/7hm4HTk9encxT0LYC0J6oI?si=9d23a7470dfb4330", "next_five": ['Figure It Out by Royal Blood', 'Joker And The Thief by Wolfmother', 'Heads Will Roll - A-Trak Remix Radio Edit by Yeah Yeah Yeahs', 'Hate To Say I Told You So by The Hives', 'Get Free by The Vines']},
|
70 |
+
{"title": "Doja Cat - Paint the Town Red", "uri" : "https://open.spotify.com/track/4dHRp03oxqJQfjGU8ECo7v?si=75a8b6b9ae304963", "next_five":["I'm Good (Blue) by David Guetta", 'Dance The Night - From Barbie The Album by Dua Lipa', 'Super Shy by NewJeans', 'Snooze by SZA', 'Watermelon Sugar by Harry Styles']},
|
71 |
+
{"title": "Beyonce - Single Ladies","uri":"https://open.spotify.com/track/5R9a4t5t5O0IsznsrKPVro?si=d7f7f6b342b446c8", "next_five": ['Locked out of Heaven by Bruno Mars', '...Baby One More Time by Britney Spears', 'I Wanna Dance with Somebody (Who Loves Me) by Whitney Houston', 'Disturbia by Rihanna', 'Too Good At Goodbyes by Sam Smith']},
|
72 |
+
{"title": "Dolly Parton - Jolene","uri":"https://open.spotify.com/track/2SpEHTbUuebeLkgs9QB7Ue?si=ab915579c1244a5f", "next_five":['Wide Open Spaces by The Chicks', 'Blue Eyes Crying In the Rain by Willie Nelson', 'Need You Now by Lady A', "Mama's Broken Heart by Miranda Lambert", "She's In Love With The Boy - Single Version by Trisha Yearwood"]},
|
73 |
+
{"title": "Taylor Swift - Lavender Haze","uri":"https://open.spotify.com/track/5jQI2r1RdgtuT8S3iG8zFC?si=5922d57584b84382", "next_five":['Dance The Night - From Barbie The Album by Dua Lipa', "I'm Good (Blue) by David Guetta", 'Perfect by Ed Sheeran', "Doin' Time by Lana Del Rey", 'Sweater Weather by The Neighbourhood']},
|
74 |
+
{"title": "Lincoln Park - What I've Done","uri":"https://open.spotify.com/track/2nLtzopw4rPReszdYBJU6h?si=1b48d972e12d43e7", "next_five":['Higher by Creed', 'Drive by Incubus', 'I Hate Everything About You by Three Days Grace', 'The Reason by Hoobastank', 'Butterfly by Crazy Town']},
|
75 |
+
{"title": "Avicii - Hey Brother","uri":"https://open.spotify.com/track/4lhqb6JvbHId48OUJGwymk?si=d148732daa8e4897", "next_five": ['Silence by Marshmello', 'Sugar (feat. Francesco Yates) by Robin Schulz', 'Where Did You Go? (feat. MNEK) by Jax Jones', 'Rockabye (feat. Sean Paul & Anne-Marie) by Clean Bandit', 'Lush Life by Zara Larsson']},
|
76 |
+
{"title": "Simon & Garfunkel - Sound of Silence","uri":"https://open.spotify.com/track/3YfS47QufnLDFA71FUsgCM?si=5bff00bb3b2e4a67", "next_five": ['American Pie by Don McLean', 'The Weight - Remastered 2000 by The Band', "You're So Vain by Carly Simon", "Do You Believe in Magic? by The Lovin' Spoonful", "You've Got a Friend by Carole King"]},
|
77 |
+
{"title": "Queen - Bohemian Rhapsody","uri":"https://open.spotify.com/track/6l8GvAyoUZwWDgF1e4822w?si=9639498e177d46e6", "next_five": ['You Really Got Me by The Kinks', 'Walk On the Wild Side by Lou Reed', 'In The Army Now by Status Quo', 'Surrender by Cheap Trick', 'More Than This by Roxy Music']},
|
78 |
+
{"title": "Frédéric Chopin - Nocturnes Op. 9 N. 2","uri":"https://open.spotify.com/track/61YM5SkqqeUjIBL7It56cs?si=01a05e921c61409b", "next_five":['5 Stücke im Volkston', 'Op. 102: II. Langsam by Robert Schumann', 'Paganini: 24 Caprices', 'Op. 1: No. 24 in A Minor by Niccolò Paganini', 'I puritani / Act I: A te', 'o cara by Vincenzo Bellini', 'Strauss I: Radetzky March', 'Op. 228 by Johann Strauss I', 'Clarinet Concerto No. 1 in F Minor', 'Op. 73: III. Rondo: Allegretto by Carl Maria von Weber', 'Scherzo-tarantelle in G Minor', 'Op.16 - 1987 Remastered Version by Henryk Wieniawski']}
|
79 |
+
]
|
80 |
+
|
81 |
+
def play_recomm():
|
82 |
+
if 'rs' in st.session_state:
|
83 |
+
del st.session_state.rs,st.session_state.err
|
84 |
+
try:
|
85 |
+
if len(pd.read_csv('data/new_tracks.csv')) >= 200:
|
86 |
+
with st.spinner('Updating the dataset...'):
|
87 |
+
x=update_dataset()
|
88 |
+
st.success('{} New tracks were added to the dataset.'.format(x))
|
89 |
+
except:
|
90 |
+
st.error("The dataset update failed. ")
|
91 |
+
with st.spinner('Getting Recommendations...'):
|
92 |
+
res,err = playlist_model(st.session_state.p_url,st.session_state.model,st.session_state.genre,st.session_state.artist)
|
93 |
+
st.session_state.rs=res
|
94 |
+
st.session_state.err=err
|
95 |
+
if len(st.session_state.rs)>=1:
|
96 |
+
if st.session_state.model == 'Model 1' or st.session_state.model == 'Model 2':
|
97 |
+
st.success('Go to the Recommended page to view the top {} recommendations'.format(len(st.session_state.rs)))
|
98 |
+
# print(st.session_state.rs)
|
99 |
+
else:
|
100 |
+
st.success('Go to the Recommended page to view the Spotify recommendations')
|
101 |
+
else:
|
102 |
+
st.error('Model failed. Check the log for more information.')
|
103 |
+
|
104 |
+
def art_recomm():
|
105 |
+
if 'rs' in st.session_state:
|
106 |
+
del st.session_state.rs,st.session_state.err
|
107 |
+
with st.spinner('Getting Recommendations...'):
|
108 |
+
res,err = top_tracks(st.session_state.a_url,st.session_state.rg)
|
109 |
+
st.session_state.rs=res
|
110 |
+
st.session_state.err=err
|
111 |
+
if len(st.session_state.rs)>=1:
|
112 |
+
st.success("Go to the Recommended page to view the Artist's top tracks")
|
113 |
+
else:
|
114 |
+
st.error('Model failed. Check the log for more information.')
|
115 |
+
|
116 |
+
def song_recomm():
|
117 |
+
if 'rs' in st.session_state:
|
118 |
+
del st.session_state.rs,st.session_state.err
|
119 |
+
with st.spinner('Getting Recommendations...'):
|
120 |
+
res,err = song_model(st.session_state.s_url,st.session_state.model,st.session_state.genre,st.session_state.artist)
|
121 |
+
st.session_state.rs=res
|
122 |
+
st.session_state.err=err
|
123 |
+
if len(st.session_state.rs)>=1:
|
124 |
+
if st.session_state.model == 'Model 1' or st.session_state.model == 'Model 2':
|
125 |
+
st.success('Go to the Recommended page to view the top {} recommendations'.format(len(st.session_state.rs)))
|
126 |
+
else:
|
127 |
+
st.success('Go to the Recommended page to view the Spotify recommendations')
|
128 |
+
else:
|
129 |
+
st.error('Model failed. Check the log for more information.')
|
130 |
+
|
131 |
+
def playlist_page():
|
132 |
+
st.subheader("User Playlist")
|
133 |
+
st.markdown('---')
|
134 |
+
playlist_uri = (st.session_state.playlist_url).split('/')[-1].split('?')[0]
|
135 |
+
uri_link = 'https://open.spotify.com/embed/playlist/' + playlist_uri
|
136 |
+
components.iframe(uri_link, height=180)
|
137 |
+
return
|
138 |
+
...
|
139 |
+
def song_page():
|
140 |
+
st.subheader("Select your favorite song from the list below:")
|
141 |
+
st.markdown('---')
|
142 |
+
|
143 |
+
titles = [song['title'] for song in song_list] # Get a list of song titles
|
144 |
+
|
145 |
+
selected_title = st.selectbox('Select a song', titles)
|
146 |
+
|
147 |
+
# Find the selected song in the song list
|
148 |
+
selected_song = next((song for song in song_list if song['title'] == selected_title), None)
|
149 |
+
if selected_song:
|
150 |
+
st.session_state.selected_song_index = selected_title
|
151 |
+
# print(st.session_state.selected_song_index)
|
152 |
+
song_uri = selected_song['uri']
|
153 |
+
st.session_state.s_url = song_uri
|
154 |
+
|
155 |
+
uri_link = 'https://open.spotify.com/embed/track/' + song_uri.split('/')[-1].split('?')[0]
|
156 |
+
# slot1 = st.empty()
|
157 |
+
components.iframe(uri_link, height=100)
|
158 |
+
|
159 |
+
def artist_page():
|
160 |
+
st.subheader("User Artist")
|
161 |
+
st.markdown('---')
|
162 |
+
artist_uri = (st.session_state.artist_url).split('/')[-1].split('?')[0]
|
163 |
+
uri_link = 'https://open.spotify.com/embed/artist/' + artist_uri
|
164 |
+
components.iframe(uri_link, height=80)
|
165 |
+
|
166 |
+
def spr_sidebar():
|
167 |
+
menu=option_menu(
|
168 |
+
menu_title=None,
|
169 |
+
options=['Home','Recommended','Explanation','Counter'],
|
170 |
+
icons=['house','lightbulb','heart','heart-half'],
|
171 |
+
menu_icon='cast',
|
172 |
+
default_index=0,
|
173 |
+
orientation='horizontal'
|
174 |
+
)
|
175 |
+
if menu=='Home':
|
176 |
+
st.session_state.app_mode = 'Home'
|
177 |
+
elif menu=='Recommended':
|
178 |
+
st.session_state.app_mode = 'Recommended'
|
179 |
+
elif menu=='About':
|
180 |
+
st.session_state.app_mode = 'About'
|
181 |
+
elif menu=='Explanation':
|
182 |
+
st.session_state.app_mode = 'Explanation'
|
183 |
+
elif menu=='Log':
|
184 |
+
st.session_state.app_mode = 'Log'
|
185 |
+
elif menu=='Counter':
|
186 |
+
st.session_state.app_mode = 'Counter'
|
187 |
+
|
188 |
+
def home_page():
|
189 |
+
st.session_state.radio=st.session_state.feature
|
190 |
+
st.session_state.num_genre=st.session_state.genre
|
191 |
+
st.session_state.same_art=st.session_state.artist
|
192 |
+
st.session_state.Region=st.session_state.rg
|
193 |
+
|
194 |
+
st.title('Spotify Recommendation System')
|
195 |
+
col2,col3=st.columns([2,2])
|
196 |
+
# radio=col.radio("Feature",options=("Playlist","Song"),key='radio',on_change=update_radio0)
|
197 |
+
radio2=col2.radio("Group Assignment",options=("Succinct","Verbose"),key='radio2',on_change=update_radio2)
|
198 |
+
|
199 |
+
st.markdown("<br>", unsafe_allow_html=True)
|
200 |
+
|
201 |
+
# Check if 'df' and 'selected_option' are in the session state
|
202 |
+
if 'df' in st.session_state and 'selected_option' in st.session_state:
|
203 |
+
df = st.session_state.df
|
204 |
+
selected_item = df[df["Name"] == st.session_state.selected_option].iloc[0]
|
205 |
+
|
206 |
+
st.write("Selected Name:", selected_item["Name"])
|
207 |
+
st.write("Selected Artist:", selected_item["Artist"])
|
208 |
+
st.write("Selected URI:", selected_item["URI"])
|
209 |
+
|
210 |
+
st.session_state.radio_choice = "Song"
|
211 |
+
st.session_state.song_url = st.session_state.s_url
|
212 |
+
# Url = st.text_input(label="Song Url",key='song_url',on_change=update_song_url)
|
213 |
+
song_page()
|
214 |
+
state =st.button('Generate Recommendations')
|
215 |
+
# with st.expander("Here's how to find any Song URL in Spotify"):
|
216 |
+
# st.write("""
|
217 |
+
# - Search for Song on the Spotify app
|
218 |
+
# - Right Click on the Song you like
|
219 |
+
# - Click "Share"
|
220 |
+
# - Choose "Copy link to Song"
|
221 |
+
# """)
|
222 |
+
# st.markdown("<br>", unsafe_allow_html=True)
|
223 |
+
# st.image('spotify_get_song_url.png')
|
224 |
+
if state:
|
225 |
+
song_recomm()
|
226 |
+
|
227 |
+
def result_page():
|
228 |
+
if 'rs' not in st.session_state:
|
229 |
+
st.error('Please select a model on the Home page and run "Generate Recommendations"')
|
230 |
+
else:
|
231 |
+
st.success('Top {} recommendations'.format(len(st.session_state.rs)))
|
232 |
+
i=0
|
233 |
+
tracks = []
|
234 |
+
original_tracks = []
|
235 |
+
length_of_explanation = 1
|
236 |
+
for uri in st.session_state.rs:
|
237 |
+
uri_link = "https://open.spotify.com/embed/track/" + uri + "?utm_source=generator&theme=0"
|
238 |
+
components.iframe(uri_link, height=80)
|
239 |
+
|
240 |
+
# Create a button for each URI and store its state
|
241 |
+
if uri not in st.session_state.button_states:
|
242 |
+
st.session_state.button_states[uri] = False
|
243 |
+
|
244 |
+
track_name, artist_name = get_track_info(uri)
|
245 |
+
tracks.append({'track_name': track_name, 'artist_name': artist_name, 'uri': uri})
|
246 |
+
st.session_state.button_states[uri] = st.button('Get explanation for {}'.format(track_name))
|
247 |
+
st.spinner('Getting explanation...')
|
248 |
+
|
249 |
+
# When button is clicked, call get_track_info
|
250 |
+
if st.session_state.button_states[uri]:
|
251 |
+
with st.spinner('Getting explanation...'):
|
252 |
+
if st.session_state.radio_choice == 'Song':
|
253 |
+
track, artist = get_track_info(uri)
|
254 |
+
print(track, artist)
|
255 |
+
|
256 |
+
songlist = [{'track_name': track, 'artist_name': artist}]
|
257 |
+
if st.session_state.explanation_length == "Verbose":
|
258 |
+
length_of_explanation = 5
|
259 |
+
else:
|
260 |
+
length_of_explanation = 1
|
261 |
+
|
262 |
+
st.session_state.explanation_status = True
|
263 |
+
# mistral.explain_why(original_songs=songlist, top_songs=st.session_state.track_list, explanation_limit=length_of_explanation)
|
264 |
+
# explanation = mistral_2_display(mistral.get_positive_explanations())
|
265 |
+
# print(explanation)
|
266 |
+
|
267 |
+
# track_name, artist_name = get_track_info(uri)
|
268 |
+
# st.write('Track Name:', track_name)
|
269 |
+
# st.write('Artist Name:', artist_name)
|
270 |
+
|
271 |
+
i+=1
|
272 |
+
# st.session_state.track_list = tracks
|
273 |
+
# formatted_string = ''
|
274 |
+
# for item in st.session_state.track_list:
|
275 |
+
# formatted_string += '{} by {}, '.format(item['track_name'], item['artist_name'])
|
276 |
+
# songs = formatted_string.rstrip(', ')
|
277 |
+
|
278 |
+
# # Split the string into a list of songs
|
279 |
+
# song_list = songs.split(", ")
|
280 |
+
|
281 |
+
# # Calculate the midpoint index
|
282 |
+
# midpoint = len(song_list) // 2
|
283 |
+
|
284 |
+
# # Get the top and bottom halves of the list
|
285 |
+
# top_half = song_list[:midpoint]
|
286 |
+
# bottom_half = song_list[midpoint:]
|
287 |
+
|
288 |
+
# # Print the top and bottom halves
|
289 |
+
# print("Top half:")
|
290 |
+
# print(top_half)
|
291 |
+
# print("Bottom half:")
|
292 |
+
# print(bottom_half)
|
293 |
+
if i%5==0:
|
294 |
+
time.sleep(1)
|
295 |
+
|
296 |
+
def Explain_page():
|
297 |
+
if 'explanation_status' not in st.session_state:
|
298 |
+
st.error('Please select the "Get Explanation" button under one of the recommended tracks.')
|
299 |
+
else:
|
300 |
+
st.success('Explanation generated below for the selected track.')
|
301 |
+
for track_explanation in st.session_state.explanation_status:
|
302 |
+
st.text(track_explanation)
|
303 |
+
|
304 |
+
def Counter_page():
|
305 |
+
if 'explanation_status' not in st.session_state:
|
306 |
+
st.error('Please select the "Get Explanation" button under one of the recommended tracks.')
|
307 |
+
else:
|
308 |
+
st.header('Understanding Recommendations')
|
309 |
+
st.markdown("<br>", unsafe_allow_html=True)
|
310 |
+
st.subheader('Please select a song from the list below that you believe should have been recommended in the top 5 songs for your original selection.')
|
311 |
+
|
312 |
+
next_five = None
|
313 |
+
for song in song_list:
|
314 |
+
if song["title"] == st.session_state.selected_song_index:
|
315 |
+
next_five = song["next_five"]
|
316 |
+
break
|
317 |
+
|
318 |
+
selected_title = st.selectbox('Select a song', next_five)
|
319 |
+
|
320 |
+
counter_fact_button = st.button('Generate Explanation')
|
321 |
+
|
322 |
+
if counter_fact_button:
|
323 |
+
None
|
324 |
+
# Generate the counter factual example
|
325 |
+
|
326 |
+
def Log_page():
|
327 |
+
log=st.checkbox('Display Output', True, key='display_output')
|
328 |
+
if log == True:
|
329 |
+
if 'err' in st.session_state:
|
330 |
+
st.write(st.session_state.err)
|
331 |
+
with open('data/streamlit.csv') as f:
|
332 |
+
st.download_button('Download Dataset', f,file_name='streamlit.csv')
|
333 |
+
def About_page():
|
334 |
+
st.header('Development')
|
335 |
+
"""
|
336 |
+
Check out the [repository](https://github.com/abdelrhmanelruby/Spotify-Recommendation-System) for the source code and approaches, and don't hesitate to contact me if you have any questions. I'm excited to read your review.
|
337 |
+
[Github](https://github.com/abdelrhmanelruby) [Linkedin](https://www.linkedin.com/in/abdelrhmanelruby/) Email : abdelrhmanelruby@gmail.com
|
338 |
+
"""
|
339 |
+
st.subheader('Spotify Million Playlist Dataset')
|
340 |
+
"""
|
341 |
+
For this project, I'm using the Million Playlist Dataset, which, as its name implies, consists of one million playlists.
|
342 |
+
contains a number of songs, and some metadata is included as well, such as the name of the playlist, duration, number of songs, number of artists, etc.
|
343 |
+
"""
|
344 |
+
|
345 |
+
"""
|
346 |
+
It is created by sampling playlists from the billions of playlists that Spotify users have created over the years.
|
347 |
+
Playlists that meet the following criteria were selected at random:
|
348 |
+
- Created by a user that resides in the United States and is at least 13 years old
|
349 |
+
- Was a public playlist at the time the MPD was generated
|
350 |
+
- Contains at least 5 tracks
|
351 |
+
- Contains no more than 250 tracks
|
352 |
+
- Contains at least 3 unique artists
|
353 |
+
- Contains at least 2 unique albums
|
354 |
+
- Has no local tracks (local tracks are non-Spotify tracks that a user has on their local device
|
355 |
+
- Has at least one follower (not including the creator
|
356 |
+
- Was created after January 1, 2010 and before December 1, 2017
|
357 |
+
- Does not have an offensive title
|
358 |
+
- Does not have an adult-oriented title if the playlist was created by a user under 18 years of age
|
359 |
+
|
360 |
+
Information about the Dataset [here](https://www.aicrowd.com/challenges/spotify-million-playlist-dataset-challenge)
|
361 |
+
"""
|
362 |
+
st.subheader('Audio Features Explanation')
|
363 |
+
"""
|
364 |
+
| Variable | Description |
|
365 |
+
| :----: | :---: |
|
366 |
+
| Acousticness | A confidence measure from 0.0 to 1.0 of whether the track is acoustic. 1.0 represents high confidence the track is acoustic. |
|
367 |
+
| Danceability | Danceability describes how suitable a track is for dancing based on a combination of musical elements including tempo, rhythm stability, beat strength, and overall regularity. A value of 0.0 is least danceable and 1.0 is most danceable. |
|
368 |
+
| Energy | Energy is a measure from 0.0 to 1.0 and represents a perceptual measure of intensity and activity. Typically, energetic tracks feel fast, loud, and noisy. For example, death metal has high energy, while a Bach prelude scores low on the scale. Perceptual features contributing to this attribute include dynamic range, perceived loudness, timbre, onset rate, and general entropy. |
|
369 |
+
| Instrumentalness | Predicts whether a track contains no vocals. "Ooh" and "aah" sounds are treated as instrumental in this context. Rap or spoken word tracks are clearly "vocal". The closer the instrumentalness value is to 1.0, the greater likelihood the track contains no vocal content. Values above 0.5 are intended to represent instrumental tracks, but confidence is higher as the value approaches 1.0. |
|
370 |
+
| Key | The key the track is in. Integers map to pitches using standard Pitch Class notation. E.g. 0 = C, 1 = C♯/D♭, 2 = D, and so on. If no key was detected, the value is -1. |
|
371 |
+
| Liveness | Detects the presence of an audience in the recording. Higher liveness values represent an increased probability that the track was performed live. A value above 0.8 provides strong likelihood that the track is live. |
|
372 |
+
| Loudness | The overall loudness of a track in decibels (dB). Loudness values are averaged across the entire track and are useful for comparing relative loudness of tracks. Loudness is the quality of a sound that is the primary psychological correlate of physical strength (amplitude). Values typically range between -60 and 0 db. |
|
373 |
+
| Mode | Mode indicates the modality (major or minor) of a track, the type of scale from which its melodic content is derived. Major is represented by 1 and minor is 0. |
|
374 |
+
| Speechiness | Speechiness detects the presence of spoken words in a track. The more exclusively speech-like the recording (e.g. talk show, audio book, poetry), the closer to 1.0 the attribute value. Values above 0.66 describe tracks that are probably made entirely of spoken words. Values between 0.33 and 0.66 describe tracks that may contain both music and speech, either in sections or layered, including such cases as rap music. Values below 0.33 most likely represent music and other non-speech-like tracks. |
|
375 |
+
| Tempo | The overall estimated tempo of a track in beats per minute (BPM). In musical terminology, tempo is the speed or pace of a given piece and derives directly from the average beat duration. |
|
376 |
+
| Time Signature | An estimated time signature. The time signature (meter) is a notational convention to specify how many beats are in each bar (or measure). The time signature ranges from 3 to 7 indicating time signatures of "3/4", to "7/4". |
|
377 |
+
| Valence | A measure from 0.0 to 1.0 describing the musical positiveness conveyed by a track. Tracks with high valence sound more positive (e.g. happy, cheerful, euphoric), while tracks with low valence sound more negative (e.g. sad, depressed, angry). |
|
378 |
+
|
379 |
+
Information about features: [here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-audio-features)
|
380 |
+
"""
|
381 |
+
|
382 |
+
|
383 |
+
# def dialog_close_button_clicked():
|
384 |
+
# st.write("### Dialog close callback results:")
|
385 |
+
# st.write("#### No preferences saved!")
|
386 |
+
# dialog.close()
|
387 |
+
|
388 |
+
|
389 |
+
# dialog = st.dialog(
|
390 |
+
# "first_dialog_with_help", title="Group Assignment",
|
391 |
+
# on_close_button_clicked=dialog_close_button_clicked, can_be_closed=True)
|
392 |
+
|
393 |
+
|
394 |
+
# def dialog_form_submit_button_clicked():
|
395 |
+
# st.write("### Dialog form submit button clicked results:")
|
396 |
+
# st.write(f"#### Hey {st.session_state.first_name} {st.session_state.last_name}!")
|
397 |
+
# st.write(f"#### Your preferences are saved")
|
398 |
+
# dialog.close()
|
399 |
+
|
400 |
+
|
401 |
+
# with dialog:
|
402 |
+
# st.radio("Explanation Length",options=("Succinct","Verbose"),key='radio2',on_change=update_radio2)
|
403 |
+
# st.text_input("First name", key="first_name")
|
404 |
+
# st.text_input("Last name", key="last_name")
|
405 |
+
# st.form_submit_button("OK", on_click=dialog_form_submit_button_clicked)
|
406 |
+
|
407 |
+
|
408 |
+
# if st.button("Open dialog", key="first_dialog_button"):
|
409 |
+
# dialog.open()
|
410 |
+
|
411 |
+
# modal = Modal("Demo Modal", key="example")
|
412 |
+
# open_modal = st.button("Open")
|
413 |
+
# if open_modal:
|
414 |
+
# modal.open()
|
415 |
+
|
416 |
+
# if modal.is_open():
|
417 |
+
# with modal.container():
|
418 |
+
# st.write("Text goes here")
|
419 |
+
# st.radio("Explanation Length",options=("Succinct","Verbose"),key='radio3',on_change=update_radio2)
|
420 |
+
# st.write("Some fancy text")
|
421 |
+
|
422 |
+
def main():
|
423 |
+
spr_sidebar()
|
424 |
+
if st.session_state.app_mode == 'Home':
|
425 |
+
home_page()
|
426 |
+
if st.session_state.app_mode == 'Recommended':
|
427 |
+
result_page()
|
428 |
+
# if st.session_state.app_mode == 'About':
|
429 |
+
# About_page()
|
430 |
+
if st.session_state.app_mode == 'Counter':
|
431 |
+
Counter_page()
|
432 |
+
if st.session_state.app_mode == 'Explanation':
|
433 |
+
Explain_page()
|
434 |
+
# Run main()
|
435 |
+
if __name__ == '__main__':
|
436 |
+
main()
|
model.py
ADDED
@@ -0,0 +1,606 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import spotipy
|
3 |
+
from spotipy.oauth2 import SpotifyOAuth, SpotifyClientCredentials
|
4 |
+
import yaml
|
5 |
+
import re
|
6 |
+
from sklearn.feature_extraction.text import TfidfVectorizer
|
7 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
8 |
+
from sklearn.preprocessing import MinMaxScaler
|
9 |
+
import pickle
|
10 |
+
import streamlit as st
|
11 |
+
import os
|
12 |
+
import dotenv
|
13 |
+
dotenv.load_dotenv()
|
14 |
+
|
15 |
+
spotify_client_id = os.getenv("CLIENT_ID")
|
16 |
+
spotify_client_secret = os.getenv("CLIENT_SECRET")
|
17 |
+
|
18 |
+
def get_track_info(track_uri):
|
19 |
+
stream = open("Spotify.yaml")
|
20 |
+
spotify_details = yaml.safe_load(stream)
|
21 |
+
auth_manager = SpotifyClientCredentials(client_id=spotify_client_id, client_secret=spotify_client_secret)
|
22 |
+
|
23 |
+
sp = spotipy.client.Spotify(auth_manager=auth_manager)
|
24 |
+
|
25 |
+
# Get track information
|
26 |
+
track_info = sp.track(track_uri)
|
27 |
+
|
28 |
+
# Extract track name and artist name
|
29 |
+
track_name = track_info['name']
|
30 |
+
artist_name = track_info['artists'][0]['name']
|
31 |
+
|
32 |
+
# Return the track name and artist name
|
33 |
+
return track_name, artist_name
|
34 |
+
|
35 |
+
def get_track_names(playlist_id):
|
36 |
+
track_names = []
|
37 |
+
|
38 |
+
stream = open("Spotify.yaml")
|
39 |
+
spotify_details = yaml.safe_load(stream)
|
40 |
+
auth_manager = SpotifyClientCredentials(client_id=spotify_client_id, client_secret=spotify_client_secret)
|
41 |
+
|
42 |
+
sp = spotipy.client.Spotify(auth_manager=auth_manager)
|
43 |
+
|
44 |
+
# Get playlist
|
45 |
+
playlist = sp.playlist(playlist_id)
|
46 |
+
|
47 |
+
# Extract track names
|
48 |
+
for item in playlist['tracks']['items']:
|
49 |
+
track = item['track']
|
50 |
+
track_name = track['name']
|
51 |
+
artists = [artist['name'] for artist in track['artists']]
|
52 |
+
track_names.append({'track_name': track_name, 'artist_name': artists[0]})
|
53 |
+
|
54 |
+
return track_names
|
55 |
+
|
56 |
+
def parse_results(results):
|
57 |
+
# Initialize lists to store results
|
58 |
+
names = []
|
59 |
+
artists = []
|
60 |
+
uris = []
|
61 |
+
|
62 |
+
# Loop through each track in the results
|
63 |
+
for idx, item in enumerate(results['tracks']['items']):
|
64 |
+
names.append(item['name'])
|
65 |
+
artists.append(item['artists'][0]['name'])
|
66 |
+
uris.append(item['uri'])
|
67 |
+
|
68 |
+
# Create a DataFrame
|
69 |
+
df = pd.DataFrame({
|
70 |
+
'Name': names,
|
71 |
+
'Artist': artists,
|
72 |
+
'URI': uris
|
73 |
+
})
|
74 |
+
|
75 |
+
return df
|
76 |
+
|
77 |
+
|
78 |
+
def search_spotify(query):
|
79 |
+
log = []
|
80 |
+
try:
|
81 |
+
log.append('spotify local method')
|
82 |
+
stream = open("Spotify.yaml")
|
83 |
+
spotify_details = yaml.safe_load(stream)
|
84 |
+
auth_manager = SpotifyClientCredentials(client_id=spotify_client_id, client_secret=spotify_client_secret)
|
85 |
+
except:
|
86 |
+
log.append('spotify .streamlit method')
|
87 |
+
try:
|
88 |
+
Client_id=st.secrets["Client_ID"]
|
89 |
+
client_secret=st.secrets["Client_secret"]
|
90 |
+
auth_manager = SpotifyClientCredentials(client_id=Client_id, client_secret=client_secret)
|
91 |
+
except:
|
92 |
+
log.append('spotify hug method')
|
93 |
+
Client_id=os.environ['Client_ID']
|
94 |
+
client_secret=os.environ['Client_secret']
|
95 |
+
auth_manager = SpotifyClientCredentials(client_id=Client_id, client_secret=client_secret)
|
96 |
+
sp = spotipy.client.Spotify(auth_manager=auth_manager)
|
97 |
+
results = sp.search(q=query, type='track,playlist')
|
98 |
+
return results
|
99 |
+
|
100 |
+
def playlist_model(url, model, max_gen=3, same_art=5):
|
101 |
+
log = []
|
102 |
+
Fresult = []
|
103 |
+
try:
|
104 |
+
log.append('Start logging')
|
105 |
+
uri = url.split('/')[-1].split('?')[0]
|
106 |
+
try:
|
107 |
+
log.append('spotify local method')
|
108 |
+
stream = open("Spotify.yaml")
|
109 |
+
spotify_details = yaml.safe_load(stream)
|
110 |
+
auth_manager = SpotifyClientCredentials(client_id=spotify_client_id, client_secret=spotify_client_secret)
|
111 |
+
except:
|
112 |
+
log.append('spotify .streamlit method')
|
113 |
+
try:
|
114 |
+
Client_id=st.secrets["Client_ID"]
|
115 |
+
client_secret=st.secrets["Client_secret"]
|
116 |
+
auth_manager = SpotifyClientCredentials(client_id=Client_id, client_secret=client_secret)
|
117 |
+
except:
|
118 |
+
log.append('spotify hug method')
|
119 |
+
Client_id=os.environ['Client_ID']
|
120 |
+
client_secret=os.environ['Client_secret']
|
121 |
+
auth_manager = SpotifyClientCredentials(client_id=Client_id, client_secret=client_secret)
|
122 |
+
sp = spotipy.client.Spotify(auth_manager=auth_manager)
|
123 |
+
|
124 |
+
if model == 'Spotify Model':
|
125 |
+
def get_IDs(user, playlist_id):
|
126 |
+
try:
|
127 |
+
log.append('start playlist extraction')
|
128 |
+
track_ids = []
|
129 |
+
playlist = sp.user_playlist(user, playlist_id)
|
130 |
+
for item in playlist['tracks']['items']:
|
131 |
+
track = item['track']
|
132 |
+
track_ids.append(track['id'])
|
133 |
+
return track_ids
|
134 |
+
except Exception as e:
|
135 |
+
log.append('Failed to load the playlist')
|
136 |
+
log.append(e)
|
137 |
+
|
138 |
+
track_ids = get_IDs('Ruby', uri)
|
139 |
+
track_ids_uni = list(set(track_ids))
|
140 |
+
log.append('Starting Spotify Model')
|
141 |
+
Spotifyresult = pd.DataFrame()
|
142 |
+
for i in range(len(track_ids_uni)-5):
|
143 |
+
if len(Spotifyresult) >= 5:
|
144 |
+
break
|
145 |
+
try:
|
146 |
+
ff = sp.recommendations(seed_tracks=list(track_ids_uni[i:i+5]), limit=5)
|
147 |
+
except Exception as e:
|
148 |
+
log.append(e)
|
149 |
+
continue
|
150 |
+
for z in range(5):
|
151 |
+
result = pd.DataFrame([z+(5*i)+1])
|
152 |
+
result['uri'] = ff['tracks'][z]['id']
|
153 |
+
Spotifyresult = pd.concat([Spotifyresult, result], axis=0)
|
154 |
+
Spotifyresult.drop_duplicates(subset=['uri'], inplace=True,keep='first')
|
155 |
+
Fresult = Spotifyresult.uri[:5]
|
156 |
+
|
157 |
+
log.append('Model run successfully')
|
158 |
+
return Fresult, log
|
159 |
+
|
160 |
+
lendf=len(pd.read_csv('data/streamlit.csv',usecols=['track_uri']))
|
161 |
+
dtypes = {'track_uri': 'object', 'artist_uri': 'object', 'album_uri': 'object', 'danceability': 'float16', 'energy': 'float16', 'key': 'float16',
|
162 |
+
'loudness': 'float16', 'mode': 'float16', 'speechiness': 'float16', 'acousticness': 'float16', 'instrumentalness': 'float16',
|
163 |
+
'liveness': 'float16', 'valence': 'float16', 'tempo': 'float16', 'duration_ms': 'float32', 'time_signature': 'float16',
|
164 |
+
'Track_release_date': 'int8', 'Track_pop': 'int8', 'Artist_pop': 'int8', 'Artist_genres': 'object'}
|
165 |
+
col_name= ['track_uri', 'artist_uri', 'album_uri', 'danceability', 'energy', 'key',
|
166 |
+
'loudness', 'mode', 'speechiness', 'acousticness', 'instrumentalness',
|
167 |
+
'liveness', 'valence', 'tempo', 'duration_ms', 'time_signature',
|
168 |
+
'Track_release_date', 'Track_pop', 'Artist_pop', 'Artist_genres']
|
169 |
+
|
170 |
+
try:
|
171 |
+
def get_IDs(user, playlist_id):
|
172 |
+
log.append('start playlist extraction')
|
173 |
+
track_ids = []
|
174 |
+
artist_id = []
|
175 |
+
playlist = sp.user_playlist(user, playlist_id)
|
176 |
+
for item in playlist['tracks']['items']:
|
177 |
+
track = item['track']
|
178 |
+
track_ids.append(track['id'])
|
179 |
+
artist = item['track']['artists']
|
180 |
+
artist_id.append(artist[0]['id'])
|
181 |
+
return track_ids, artist_id
|
182 |
+
except Exception as e:
|
183 |
+
log.append('Failed to load the playlist')
|
184 |
+
log.append(e)
|
185 |
+
|
186 |
+
track_ids, artist_id = get_IDs('Ruby', uri)
|
187 |
+
log.append("Number of Track : {}".format(len(track_ids)))
|
188 |
+
|
189 |
+
artist_id_uni = list(set(artist_id))
|
190 |
+
track_ids_uni = list(set(track_ids))
|
191 |
+
log.append("Number of unique Artists : {}".format(len(artist_id_uni)))
|
192 |
+
log.append("Number of unique Tracks : {}".format(len(track_ids_uni)))
|
193 |
+
|
194 |
+
def extract(track_ids_uni, artist_id_uni):
|
195 |
+
err = []
|
196 |
+
err.append('Start audio features extraction')
|
197 |
+
audio_features = pd.DataFrame()
|
198 |
+
for i in range(0, len(track_ids_uni), 25):
|
199 |
+
try:
|
200 |
+
track_feature = sp.audio_features(track_ids_uni[i:i+25])
|
201 |
+
track_df = pd.DataFrame(track_feature)
|
202 |
+
audio_features = pd.concat([audio_features, track_df], axis=0)
|
203 |
+
except Exception as e:
|
204 |
+
err.append(e)
|
205 |
+
continue
|
206 |
+
err.append('Start track features extraction')
|
207 |
+
track_ = pd.DataFrame()
|
208 |
+
for i in range(0, len(track_ids_uni), 25):
|
209 |
+
try:
|
210 |
+
track_features = sp.tracks(track_ids_uni[i:i+25])
|
211 |
+
for x in range(25):
|
212 |
+
track_pop = pd.DataFrame([track_ids_uni[i+x]], columns=['Track_uri'])
|
213 |
+
track_pop['Track_release_date'] = track_features['tracks'][x]['album']['release_date']
|
214 |
+
track_pop['Track_pop'] = track_features['tracks'][x]["popularity"]
|
215 |
+
track_pop['Artist_uri'] = track_features['tracks'][x]['artists'][0]['id']
|
216 |
+
track_pop['Album_uri'] = track_features['tracks'][x]['album']['id']
|
217 |
+
track_ = pd.concat([track_, track_pop], axis=0)
|
218 |
+
except Exception as e:
|
219 |
+
err.append(e)
|
220 |
+
continue
|
221 |
+
err.append('Start artist features extraction')
|
222 |
+
artist_ = pd.DataFrame()
|
223 |
+
for i in range(0, len(artist_id_uni), 25):
|
224 |
+
try:
|
225 |
+
artist_features = sp.artists(artist_id_uni[i:i+25])
|
226 |
+
for x in range(25):
|
227 |
+
artist_df = pd.DataFrame([artist_id_uni[i+x]], columns=['Artist_uri'])
|
228 |
+
artist_pop = artist_features['artists'][x]["popularity"]
|
229 |
+
artist_genres = artist_features['artists'][x]["genres"]
|
230 |
+
artist_df["Artist_pop"] = artist_pop
|
231 |
+
if artist_genres:
|
232 |
+
artist_df["genres"] = " ".join([re.sub(' ', '_', i) for i in artist_genres])
|
233 |
+
else:
|
234 |
+
artist_df["genres"] = "unknown"
|
235 |
+
artist_ = pd.concat([artist_, artist_df], axis=0)
|
236 |
+
except Exception as e:
|
237 |
+
err.append(e)
|
238 |
+
continue
|
239 |
+
try:
|
240 |
+
test = pd.DataFrame(
|
241 |
+
track_, columns=['Track_uri', 'Artist_uri', 'Album_uri'])
|
242 |
+
|
243 |
+
test.rename(columns={'Track_uri': 'track_uri',
|
244 |
+
'Artist_uri': 'artist_uri', 'Album_uri': 'album_uri'}, inplace=True)
|
245 |
+
|
246 |
+
audio_features.drop(
|
247 |
+
columns=['type', 'uri', 'track_href', 'analysis_url'], axis=1, inplace=True)
|
248 |
+
|
249 |
+
test = pd.merge(test, audio_features,
|
250 |
+
left_on="track_uri", right_on="id", how='outer')
|
251 |
+
test = pd.merge(test, track_, left_on="track_uri",
|
252 |
+
right_on="Track_uri", how='outer')
|
253 |
+
test = pd.merge(test, artist_, left_on="artist_uri",
|
254 |
+
right_on="Artist_uri", how='outer')
|
255 |
+
|
256 |
+
test.rename(columns={'genres': 'Artist_genres'}, inplace=True)
|
257 |
+
|
258 |
+
test.drop(columns=['Track_uri', 'Artist_uri_x',
|
259 |
+
'Artist_uri_y', 'Album_uri', 'id'], axis=1, inplace=True)
|
260 |
+
|
261 |
+
test.dropna(axis=0, inplace=True)
|
262 |
+
test['Track_pop'] = test['Track_pop'].apply(lambda x: int(x/5))
|
263 |
+
test['Artist_pop'] = test['Artist_pop'].apply(lambda x: int(x/5))
|
264 |
+
test['Track_release_date'] = test['Track_release_date'].apply(lambda x: x.split('-')[0])
|
265 |
+
test['Track_release_date'] = test['Track_release_date'].astype('int16')
|
266 |
+
test['Track_release_date'] = test['Track_release_date'].apply(lambda x: int(x/5))
|
267 |
+
|
268 |
+
test[['danceability', 'energy', 'key', 'loudness', 'mode', 'speechiness', 'acousticness', 'instrumentalness', 'liveness', 'valence', 'tempo', 'time_signature']] = test[[
|
269 |
+
'danceability', 'energy', 'key', 'loudness', 'mode', 'speechiness', 'acousticness', 'instrumentalness', 'liveness', 'valence', 'tempo', 'time_signature']].astype('float16')
|
270 |
+
test[['duration_ms']] = test[['duration_ms']].astype('float32')
|
271 |
+
test[['Track_release_date', 'Track_pop', 'Artist_pop']] = test[[
|
272 |
+
'Track_release_date', 'Track_pop', 'Artist_pop']].astype('int8')
|
273 |
+
except Exception as e:
|
274 |
+
err.append(e)
|
275 |
+
err.append('Finish extraction')
|
276 |
+
return test, err
|
277 |
+
test, err = extract(track_ids_uni, artist_id_uni)
|
278 |
+
|
279 |
+
for i in err:
|
280 |
+
log.append(i)
|
281 |
+
del err
|
282 |
+
grow = test.copy()
|
283 |
+
test['Artist_genres'] = test['Artist_genres'].apply(lambda x: x.split(" "))
|
284 |
+
tfidf = TfidfVectorizer(max_features=max_gen)
|
285 |
+
tfidf_matrix = tfidf.fit_transform(test['Artist_genres'].apply(lambda x: " ".join(x)))
|
286 |
+
genre_df = pd.DataFrame(tfidf_matrix.toarray())
|
287 |
+
genre_df.columns = ['genre' + "|" +i for i in tfidf.get_feature_names_out()]
|
288 |
+
genre_df = genre_df.astype('float16')
|
289 |
+
test.drop(columns=['Artist_genres'], axis=1, inplace=True)
|
290 |
+
test = pd.concat([test.reset_index(drop=True),genre_df.reset_index(drop=True)], axis=1)
|
291 |
+
Fresult = pd.DataFrame()
|
292 |
+
x = 1
|
293 |
+
for i in range(int(lendf/2), lendf+1, int(lendf/2)):
|
294 |
+
try:
|
295 |
+
df = pd.read_csv('data/streamlit.csv',names= col_name,dtype=dtypes,skiprows=x,nrows=i)
|
296 |
+
log.append('reading data frame chunks from {} to {}'.format(x,i))
|
297 |
+
except Exception as e:
|
298 |
+
log.append('Failed to load grow')
|
299 |
+
log.append(e)
|
300 |
+
grow = grow[~grow['track_uri'].isin(df['track_uri'].values)]
|
301 |
+
df = df[~df['track_uri'].isin(test['track_uri'].values)]
|
302 |
+
df['Artist_genres'] = df['Artist_genres'].apply(lambda x: x.split(" "))
|
303 |
+
tfidf_matrix = tfidf.transform(df['Artist_genres'].apply(lambda x: " ".join(x)))
|
304 |
+
genre_df = pd.DataFrame(tfidf_matrix.toarray())
|
305 |
+
genre_df.columns = ['genre' + "|" +i for i in tfidf.get_feature_names_out()]
|
306 |
+
genre_df = genre_df.astype('float16')
|
307 |
+
df.drop(columns=['Artist_genres'], axis=1, inplace=True)
|
308 |
+
df = pd.concat([df.reset_index(drop=True),
|
309 |
+
genre_df.reset_index(drop=True)], axis=1)
|
310 |
+
del genre_df
|
311 |
+
try:
|
312 |
+
df.drop(columns=['genre|unknown'], axis=1, inplace=True)
|
313 |
+
test.drop(columns=['genre|unknown'], axis=1, inplace=True)
|
314 |
+
except:
|
315 |
+
log.append('genre|unknown not found')
|
316 |
+
log.append('Scaling the data .....')
|
317 |
+
if x == 1:
|
318 |
+
sc = pickle.load(open('data/sc.sav','rb'))
|
319 |
+
df.iloc[:, 3:19] = sc.transform(df.iloc[:, 3:19])
|
320 |
+
test.iloc[:, 3:19] = sc.transform(test.iloc[:, 3:19])
|
321 |
+
log.append("Creating playlist vector")
|
322 |
+
playvec = pd.DataFrame(test.sum(axis=0)).T
|
323 |
+
else:
|
324 |
+
df.iloc[:, 3:19] = sc.transform(df.iloc[:, 3:19])
|
325 |
+
x = i
|
326 |
+
if model == 'Model 1':
|
327 |
+
df['sim']=cosine_similarity(df.drop(['track_uri', 'artist_uri', 'album_uri'], axis = 1),playvec.drop(['track_uri', 'artist_uri', 'album_uri'], axis = 1))
|
328 |
+
df['sim2']=cosine_similarity(df.iloc[:,16:-1],playvec.iloc[:,16:])
|
329 |
+
df['sim3']=cosine_similarity(df.iloc[:,19:-2],playvec.iloc[:,19:])
|
330 |
+
df = df.sort_values(['sim3','sim2','sim'],ascending = False,kind='stable').groupby('artist_uri').head(same_art).head(5)
|
331 |
+
Fresult = pd.concat([Fresult, df], axis=0)
|
332 |
+
Fresult = Fresult.sort_values(['sim3', 'sim2', 'sim'],ascending=False,kind='stable')
|
333 |
+
Fresult.drop_duplicates(subset=['track_uri'], inplace=True,keep='first')
|
334 |
+
Fresult = Fresult.groupby('artist_uri').head(same_art).head(5)
|
335 |
+
elif model == 'Model 2':
|
336 |
+
df['sim'] = cosine_similarity(df.iloc[:, 3:16], playvec.iloc[:, 3:16])
|
337 |
+
df['sim2'] = cosine_similarity(df.loc[:, df.columns.str.startswith('T') | df.columns.str.startswith('A')], playvec.loc[:, playvec.columns.str.startswith('T') | playvec.columns.str.startswith('A')])
|
338 |
+
df['sim3'] = cosine_similarity(df.loc[:, df.columns.str.startswith('genre')], playvec.loc[:, playvec.columns.str.startswith('genre')])
|
339 |
+
df['sim4'] = (df['sim']+df['sim2']+df['sim3'])/3
|
340 |
+
df = df.sort_values(['sim4'], ascending=False,kind='stable').groupby('artist_uri').head(same_art).head(5)
|
341 |
+
Fresult = pd.concat([Fresult, df], axis=0)
|
342 |
+
Fresult = Fresult.sort_values(['sim4'], ascending=False,kind='stable')
|
343 |
+
Fresult.drop_duplicates(subset=['track_uri'], inplace=True,keep='first')
|
344 |
+
Fresult = Fresult.groupby('artist_uri').head(same_art).head(5)
|
345 |
+
del test
|
346 |
+
try:
|
347 |
+
del df
|
348 |
+
log.append('Getting Result')
|
349 |
+
except:
|
350 |
+
log.append('Getting Result')
|
351 |
+
if model == 'Model 1':
|
352 |
+
Fresult = Fresult.sort_values(['sim3', 'sim2', 'sim'],ascending=False,kind='stable')
|
353 |
+
Fresult.drop_duplicates(subset=['track_uri'], inplace=True,keep='first')
|
354 |
+
Fresult = Fresult.groupby('artist_uri').head(same_art).track_uri.head(5)
|
355 |
+
elif model == 'Model 2':
|
356 |
+
Fresult = Fresult.sort_values(['sim4'], ascending=False,kind='stable')
|
357 |
+
Fresult.drop_duplicates(subset=['track_uri'], inplace=True,keep='first')
|
358 |
+
Fresult = Fresult.groupby('artist_uri').head(same_art).track_uri.head(5)
|
359 |
+
log.append('{} New Tracks Found'.format(len(grow)))
|
360 |
+
if(len(grow)>=1):
|
361 |
+
try:
|
362 |
+
new=pd.read_csv('data/new_tracks.csv',dtype=dtypes)
|
363 |
+
new=pd.concat([new, grow], axis=0)
|
364 |
+
new=new[new.Track_pop >0]
|
365 |
+
new.drop_duplicates(subset=['track_uri'], inplace=True,keep='last')
|
366 |
+
new.to_csv('data/new_tracks.csv',index=False)
|
367 |
+
except:
|
368 |
+
grow.to_csv('data/new_tracks.csv', index=False)
|
369 |
+
log.append('Model run successfully')
|
370 |
+
except Exception as e:
|
371 |
+
log.append("Model Failed")
|
372 |
+
log.append(e)
|
373 |
+
return Fresult, log
|
374 |
+
|
375 |
+
|
376 |
+
|
377 |
+
def top_tracks(url,region):
|
378 |
+
log = []
|
379 |
+
Fresult = []
|
380 |
+
uri = url.split('/')[-1].split('?')[0]
|
381 |
+
try:
|
382 |
+
log.append('spotify local method')
|
383 |
+
stream = open("Spotify.yaml")
|
384 |
+
spotify_details = yaml.safe_load(stream)
|
385 |
+
auth_manager = SpotifyClientCredentials(client_id=spotify_client_id, client_secret=spotify_client_secret)
|
386 |
+
except:
|
387 |
+
log.append('spotify .streamlit method')
|
388 |
+
try:
|
389 |
+
Client_id=st.secrets["Client_ID"]
|
390 |
+
client_secret=st.secrets["Client_secret"]
|
391 |
+
auth_manager = SpotifyClientCredentials(client_id=Client_id, client_secret=client_secret)
|
392 |
+
except:
|
393 |
+
log.append('spotify hug method')
|
394 |
+
Client_id=os.environ['Client_ID']
|
395 |
+
client_secret=os.environ['Client_secret']
|
396 |
+
auth_manager = SpotifyClientCredentials(client_id=Client_id, client_secret=client_secret)
|
397 |
+
sp = spotipy.client.Spotify(auth_manager=auth_manager)
|
398 |
+
try:
|
399 |
+
log.append('Starting Spotify Model')
|
400 |
+
top=sp.artist_top_tracks(uri,country=region)
|
401 |
+
for i in range(5) :
|
402 |
+
Fresult.append(top['tracks'][i]['id'])
|
403 |
+
log.append('Model run successfully')
|
404 |
+
except Exception as e:
|
405 |
+
log.append("Model Failed")
|
406 |
+
log.append(e)
|
407 |
+
return Fresult,log
|
408 |
+
|
409 |
+
def song_model(url, model, max_gen=3, same_art=5):
|
410 |
+
log = []
|
411 |
+
Fresult = []
|
412 |
+
try:
|
413 |
+
log.append('Start logging')
|
414 |
+
uri = url.split('/')[-1].split('?')[0]
|
415 |
+
try:
|
416 |
+
log.append('spotify local method')
|
417 |
+
stream = open("Spotify.yaml")
|
418 |
+
spotify_details = yaml.safe_load(stream)
|
419 |
+
auth_manager = SpotifyClientCredentials(client_id=spotify_client_id, client_secret=spotify_client_secret)
|
420 |
+
except:
|
421 |
+
log.append('spotify .streamlit method')
|
422 |
+
try:
|
423 |
+
Client_id=st.secrets["Client_ID"]
|
424 |
+
client_secret=st.secrets["Client_secret"]
|
425 |
+
auth_manager = SpotifyClientCredentials(client_id=Client_id, client_secret=client_secret)
|
426 |
+
except:
|
427 |
+
log.append('spotify hug method')
|
428 |
+
Client_id=os.environ['Client_ID']
|
429 |
+
client_secret=os.environ['Client_secret']
|
430 |
+
auth_manager = SpotifyClientCredentials(client_id=Client_id, client_secret=client_secret)
|
431 |
+
sp = spotipy.client.Spotify(auth_manager=auth_manager)
|
432 |
+
|
433 |
+
if model == 'Spotify Model':
|
434 |
+
log.append('Starting Spotify Model')
|
435 |
+
aa=sp.recommendations(seed_tracks=[uri], limit=25)
|
436 |
+
for i in range(25):
|
437 |
+
Fresult.append(aa['tracks'][i]['id'])
|
438 |
+
log.append('Model run successfully')
|
439 |
+
return Fresult, log
|
440 |
+
lendf=len(pd.read_csv('data/streamlit.csv',usecols=['track_uri']))
|
441 |
+
dtypes = {'track_uri': 'object', 'artist_uri': 'object', 'album_uri': 'object', 'danceability': 'float16', 'energy': 'float16', 'key': 'float16',
|
442 |
+
'loudness': 'float16', 'mode': 'float16', 'speechiness': 'float16', 'acousticness': 'float16', 'instrumentalness': 'float16',
|
443 |
+
'liveness': 'float16', 'valence': 'float16', 'tempo': 'float16', 'duration_ms': 'float32', 'time_signature': 'float16',
|
444 |
+
'Track_release_date': 'int8', 'Track_pop': 'int8', 'Artist_pop': 'int8', 'Artist_genres': 'object'}
|
445 |
+
col_name= ['track_uri', 'artist_uri', 'album_uri', 'danceability', 'energy', 'key',
|
446 |
+
'loudness', 'mode', 'speechiness', 'acousticness', 'instrumentalness',
|
447 |
+
'liveness', 'valence', 'tempo', 'duration_ms', 'time_signature',
|
448 |
+
'Track_release_date', 'Track_pop', 'Artist_pop', 'Artist_genres']
|
449 |
+
log.append('Start audio features extraction')
|
450 |
+
audio_features = pd.DataFrame(sp.audio_features([uri]))
|
451 |
+
log.append('Start track features extraction')
|
452 |
+
track_ = pd.DataFrame()
|
453 |
+
track_features = sp.tracks([uri])
|
454 |
+
track_pop = pd.DataFrame([uri], columns=['Track_uri'])
|
455 |
+
track_pop['Track_release_date'] = track_features['tracks'][0]['album']['release_date']
|
456 |
+
track_pop['Track_pop'] = track_features['tracks'][0]["popularity"]
|
457 |
+
track_pop['Artist_uri'] = track_features['tracks'][0]['artists'][0]['id']
|
458 |
+
track_pop['Album_uri'] = track_features['tracks'][0]['album']['id']
|
459 |
+
track_ = pd.concat([track_, track_pop], axis=0)
|
460 |
+
log.append('Start artist features extraction')
|
461 |
+
artist_id_uni=list(track_['Artist_uri'])
|
462 |
+
artist_ = pd.DataFrame()
|
463 |
+
artist_features = sp.artists(artist_id_uni)
|
464 |
+
artist_df = pd.DataFrame(artist_id_uni, columns=['Artist_uri'])
|
465 |
+
artist_pop = artist_features['artists'][0]["popularity"]
|
466 |
+
artist_genres = artist_features['artists'][0]["genres"]
|
467 |
+
artist_df["Artist_pop"] = artist_pop
|
468 |
+
if artist_genres:
|
469 |
+
artist_df["genres"] = " ".join([re.sub(' ', '_', i) for i in artist_genres])
|
470 |
+
else:
|
471 |
+
artist_df["genres"] = "unknown"
|
472 |
+
artist_ = pd.concat([artist_, artist_df], axis=0)
|
473 |
+
try:
|
474 |
+
test = pd.DataFrame(track_, columns=['Track_uri', 'Artist_uri', 'Album_uri'])
|
475 |
+
test.rename(columns={'Track_uri': 'track_uri','Artist_uri': 'artist_uri', 'Album_uri': 'album_uri'}, inplace=True)
|
476 |
+
audio_features.drop(columns=['type', 'uri', 'track_href', 'analysis_url'], axis=1, inplace=True)
|
477 |
+
test = pd.merge(test, audio_features,left_on="track_uri", right_on="id", how='outer')
|
478 |
+
test = pd.merge(test, track_, left_on="track_uri",right_on="Track_uri", how='outer')
|
479 |
+
test = pd.merge(test, artist_, left_on="artist_uri",right_on="Artist_uri", how='outer')
|
480 |
+
test.rename(columns={'genres': 'Artist_genres'}, inplace=True)
|
481 |
+
test.drop(columns=['Track_uri', 'Artist_uri_x','Artist_uri_y', 'Album_uri', 'id'], axis=1, inplace=True)
|
482 |
+
test.dropna(axis=0, inplace=True)
|
483 |
+
test['Track_pop'] = test['Track_pop'].apply(lambda x: int(x/5))
|
484 |
+
test['Artist_pop'] = test['Artist_pop'].apply(lambda x: int(x/5))
|
485 |
+
test['Track_release_date'] = test['Track_release_date'].apply(lambda x: x.split('-')[0])
|
486 |
+
test['Track_release_date'] = test['Track_release_date'].astype('int16')
|
487 |
+
test['Track_release_date'] = test['Track_release_date'].apply(lambda x: int(x/5))
|
488 |
+
test[['danceability', 'energy', 'key', 'loudness', 'mode', 'speechiness', 'acousticness', 'instrumentalness', 'liveness', 'valence', 'tempo', 'time_signature']] = test[['danceability', 'energy', 'key', 'loudness', 'mode', 'speechiness', 'acousticness', 'instrumentalness', 'liveness', 'valence', 'tempo', 'time_signature']].astype('float16')
|
489 |
+
test[['duration_ms']] = test[['duration_ms']].astype('float32')
|
490 |
+
test[['Track_release_date', 'Track_pop', 'Artist_pop']] = test[['Track_release_date', 'Track_pop', 'Artist_pop']].astype('int8')
|
491 |
+
except Exception as e:
|
492 |
+
log.append(e)
|
493 |
+
log.append('Finish extraction')
|
494 |
+
grow = test.copy()
|
495 |
+
test['Artist_genres'] = test['Artist_genres'].apply(lambda x: x.split(" "))
|
496 |
+
tfidf = TfidfVectorizer(max_features=max_gen)
|
497 |
+
tfidf_matrix = tfidf.fit_transform(test['Artist_genres'].apply(lambda x: " ".join(x)))
|
498 |
+
genre_df = pd.DataFrame(tfidf_matrix.toarray())
|
499 |
+
genre_df.columns = ['genre' + "|" +i for i in tfidf.get_feature_names_out()]
|
500 |
+
genre_df = genre_df.astype('float16')
|
501 |
+
test.drop(columns=['Artist_genres'], axis=1, inplace=True)
|
502 |
+
test = pd.concat([test.reset_index(drop=True),genre_df.reset_index(drop=True)], axis=1)
|
503 |
+
Fresult = pd.DataFrame()
|
504 |
+
x = 1
|
505 |
+
for i in range(int(lendf/2), lendf+1, int(lendf/2)):
|
506 |
+
try:
|
507 |
+
df = pd.read_csv('data/streamlit.csv',names= col_name,dtype=dtypes,skiprows=x,nrows=i)
|
508 |
+
log.append('reading data frame chunks from {} to {}'.format(x,i))
|
509 |
+
except Exception as e:
|
510 |
+
log.append('Failed to load grow')
|
511 |
+
log.append(e)
|
512 |
+
grow = grow[~grow['track_uri'].isin(df['track_uri'].values)]
|
513 |
+
df = df[~df['track_uri'].isin(test['track_uri'].values)]
|
514 |
+
df['Artist_genres'] = df['Artist_genres'].apply(lambda x: x.split(" "))
|
515 |
+
tfidf_matrix = tfidf.transform(df['Artist_genres'].apply(lambda x: " ".join(x)))
|
516 |
+
genre_df = pd.DataFrame(tfidf_matrix.toarray())
|
517 |
+
genre_df.columns = ['genre' + "|" +i for i in tfidf.get_feature_names_out()]
|
518 |
+
genre_df = genre_df.astype('float16')
|
519 |
+
df.drop(columns=['Artist_genres'], axis=1, inplace=True)
|
520 |
+
df = pd.concat([df.reset_index(drop=True),
|
521 |
+
genre_df.reset_index(drop=True)], axis=1)
|
522 |
+
del genre_df
|
523 |
+
try:
|
524 |
+
df.drop(columns=['genre|unknown'], axis=1, inplace=True)
|
525 |
+
test.drop(columns=['genre|unknown'], axis=1, inplace=True)
|
526 |
+
except:
|
527 |
+
log.append('genre|unknown not found')
|
528 |
+
log.append('Scaling the data .....')
|
529 |
+
if x == 1:
|
530 |
+
sc = pickle.load(open('data/sc.sav','rb'))
|
531 |
+
df.iloc[:, 3:19] = sc.transform(df.iloc[:, 3:19])
|
532 |
+
test.iloc[:, 3:19] = sc.transform(test.iloc[:, 3:19])
|
533 |
+
log.append("Creating playlist vector")
|
534 |
+
playvec = pd.DataFrame(test.sum(axis=0)).T
|
535 |
+
else:
|
536 |
+
df.iloc[:, 3:19] = sc.transform(df.iloc[:, 3:19])
|
537 |
+
x = i
|
538 |
+
if model == 'Model 1':
|
539 |
+
df['sim']=cosine_similarity(df.drop(['track_uri', 'artist_uri', 'album_uri'], axis = 1),playvec.drop(['track_uri', 'artist_uri', 'album_uri'], axis = 1))
|
540 |
+
df['sim2']=cosine_similarity(df.iloc[:,16:-1],playvec.iloc[:,16:])
|
541 |
+
df['sim3']=cosine_similarity(df.iloc[:,19:-2],playvec.iloc[:,19:])
|
542 |
+
df = df.sort_values(['sim3','sim2','sim'],ascending = False,kind='stable').groupby('artist_uri').head(same_art).head(5)
|
543 |
+
Fresult = pd.concat([Fresult, df], axis=0)
|
544 |
+
Fresult = Fresult.sort_values(['sim3', 'sim2', 'sim'],ascending=False,kind='stable')
|
545 |
+
Fresult.drop_duplicates(subset=['track_uri'], inplace=True,keep='first')
|
546 |
+
Fresult = Fresult.groupby('artist_uri').head(same_art).head(5)
|
547 |
+
elif model == 'Model 2':
|
548 |
+
df['sim'] = cosine_similarity(df.iloc[:, 3:16], playvec.iloc[:, 3:16])
|
549 |
+
df['sim2'] = cosine_similarity(df.loc[:, df.columns.str.startswith('T') | df.columns.str.startswith('A')], playvec.loc[:, playvec.columns.str.startswith('T') | playvec.columns.str.startswith('A')])
|
550 |
+
df['sim3'] = cosine_similarity(df.loc[:, df.columns.str.startswith('genre')], playvec.loc[:, playvec.columns.str.startswith('genre')])
|
551 |
+
df['sim4'] = (df['sim']+df['sim2']+df['sim3'])/3
|
552 |
+
df = df.sort_values(['sim4'], ascending=False,kind='stable').groupby('artist_uri').head(same_art).head(5)
|
553 |
+
Fresult = pd.concat([Fresult, df], axis=0)
|
554 |
+
Fresult = Fresult.sort_values(['sim4'], ascending=False,kind='stable')
|
555 |
+
Fresult.drop_duplicates(subset=['track_uri'], inplace=True,keep='first')
|
556 |
+
Fresult = Fresult.groupby('artist_uri').head(same_art).head(5)
|
557 |
+
del test
|
558 |
+
try:
|
559 |
+
del df
|
560 |
+
log.append('Getting Result')
|
561 |
+
except:
|
562 |
+
log.append('Getting Result')
|
563 |
+
if model == 'Model 1':
|
564 |
+
Fresult = Fresult.sort_values(['sim3', 'sim2', 'sim'],ascending=False,kind='stable')
|
565 |
+
Fresult.drop_duplicates(subset=['track_uri'], inplace=True,keep='first')
|
566 |
+
Fresult = Fresult.groupby('artist_uri').head(same_art).track_uri.head(5)
|
567 |
+
elif model == 'Model 2':
|
568 |
+
Fresult = Fresult.sort_values(['sim4'], ascending=False,kind='stable')
|
569 |
+
Fresult.drop_duplicates(subset=['track_uri'], inplace=True,keep='first')
|
570 |
+
Fresult = Fresult.groupby('artist_uri').head(same_art).track_uri.head(5)
|
571 |
+
log.append('{} New Tracks Found'.format(len(grow)))
|
572 |
+
if(len(grow)>=1):
|
573 |
+
try:
|
574 |
+
new=pd.read_csv('data/new_tracks.csv',dtype=dtypes)
|
575 |
+
new=pd.concat([new, grow], axis=0)
|
576 |
+
new=new[new.Track_pop >0]
|
577 |
+
new.drop_duplicates(subset=['track_uri'], inplace=True,keep='last')
|
578 |
+
new.to_csv('data/new_tracks.csv',index=False)
|
579 |
+
except:
|
580 |
+
grow.to_csv('data/new_tracks.csv', index=False)
|
581 |
+
log.append('Model run successfully')
|
582 |
+
except Exception as e:
|
583 |
+
log.append("Model Failed")
|
584 |
+
log.append(e)
|
585 |
+
return Fresult, log
|
586 |
+
|
587 |
+
def update_dataset():
|
588 |
+
col_name= ['track_uri', 'artist_uri', 'album_uri', 'danceability', 'energy', 'key',
|
589 |
+
'loudness', 'mode', 'speechiness', 'acousticness', 'instrumentalness',
|
590 |
+
'liveness', 'valence', 'tempo', 'duration_ms', 'time_signature',
|
591 |
+
'Track_release_date', 'Track_pop', 'Artist_pop', 'Artist_genres']
|
592 |
+
dtypes = {'track_uri': 'object', 'artist_uri': 'object', 'album_uri': 'object', 'danceability': 'float16', 'energy': 'float16', 'key': 'float16',
|
593 |
+
'loudness': 'float16', 'mode': 'float16', 'speechiness': 'float16', 'acousticness': 'float16', 'instrumentalness': 'float16',
|
594 |
+
'liveness': 'float16', 'valence': 'float16', 'tempo': 'float16', 'duration_ms': 'float32', 'time_signature': 'float16',
|
595 |
+
'Track_release_date': 'int8', 'Track_pop': 'int8', 'Artist_pop': 'int8', 'Artist_genres': 'object'}
|
596 |
+
df = pd.read_csv('data/streamlit.csv',dtype=dtypes)
|
597 |
+
grow = pd.read_csv('data/new_tracks.csv',dtype=dtypes)
|
598 |
+
cur = len(df)
|
599 |
+
df=pd.concat([df,grow],axis=0)
|
600 |
+
grow=pd.DataFrame(columns=col_name)
|
601 |
+
grow.to_csv('data/new_tracks.csv',index=False)
|
602 |
+
df=df[df.Track_pop >0]
|
603 |
+
df.drop_duplicates(subset=['track_uri'],inplace=True,keep='last')
|
604 |
+
df.dropna(axis=0,inplace=True)
|
605 |
+
df.to_csv('data/streamlit.csv',index=False)
|
606 |
+
return (len(df)-cur)
|
requirements.txt
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
transformers==4.34
|
2 |
+
jsonlines
|
3 |
+
numpy
|
4 |
+
torch
|
5 |
+
pandas==1.4.4
|
6 |
+
PyYAML==6.0
|
7 |
+
scikit_learn==1.1.3
|
8 |
+
spotipy==2.20.0
|
9 |
+
streamlit==1.22.0
|
10 |
+
streamlit_option_menu==0.3.2
|
11 |
+
python-dotenv
|
spotify_get_artist_url.png
ADDED
spotify_get_playlist_url.png
ADDED
spotify_get_song_url.png
ADDED