mclemcrew commited on
Commit
d382306
1 Parent(s): 016651d

Upload 15 files

Browse files
.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