Рубрики
Без рубрики

Как построить песню Recial, используя создание ML MLRECommender

Использование Python, Pandas и Swift для создания двигателя рекомендации песни. Помечено с машиной, быстрым, питоном, пандами.

Вы можете найти этот пост и многое другое на моем Веб-сайт !

Цель

К концу этого поста мы узнаем, как использовать Создать ML MLRECommender Чтобы порекомендовать песню пользователю, учитывая их истории прослушивания. Мы также узнаем, как разбираться и подготовить Mldatatable Использование Python и Data от третьей стороны.

Введение в MLRECommender.

Персонализированная система рекомендации может использоваться во многих различных приложениях, таких как музыкальный проигрыватель, видеоплеер или сайт социальных сетей. Система рекомендации машинного обучения сравнивает прошлую деятельность пользователя для большой библиотеки активности от многих других пользователей. Например, если Spotify хотел порекомендовать вам новую ежедневную смесь, их система ML ML-рекомендации может посмотреть на историю прослушивания в течение последних нескольких недель и сравнить историю истории ваших друзей. Наша цель сегодня – создать MLRECommender Рекомендовать песни пользователю, учитывая их истории прослушивания.

Конструктор для MLRECommender является:

init(trainingData: MLDataTable, userColumn: String, itemColumn: String, ratingColumn: String? = nil, parameters: MLRecommender.ModelParameters = ModelParameters()) throws

Создание таблиц данных

Первый шаг – создать WeatingData в виде Mldatatable Отказ В этом случае наши учебные данные – это история прослушивания многих разных пользователей из Миллион наборов песни , который проводит метаданные более миллиона песен и рейтингов, предоставляемых пользователями.

Мы будем использовать два файла из набора данных. Первый это 1000.txt Содержит идентификатор пользователя, идентификатор песни и время прослушивания для 10000 записей. Мы назовем это History.txt впредь. Второй – song_data.csv. , который содержит идентификатор песни, название, дату выпуска и имя исполнителя. Мы назовем это Songs.csv впредь. Все полные файлы для этого руководства можно найти в конце поста.

Вот как выглядят наши входные файлы. Обратите внимание, что Songs.csv имеет ряд заголовка, пока History.txt. не:

# history.txt

b80344d063b5ccb3212f76538f3d9e43d87dca9e    SOAKIMP12A8C130995  1
b80344d063b5ccb3212f76538f3d9e43d87dca9e    SOBBMDR12A8C13253B  2
b80344d063b5ccb3212f76538f3d9e43d87dca9e    SOBXHDL12A81C204C0  1
...
# songs.csv

song_id,title,release,artist_name,year
SOQMMHC12AB0180CB8,"Silent Night","Monster Ballads X-Mas","Faster Pussy cat",2003
SOVFVAK12A8C1350D9,"Tanssi vaan","Karkuteillä",Karkkiautomaatti,1995
SOGTUKN12AB017F4F1,"No One Could Ever",Butter,"Hudson Mohawke",2006
...

Мы будем использовать Пандас Библиотека Python для обработки наших данных CSV. Сначала загрузите файлы выше и назовите их History.txt и Songs.csv и мы загрузим их:

import csv
import pandas as pd

history_file = 'history.txt' # 'https://static.turi.com/datasets/millionsong/10000.txt'
songs_metadata_file = 'songs.csv' # 'https://static.turi.com/datasets/millionsong/song_data.csv'

# Import the files
history_df = pd.read_table(history_file, header=None)
history_df.columns = ['user_id', 'song_id', 'listen_count']
metadata_df =  pd.read_csv(songs_metadata_file)

Songs.csv Уже есть заголовки столбцов в файле, поэтому нам не нужно было добавлять такие, как мы сделали с История_df Отказ Это то, как сейчас выглядят наши данные по датафам:

# history_df

                                    user_id             song_id  listen_count
