Використання autoencoder-ів для побудови рекомендаційної системи

Як і в багатьох рекоммендационных системах у нас є продукти, користувачі і оцінки, які виставляють користувачі (явно чи не явно) продуктів. Наше завдання передбачити оцінки продуктів, які ще не оцінив користувач і тим самим передбачити ті продукти, які можуть бути високо оцінені користувачами, або продукти, які можуть бути цікаві користувачам. (В чому і полягає функція рекомендационой системи — знайти продукти, які можуть бути потенційно цікаві користувачеві.)

Необхідно було розробити рекомендаційну систему, яка б:

  1. Була оптимальна з точки зору швидкості роботи після навчання моделі.
  2. Вимагала б мінімальних витрат на обробку нових вхідних даних. Тобто щоб рекомендаційною системі не було б повне перенавчання або ж донавчання після отримання нових даних або ж щоб операції такого роду були б мінімальні (можливо, ми б втрачали в якості роботи, але при цьому не вимагали би значних витрат на повторне побудова моделі).

Рішення
Основні концепції пропонованого рішення
Як і в будь класичної рекомендаційною системі у нас є: продукти, користувачі та оцінки користувачами продуктів.

Для кожного продукту користувача і ми визначаємо N-мірний вектор. Тобто кожен продукт і кожен користувач представлений у нас точкою в N-мірному просторі. Використовуємо два простору. Одне для користувачів, друге – для продуктів. (Вектора ідентифікатори користувачів і продуктів.)

Так само використовуємо дані про користувача, продукт, оцінки при побудові моделі і при отриманні результатів оцінок продуктів для користувачів.

Наприклад, для набору даних MovieLens 1M ми використовуємо:

  • такі дані про користувача як, стать користувача і вік (вектора розміром 2 елементи);
  • або ж для фільму (продукту) ми використовуємо рік створення фільму (вектори одиничної довжини);
  • а для виставленої оцінки те в який день тижня вона була виставлена (вектора одиничної довжини).
(Дивіться вихідний код демонстрації.) Також слід враховувати, що ще використовуються вектори ідентифікаторів користувачів і продуктів (розміру N).

Такі дані евристично дозволяють робити більш точні оцінки продуктів для користувачів. Ці дані перетворюються в вектора:

  • даних про користувача;
  • даних про продукт;
  • даних про оцінку;
  • сама оцінка або безлічі оцінок.
Використання autoencoder-ів
Для отримання N-мірних векторів для кожного продукту/користувача ми використовуємо наступну схему з використанням autoencoder-ів.

Нагадаю, що у autoencoder навчається стискати дані подані на його входи і представляти вхідні дані в стислому вигляді.

Ми використовуємо два autoencoder-а. На вхід (і як цільове значення) ми подаємо список з M (число, що дорівнює 5-7) записів, кожна з яких являє собою:

  1. autoencoder-а, який навчається на даних про оцінки користувачів, ми використовуємо значення: 1) вектор ідентифікатора користувача; 2) даних про користувача, выставившем оцінку даного продукту (вектор даннах користувача); 3) даних оцінки, які виставив користувач даного продукту (вектор даних про оцінку); 4) самі оцінки (вектор значень оцінки).При цьому для даного autoencoder-а всі значення задаються для одного продукту (на один цикл навчання), хоча і для різних оцінок (які ми маємо в системі) користувачів цього продукту. (Для даних MovieLens1M ми задаємо M записів види: 1) вектор з N значень — вектор ідентифікатор користувача;2) вектор з 2 значень — дані про користувача; 3) вектор з одного значення — день тижня виставлення оцінки; 4) вектор з одного значення — сама оцінка. Тобто все ми задаємо M*(N+2+1+1) значень на входи autoencoder-а у разі MovieLens1M.)

  2. autoencoder-а, який навчається на даних про оцінки продуктів, ми використовуємо значення: 1) вектор ідентифікатор продукту (вектор з N елементів); 2) даних про продукті, які оцінив цей користувач (вектор даних про продукт); 3) дані оцінки продукту користувачем (вектор даних про оцінку); 4) самі оцінки (вектор оцінки/оцінок). При цьому всі значення задаються для одного користувача і для різних продуктів, які були оцінені цими даними користувачем.
