Сбор датасета - cscenter/automatic-playlist-generation GitHub Wiki

Плейлисты

deezer.com -- плейлисты собираются последовательно с номера 1. Плейлисты шумные -- записи с ошибками, качество плейлистов разнообразное, бывают весьма редкие исполнители. Названия композиций подвергаются коррекции по методу getCorrection из API last.fm. Для полученных композиций собираются теги last.fm и audio-features по id композиции на spotify.com. spotify.com -- по ключевому слову выдаётся список плейлистов, для которых можно собрать список всех композиций.

Из плейлистов составляется уменьшенный список композиций без повторов, чтобы было меньше запросов при сборе тегов. 72 тысячи плейлистов с deezer.com содержат ~2.3 миллиона композиций. Уменьшенный список состоит из ~255 тысяч композиций, которым соответствуют ~36 тысяч исполнителей. Если оставлять только тех исполнителей, от которых есть хотя бы 5 композиций в общем вкладе, останется ~214 тысяч композиций и всего ~8 тысяч исполнителей. Все файлы, структура которых описана ниже, формата json.

Формат уменьшенного списка: на каждой строчке словарь, ключом которого является имя исполнителея, а значением -- список композиций этого исполнителя:

{ARTIST1: [TRACK1, TRACK2, ... ]}
{ARTIST2: [TRACK1, TRACK2, ... ]}

Список подаётся на вход процедур, которые собирают для них информацию, используя методы API. Для каждого вызова метода создаётся отдельный файл в директории, соответствующей методу. Затем полученные файлы обрабатываются -- из них собирается информация в один файл для каждой директории.

Теги last.fm

Для композиций из откорректированных плейлистов используются следующие методы last.fm:

Не используются, но могут быть полезными для анализа тегов следующие методы last.fm:

Структура хранения тегов last.fm

Названия композиций для сбора тегов используются из уменьшенного списка композиций плейлистов. Формат для метода artist.getTopTags: словарь, ключом которого является имя исполнителя, а значением -- словарь его тегов, где ключом является тег, а значением -- количество его вхождений:

{ARTIST1: {tag1: count1, tag2: count2, ...}, ARTIST2: {tag1: count1, tag2: count2, ...}, ...}

Формат для метода track.getTopTags: словарь, ключом которого является имя исполнителя, а значением -- массив композиций с тегами. Каждый элемент массива -- словарь, ключом которого является название трека, а значением -- словарь тегов с подсчётом вхождений:

{ARTIST1: [{TRACK1: {tag1: count1, tag2: count2, ...}}, {TRACK2: {tag1: count1, tag2: count2, ...}}, ...], ARTIST2: [{TRACK1: {tag1: count1, tag2: count2, ...}}, {TRACK2: {tag1: count1, tag2: count2, ...}}, ...]

Формат для метода artist.getSimilar: словарь, ключом которого является имя исполнителя, а значением -- словарь похожих исполнителей, где ключом является имя исполнителя, а значением -- match (выдаваемое last.fm):

{ARTIST1: {artist_similar1: match1, artist_similar2: match2, ...}, ARTIST2: {artist_similar1: match1, artist_similar2: match2, ...}, ...}

Формат для метода track.getSimilar: словарь, ключом которого является имя исполнителя, а значением -- массив композиций исполнителя с похожими. Каждый элемент массива -- словарь, ключом которого является название трека, а значением -- массив словарей похожих композиций расширенного формата: ключи "artist", "title", "match", а значения -- соответствующие им строки по выдаче метода:

{ARTIST1: [{TRACK1: [{"artist": artist1, "title": title1, "match": match1}, {"artist": artist2, "title": title2, "match": match2}, ...]}, {TRACK2: [{"artist": artist1, "title": title1, "match": match1}, {"artist": artist2, "title": title2, "match": match2}, ...]}, ...], ARTIST2: [{TRACK1: [{"artist": artist1, "title": title1, "match": match1}, {"artist": artist2, "title": title2, "match": match2}, ...]}, {TRACK2: [{"artist": artist1, "title": title1, "match": match1}, {"artist": artist2, "title": title2, "match": match2}, ...]}, ...], ...}

Метод artist.getTopTracks по имени исполнителя возвращает отранжированный по популярности список его композиций (по умолчанию limit=50). Композициям присваивается значение популярности от 0.0 до 1.0 следующим образом: если композиции в списке нет -- присваивается 0, если её номер в списке i -- присваивается exp(-i/10.0). Уменьшенный список композиций плейлистов обрабатывается таким образом и на выходе получается следующий формат: словарь, ключом которого является имя исполнителя, а значением -- словарь для композиций, который есть в уменьшенном списке. Композиция является ключом, а значением словаря -- посчитанная популярность композиции:

{ARTIST1: {TRACK1: popularity1, TRACK2: popularity2, ...}, ARTIST2: {TRACK1: popularity1, TRACK2: popularity2, ...}, ...}

Метод audio-features spotify.com

Для использования метода https://developer.spotify.com/web-api/get-audio-features/ нужен ID композиции на spotify.com. При поиске id по названию композиции и исполнителя возможны несколько ID в зависимости от релиза. Сохраняются все id и соответствующие им аудио-характеристики. Формат вывода: словарь, ключом которого является имя исполнителя, а значением -- массив словарей композиций, где ключом словаря является название композиции, значением -- массив ID:

{ARTIST1: [{TRACK1: [id1, id2, ...]}, {TRACK2: [id1, id2, ...]}, ...}

По id собираются audio-features (являющиеся словарём) и записываются в аналогичном формате:

{ARTIST1: [{TRACK1: [audio-features1, audio-features2, ...]}, {TRACK2: [audio-features1, audio-features2, ...]}, ...}

Проблемы: не всегда есть ID spotify для композиции. Нужно отслеживать момент обновления токена и обновлять, иначе запросы не идут.