0  b80344d063b5ccb3212f76538f3d9e43d87dca9e  SOAKIMP12A8C130995             1
1  b80344d063b5ccb3212f76538f3d9e43d87dca9e  SOBBMDR12A8C13253B             2
2  b80344d063b5ccb3212f76538f3d9e43d87dca9e  SOBXHDL12A81C204C0             1
...
# metadata_df
# (The '\' means that the row continues onto the next lines)

              song_id              title                release  \
0  SOQMMHC12AB0180CB8       Silent Night  Monster Ballads X-Mas
1  SOVFVAK12A8C1350D9        Tanssi vaan            Karkuteillä
2  SOGTUKN12AB017F4F1  No One Could Ever                 Butter

        artist_name  year
0  Faster Pussy cat  2003
1  Karkkiautomaatti  1995
2    Hudson Mohawke  2006
...

Далее, чтобы создать одну историю прослушивания для всех пользователей, мы хотим объединить данные песни в metadata_df в историю прослушивания в История_df и создать CSV для использования в SWIFT. Давайте также добавим столбец, который сочетает в себе название песни с именем художника, чтобы мы могли видеть как в нашем MLRECommender :

# Merge the files into a single csv
song_df = pd.merge(history_df, metadata_df.drop_duplicates(['song_id']), on="song_id", how="left")
song_df.to_csv('merged_listen_data.csv', quoting=csv.QUOTE_NONNUMERIC)

# Add a "Title - Name" column for easier printing later
song_df['song'] = song_df['title'] + ' - ' + song_df['artist_name']

Вот что теперь выглядит наша комбинированная песня DataFrame:

# song_df

                                    user_id             song_id  listen_count  \
0  b80344d063b5ccb3212f76538f3d9e43d87dca9e  SOAKIMP12A8C130995             1
1  b80344d063b5ccb3212f76538f3d9e43d87dca9e  SOBBMDR12A8C13253B             2
2  b80344d063b5ccb3212f76538f3d9e43d87dca9e  SOBXHDL12A81C204C0             1

             title              release    artist_name  year  \
0         The Cove   Thicker Than Water   Jack Johnson     0
1  Entre Dos Aguas  Flamenco Para Niños  Paco De Lucia  1976
2         Stronger           Graduation     Kanye West  2007

                              song
0          The Cove - Jack Johnson
1  Entre Dos Aguas - Paco De Lucia
2            Stronger - Kanye West
...

С момента написания, MLRECommender требует, чтобы столбец идентификатора элемента в WeatingData Перейти от 1 до количества предметов. Другими словами, если наше WeatingData включены только три песни, merged_listen_data.csv будет иметь такие идентификаторы песни, как Soqmmhc12ab0180cb8 , SUVFVAK12A8C1350D9 и Sogtukn12ab017f4f1 , но нам нужно иметь идентификаторы песни 0 С 1 и 2 Отказ Давайте добавим новый столбец к CSV, который использует инкрементные идентификаторы песни от 0 до N:

# Find the unique song ids
song_ids = metadata_df.song_id.unique()

# Create a new dataframe of the unique song ids and a new incremental
# id for each one
incremental_id_df = pd.DataFrame({'song_id': song_ids})
incremental_id_df['incremental_song_id'] = incremental_id_df.index

# Merge the original song metadata with the incremental ids
new_song_id_df = pd.merge(song_id_df, incremental_id_df, on='song_id', how='left')
new_song_id_df.to_csv('songs_incremental_id.csv', quoting=csv.QUOTE_NONNUMERIC)

# Create a new merged history and song metadata CSV with incremental ids
new_history_df = pd.merge(history_df, incremental_id_df, on='song_id', how='inner')
new_history_df.to_csv('merged_listen_data_incremental_song_id.csv', quoting=csv.QUOTE_NONNUMERIC)

Вот как выглядит наша новая песня CSV-файл. Обратите внимание, что в начале есть добавленный столбец с идентификатором песни от 0 до 999999:

# songs_incremental_id.csv

"","song_id","title","release","artist_name","year","incremental_song_id"
0,"SOQMMHC12AB0180CB8","Silent Night","Monster Ballads X-Mas","Faster Pussy cat",2003,0
1,"SOVFVAK12A8C1350D9","Tanssi vaan","Karkuteillä","Karkkiautomaatti",1995,1
2,"SOGTUKN12AB017F4F1","No One Could Ever","Butter","Hudson Mohawke",2006,2
...