Таким чином, ми отримуємо в процесі навчання (на кожному кроці навчання) autoencoder-ів на входах (і цільових значень) список з M оцінок:

  1. Для одного продукту — M оцінок користувачів, оцінили продукт (у першому autoencoder-е).

  2. Для одного користувача — M оцінок продуктів, оцінених даними користувачем (у другому autoencoder-е).
Також ми отримуємо, що перший autoencoder кодує вектор ідентифікатор продукту, а другий кодує вектор ідентифікатора користувача.

У мінімальному випадку ми можемо задавати (для першого autoencoder-а) тільки вектора ідентифікаторів користувача та оцінки. А для другого autoencoder-а тільки вектора ідентифікаторів продуктів і оцінки. Тобто опустити дані про користувачів, продуктах і оцінках. Як показано на рис 1.


Рис. 1. Схема тренування autoencoder-ів при використанні мінімальних даних для тренування (тільки вектора ідентифікаторів користувачів, вектора ідентифікаторів продуктів і оцінки). А також схема отримання векторів ідентифікаторів при кодуванні autoencoder-ами.

Як отримувати вектора ідентифікатори користувачів і продуктів
Вони виходять наступним чином. Після декількох циклів навчання autoencoder-ів (близько 100..1000) ми задаємо для другого autoencoder-а значення оцінок продуктів одним користувачем (для кожного користувача задаємо K різних варіантів (число близько 24..64) або значення оцінок користувачів для одного продукту для першого autroencoder-а.

Припустимо, для одного користувача ми поставили K варіантів (випадкових) оцінок продуктів (другий autoencoder), тобто сформували K різних входів для autoencoder-а. При цьому ми отримали K різних стислих значень отриманих при роботі autoencoder-а. (Тобто ми отримали K векторів часткових ідентифікаторів користувача) (Зрозуміло, що ми повинні будувати такий autoencoder, який би мав середній шар, що складається з N елементів, тобто був би дорівнює розміру вектора ідентифікатора користувача/продукту.) Ми знаходимо середнє з цих значень K. Це і буде нове значення вектора ідентифікатора користувача, до якого ми будемо рухатися від поточного значення вектора ідентифікатора користувача. Так ми робимо для деякого числа (L1) користувачів і отримуємо L1 середніх значень.

Аналогічно ми отримуємо L2 середніх значень стислих і autoencoder-му, учнем на оцінках користувачів (або кодирующим ідентифікатори продукту).

Якщо спочатку ми використовуємо випадкові значення векторів ідентифікаторів користувачів і продуктів, то ми можемо рухатися від наших початкових значень, отриманих L1 і L2 середнім стисненим (середні стислі і будуть новими цільовими векторами ідентифікаторів).

Ми використовуємо евристику плавного рух до цільових значень ідентифікаторів. Ми поступово змінюємо вектора ідентифікаторів користувачів і продуктів до отриманих цільових значень векторів ідентифікаторів користувачів і продуктів.

Для того, щоб отримати задовільні значення для векторів ідентифікаторів користувачів і продуктів потрібно враховувати і ще один аспект роботи autoencoder-ів – це «дихання» закодованих значень або групове плавання значень в деяких межах. При «диханні» закодованих значень autoencoder-ів усі отримані значення зміщують на деяке зміщення в ході навчання. У результаті, якщо ми буде використовувати закодовані значення без будь-якої корекції, то векторах ідентифікаторів буде складно сходитися. Ця задача досить легко вирішується. Як це здійснюється я докладно не описую. Цей момент вирішено з допомогою знаходження середніх зміщень нових отриманих векторів ідентифікаторів користувачів/продуктів щодо попередніх значення векторів ідентифікаторів користувачів/продуктів. І далі здійснюється коригування попередніх значень векторів ідентифікаторів без врахування середнього змішування.(Дивіться вихідних код демонстрації для отримання докладної інформації.)

Отримання оцінок продуктів для користувача
Коли у нас є ідентифікатори, то вони виявляються впорядкованими в N-мірному просторі користувачів або ж продуктів. Близькі продукти/користувачі (виходячи з оцінок користувачів) знаходяться на малій відстані (евклідова метрика). Далі ми можемо використовувати нейронну мережу для отримання передбачення щодо: 1) вектору ідентифікатором продукту; 2) даними про продукт; 3) даними про можливу оцінці продукту (не самій оцінці, а це, наприклад, день тижня/час, коли користувач хоче подивитися/вже подивився фільм); 4) вектору ідентифікатора користувача; 5) даними про користувача. Використовуючи всі ці дані ми навчаємо нейронну мережу для прогнозування оцінки (оцінок), які може дати користувач даного продукту при даних умовах.