И вот как наш окончательный объединенный данные прослушивания выглядит с помощью инкрементных идентификаторов, готовых к чтению MLRECommender :

# merged_listen_data_incremental_song_id.csv

"","Unnamed: 0","user_id","song_id","listen_count","title","release","artist_name","year","incremental_song_id"
0,0,"b80344d063b5ccb3212f76538f3d9e43d87dca9e","SOAKIMP12A8C130995",1,"The Cove","Thicker Than Water","Jack Johnson",0,397069
1,18887,"7c86176941718984fed11b7c0674ff04c029b480","SOAKIMP12A8C130995",1,"The Cove","Thicker Than Water","Jack Johnson",0,397069
2,21627,"76235885b32c4e8c82760c340dc54f9b608d7d7e","SOAKIMP12A8C130995",3,"The Cove","Thicker Than Water","Jack Johnson",0,397069
...

Теперь мы готовы загрузить его в рекомендации!

Использование MLRECommender.

Создайте новую SWIFT Playground и добавьте два CSV merged_listen_data_incremental_song_id.csv и songs_incremental_id.csv как ресурсы на вашей детской площадке. За помощью о добавлении ресурсов на Swift Playground, проверьте Это пост Отказ Убедитесь, что ваша SWIFT Playground является пустой игровой площадкой Macos, а не детская площадка IOS Отказ Потому что наш MLRECommender Даст нам только идентификатор пользователя и инкрементную песню при создании рекомендаций, мы будем использовать второй CSV для просмотра названий песни.

Во-первых, давайте загрузим объединенную историю прослушивания с помощью инкрементных идентификаторов:

import Foundation
import CreateML

// Create an MLDataTable from the merged CSV data
let history_csv = Bundle.main.url(forResource: "merged_listen_data_incremental_song_id", withExtension: "csv")!
let history_table = try MLDataTable(contentsOf: history_csv)
print(history_table)
Columns:
    X1  string
    Unnamed: 0  integer
    user_id string
    song_id string
    listen_count    integer
    title   string
    release string
    artist_name string
    year    integer
    incremental_song_id integer
Rows: 2000000
Data:
+----------------+----------------+----------------+----------------+----------------+
| X1             | Unnamed: 0     | user_id        | song_id        | listen_count   |
+----------------+----------------+----------------+----------------+----------------+
| 0              | 0              | b80344d063b5...| SOAKIMP12A8C...| 1              |
| 1              | 18887          | 7c8617694171...| SOAKIMP12A8C...| 1              |
| 2              | 21627          | 76235885b32c...| SOAKIMP12A8C...| 3              |
| 3              | 27714          | 250c0fa2a77b...| SOAKIMP12A8C...| 1              |
| 4              | 34428          | 3f73f44560e8...| SOAKIMP12A8C...| 6              |
| 5              | 34715          | 7a4b8e7d2905...| SOAKIMP12A8C...| 6              |
| 6              | 55885          | b4a678fb729b...| SOAKIMP12A8C...| 2              |
| 7              | 65683          | 33280fc74b16...| SOAKIMP12A8C...| 1              |
| 8              | 75029          | be21ec120193...| SOAKIMP12A8C...| 1              |
| 9              | 105313         | 6fbb9ff93663...| SOAKIMP12A8C...| 2              |
+----------------+----------------+----------------+----------------+----------------+
+----------------+----------------+----------------+----------------+---------------------+
| title          | release        | artist_name    | year           | incremental_song_id |
+----------------+----------------+----------------+----------------+---------------------+
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
| The Cove       | Thicker Than...| Jack Johnson   | 0              | 397069              |
+----------------+----------------+----------------+----------------+---------------------+
[2000000 rows x 10 columns]

Оттуда мы можем создать MLRECommender Отказ Наше WeatingData Является ли формат таблицы данных объединенного истории прослушивания CSV, Usercolumn это user_id Имя столбца и itembolumn это incrimental_song_id Имя столбца. user_id B80344D063B5CCB3212F76538F3D9E43D87DCA9E был случайным образом выбран из объединенных данных CSV: =.

// Generate recommendations
let recommender = try MLRecommender(trainingData: history_table, userColumn: "user_id", itemColumn: "incremental_song_id")
let recs = try recommender.recommendations(fromUsers: ["b80344d063b5ccb3212f76538f3d9e43d87dca9e"])
print(recs)
Columns:
    user_id string
    incremental_song_id integer
    score   float
    rank    integer
Rows: 10
Data:
+----------------+---------------------+----------------+----------------+
| user_id        | incremental_song_id | score          | rank           |
+----------------+---------------------+----------------+----------------+
| b80344d063b5...| 114557              | 0.0461493      | 1              |
| b80344d063b5...| 834311              | 0.0436045      | 2              |
| b80344d063b5...| 939015              | 0.043068       | 3              |
| b80344d063b5...| 955047              | 0.0427589      | 4              |
| b80344d063b5...| 563380              | 0.0426116      | 5              |
| b80344d063b5...| 677759              | 0.0423951      | 6              |
| b80344d063b5...| 689170              | 0.0418951      | 7              |
| b80344d063b5...| 333053              | 0.041788       | 8              |
| b80344d063b5...| 381319              | 0.0403042      | 9              |
| b80344d063b5...| 117491              | 0.0400819      | 10             |
+----------------+---------------------+----------------+----------------+
[10 rows x 4 columns]

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

// Use the songs data CSV to print the recommended song titles
let songs_csv = Bundle.main.url(forResource: "songs_incremental_id", withExtension: "csv")!
let songs_table = try MLDataTable(contentsOf: songs_csv)
print(songs_table)

let song_title_recs = recs.join(with: songs_table, on: "incremental_song_id")
print(song_title_recs)
Columns:
    X1  string
    song_id string
    title   undefined
    release string
    artist_name string
    year    integer
    incremental_song_id integer
Rows: 1000000
Data:
+----------------+----------------+----------------+----------------+----------------+
| X1             | song_id        | title          | release        | artist_name    |
+----------------+----------------+----------------+----------------+----------------+
| 0              | SOQMMHC12AB0...| Silent Night   | Monster Ball...| Faster Pussy...|
| 1              | SOVFVAK12A8C...| Tanssi vaan    | Karkuteillä   | Karkkiautoma...|
| 2              | SOGTUKN12AB0...| No One Could...| Butter         | Hudson Mohawke |
| 3              | SOBNYVR12A8C...| Si Vos Querés | De Culo        | Yerba Brava    |
| 4              | SOHSBXH12A8C...| Tangle Of As...| Rene Ablaze ...| Der Mystic     |
| 5              | SOZVAPQ12A8C...| Symphony No....| Berwald: Sym...| David Montgo...|
| 6              | SOQVRHI12A6D...| We Have Got ...| Strictly The...| Sasha / Turb...|
| 7              | SOEYRFT12AB0...| 2 Da Beat Ch...| Da Bomb        | Kris Kross     |
| 8              | SOPMIYT12A6D...| Goodbye        | Danny Boy      | Joseph Locke   |
| 9              | SOJCFMH12A8C...| Mama_ mama c...| March to cad...| The Sun Harb...|
+----------------+----------------+----------------+----------------+----------------+
+----------------+---------------------+
| year           | incremental_song_id |
+----------------+---------------------+
| 2003           | 0                   |
| 1995           | 1                   |
| 2006           | 2                   |
| 2003           | 3                   |
| 0              | 4                   |
| 0              | 5                   |
| 0              | 6                   |
| 1993           | 7                   |
| 0              | 8                   |
| 0              | 9                   |
+----------------+---------------------+
[1000000 rows x 7 columns]


Columns:
    user_id string
    incremental_song_id integer
    score   float
    rank    integer
    X1  string
    song_id string
    title   undefined
    release string
    artist_name string
    year    integer