Побудова моделі
Ми повторюємо навчання autoencoder-ів та нейронної мережі для апроксимації функції оцінки користувачем продукту. Є деякі нюанси холодного старту навчання autoencoder-ів з випадкових початкових значень. Запропоновані евристики для вирішення цих проблем можна знайти в пропонованому вихідному коді до статті.

Після навчання ми отримуємо модель, що складається з ідентифікаторами користувачів і продуктів з нейронних мереж – двох autoencoder-ів і нейронної мережі передбачення оцінки.

Робота з системою після отримання моделі
Після навчання системи ми можемо визначити оцінки для продуктів, які не оцінили користувачі. Але також важливим моментом служить можливість того, що ми можемо:

  1. Додавати нові оцінки і коригувати вектори ідентифікаторів користувачів і продуктів.
  2. Додавати нові продукти і нових користувачів. Тобто обчислювати вектори ідентифікаторів для нових користувачів і продуктів.
Для обчислення векторів нових ідентифікаторів ми використовуємо autoencoder-и з отриманої моделі. При цьому ми використовуємо той же процес, що і процес отримання векторів ідентифікаторів при навчанні моделі, за виключенням того, що ми не навчаємо encoder-и на нових даних, а лише обчислює ідентифікатори.

Процес обчислення ідентифікаторів може бути використаний і при появі нових оцінок. В цьому випадку ми можемо коригувати ідентифікатори. В рамках вже навченої моделі, тобто знову ж не переобучая/не дообучая autoencoder-и.

При обчисленні/коригування ідентифікаторів ми, звичайно ж, в цілях швидкості обробки не коригуємо частина моделі задається нейронними мережами. Але нові дані можуть змінювати/розширювати модель, так що така зміна/розширення не може бути виражено тільки в обчисленні векторів ідентифікаторів користувачів/продуктів, тому гарною евристикою може бути донавчання моделі через деякий інтервал часу (раз на день/тиждень/місяць/квартал). Таке донавчання можна проводити паралельно нормальної роботи системи в рамках передбачення оцінок, додавання нових продуктів, користувачів, додавання нових оцінок.

Що дає запропонований підхід
Крім вирішення завдань, які ставилися у постановці задачі, також даний підхід дає можливість вводити в системи машинного навчання пам'ять. Тут під пам'яттю можна розуміти безпосередньо значення обчислених ідентифікаторів. Вони в рамках моделі можуть представляти об'єкти зовнішнього світу, несучи в собі деякий опис об'єкта зовнішнього світу з точки зору системи (деяких оцінок системи даних об'єктів). Така пам'ять може бути використана для опису об'єкта.

Крім цього даний підхід дає можливість задавати велику кількість параметрів, якими визначаються вектори ідентифікаторів користувачів і продуктів, а також параметрів оцінки. (Можливо, в цьому випадку має сенс використовувати евристику завдання ступеня впливу певних даних на процес навчання.)

» Вихідний код демонстрації рекоммендательной системи за даного підходу
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.