Rows: 11
Data:
+----------------+---------------------+----------------+----------------+----------------+
| user_id        | incremental_song_id | score          | rank           | X1             |
+----------------+---------------------+----------------+----------------+----------------+
| b80344d063b5...| 114557              | 0.0461493      | 1              | 114578         |
| b80344d063b5...| 117491              | 0.0400819      | 10             | 117512         |
| b80344d063b5...| 333053              | 0.041788       | 8              | 333174         |
| b80344d063b5...| 381319              | 0.0403042      | 9              | 381465         |
| b80344d063b5...| 381319              | 0.0403042      | 9              | 444615         |
| b80344d063b5...| 563380              | 0.0426116      | 5              | 563705         |
| b80344d063b5...| 677759              | 0.0423951      | 6              | 678222         |
| b80344d063b5...| 689170              | 0.0418951      | 7              | 689654         |
| b80344d063b5...| 834311              | 0.0436045      | 2              | 834983         |
| b80344d063b5...| 939015              | 0.043068       | 3              | 939863         |
+----------------+---------------------+----------------+----------------+----------------+
+----------------+----------------+----------------+----------------+----------------+
| song_id        | title          | release        | artist_name    | year           |
+----------------+----------------+----------------+----------------+----------------+
| SOHENSJ12AAF...| Great Indoors  | Room For Squ...| John Mayer     | 0              |
| SOOGZYY12A67...| Crying Shame   | In Between D...| Jack Johnson   | 2005           |
| SOGFKJE12A8C...| Sun It Rises   | Fleet Foxes    | Fleet Foxes    | 2008           |
| SOECLAD12AAF...| St. Patrick'...| Room For Squ...| John Mayer     | 0              |
| SOECLAD12AAF...| St. Patrick'...| Room For Squ...| John Mayer     | 0              |
| SOAYTRA12A8C...| All At Once    | Sleep Throug...| Jack Johnson   | 2008           |
| SOKLVUI12A67...| If I Could     | In Between D...| Jack Johnson   | 2005           |
| SOYIJIL12A67...| Posters        | Brushfire Fa...| Jack Johnson   | 2000           |
| SORKFWO12A8C...| Quiet Houses   | Fleet Foxes    | Fleet Foxes    | 2008           |
| SOJAMXH12A8C...| Meadowlarks    | Fleet Foxes    | Fleet Foxes    | 2008           |
+----------------+----------------+----------------+----------------+----------------+
[11 rows x 10 columns]

Последняя таблица напечатана наши рекомендуемые песни, а первый – «Великий в помещении»! Теперь мы можем использовать наши MLRECommender Для других идентификаторов пользователей.

Заворачивать

Во-первых, мы посмотрели на MLRECommender конструктор. Тогда мы собрали данные песни из миллионов песни набора данных. Мы модифицировали набор данных для увеличения разборчивости и добавлены инкрементные идентификаторы для метаданных песни. Мы загрузили метаданные песни и истории прослушивания в Swift Playground, создали MLRECommender Из истории прослушивания и созданные рекомендуемые песни. Затем мы использовали песни метаданные, чтобы присоединиться к рекомендуемым песням к своим названиям и артистам.

Исходные файлы

Каждый из файлов, упомянутых в этом руководстве, можно найти здесь , включая:

  • Songs.csv : Метаданные на миллион песен
  • History.txt : История прослушивания песни для нескольких пользователей
  • data-parser.py : Код Python для манипулирования набора данных Million Song
  • merged_listed_data.csv : Объединенный набор данных песни метаданных и истории прослушивания
  • merged_listed_data_incremental_song_id.csv. : merged_listed_data.csv с добавленными инкрементными идентификаторами
  • songs_incremental_id.csv : Songs.csv с инкрементными идентификаторами добавлен
  • Musicrecommender.playground : Swift Playground для создания MLRECommender

Этот пост в блоге был вдохновлен Эриком Ле ‘ Как построить простую систему соревновательной песни Отказ

Оригинал: “https://dev.to/nickymarino/how-to-build-a-song-recommender-using-create-ml-mlrecommender-45h1”