Як використовувати SVD для спільної фільтрації?


30

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

Припустимо, мій соціальний графік відповідав instagram, і я покладав відповідальність рекомендувати користувачів у сервісі, спираючись лише на соціальний графік. Спочатку я хотів би побудувати матрицю суміжності , візьміть СВД, , вибирають перші власних значень, то що?A (m×m)A=UsVk

Імовірно, я б створив новий набір матриць: то що робити?

Unewm×ksnewk×kVnewk×m

Я дивився в Інтернеті, і більшість посилань зосереджуються на обчисленні SVD, але ніхто не каже вам, що з цим робити. То що мені робити?


1
Це може відповісти на ваше запитання: datascience.stackexchange.com/a/16523
avli

Відповіді:


7

Однак: з чистою SVD ванілі у вас можуть виникнути проблеми з відтворенням оригінальної матриці, не кажучи вже про передбачення значень пропущених елементів. Корисна велика норма в цій області - це обчислення середньої оцінки за фільм та віднімання цього середнього для кожної комбінації користувача / фільму, тобто віднімання зміщення фільму від кожного користувача. Тоді рекомендується запустити SVD, і, звичайно, вам доведеться десь записати ці значення зміщення, щоб відтворити рейтинги або передбачити невідомі значення. Я прочитав пост Саймона Функ на SVD для рекомендацій - він винайшов поступовий підхід SVD під час змагань Netflix.

http://sifter.org/~simon/journal/20061211.html

Я думаю, що матриця приниження A перед SVD має сенс, оскільки близький двоюрідний брат PCA також працює аналогічно. Що стосується покрокових обчислень, Функ сказав мені, що якщо ви не змішуєте, перший градієнтний напрямок домінує над рештою обчислень. Я бачив це з перших вуст, в основному без приниження речі не працюють.


24

Я хотів би запропонувати інша думка:

Пропущені краї як пропущені значення

У проблемі спільної фільтрації з'єднання, які не існують (користувачijxyijxy

Коли ви берете SVD соціального графіка (наприклад, підключіть його svd()), ви в основному вводите нулі у всі ці відсутні місця. Те, що це проблематично, очевидніше в налаштуваннях рейтингу користувачів-елементів для спільної фільтрації. Якби у мене був спосіб надійно заповнити пропущені записи, мені б зовсім не потрібно було використовувати SVD. Я б просто дав рекомендації на основі заповнених записів. Якщо у мене немає способу це зробити, я не повинен заповнювати їх перед тим, як зробити SVD. *

SVD з відсутніми значеннями

Звичайно, svd()функція не знає, як впоратися з відсутніми значеннями. Отже, що саме ти повинен робити? Ну, є спосіб переосмислити проблему як

k

Це справді проблема, яку ви намагаєтеся вирішити, і ви не збираєтесь її використовувати svd(). Спосіб, який працював на мене (за даними про призи Netflix), був такий:

  • X^i,j=μ+αi+βj

  • ikuijkvjkuimvjm

  • Скористайтеся деяким алгоритмом для пошуку векторів, які мінімізують відстань до вихідної матриці. Наприклад, використовуйте цей документ

Удачі!

*: Теналі, що рекомендує, - це в основному найближчі сусіди. Ви намагаєтеся знайти схожих користувачів і даєте рекомендації щодо цього. На жаль, проблема зрідженості (~ 99% матриці не вистачає значень) ускладнює пошук найближчих сусідів, використовуючи відстань косинусу або жакардову схожість чи що завгодно. Отже, він рекомендує зробити SVD матриці (з нулями, вписаними у відсутніх значень), щоб спершу стиснути користувачів у менший простір функцій, а потім зробити порівняння там. Робити SVD-найближчих сусідів добре, але я все-таки рекомендую робити SVD правильно (я маю на увазі ... мій шлях). Не потрібно робити безглузду імпутацію значення!


Це була насправді відповідь, яку я шукав, і хотів почути :) Дякую!
Вішал

Як не дивно, на запитання "Я подивився в Інтернеті, і більшість посилань зосереджено на обчисленні SVD, але ніхто не каже вам, що з цим робити. Так що мені робити?" або з цього приводу заголовок каже: "Як я використовую SVD для спільної фільтрації?"
TenaliRaman

Так, і моя відповідь узагальнила, як я використовую це для спільної фільтрації.
Ступчастий Джо Піт

1
+1, як я розумію, ви не обчислюєте матрицю низького рангу за допомогою SVD, а ітеративний метод мінімізації квадратичної помилки, правда? Однак, якщо я хочу використовувати SVD, я повинен заповнити пропущені записи деякими значеннями, перш ніж робити матричну факторизацію, правда?
авокадо

1
svd()

14

Причина, коли ніхто не каже вам, що з цим робити, це тому, що якщо ви знаєте, що робить SVD, то трохи очевидно, що з цим робити :-).

Оскільки ваші рядки та стовпці однакові, я поясню це через іншу матрицю А. Нехай матриця A буде такою, що рядки - це користувачі, а стовпці - елементи, які користувачеві подобається. Зауважте, що ця матриця не повинна бути симетричною, але у вашому випадку, мабуть, вона виявляється симетричною. Один із способів думати про SVD:

A=U×s×VUV

Тепер, якщо я даю вам два вектори з одного і того ж простору функцій і попрошу вас знайти, чи вони схожі, що найпростіше, що ви можете подумати для досягнення цього? Точковий продукт.

ijiUj


Два питання: 1) Чи заповнюєте пропущені значення нулем (елемент j не переглядається користувачем i) перед запуском SVD? 2) Як ви можете обчислити, чи сподобається новому користувачеві елемент j?
B_Miner

1
@B_Miner Привіт, вибачте за затримку відповіді. Відповіді: 1) Що ж, так, ми зазвичай заповнюємо пропущені значення нулем перед запуском SVD. Однак я зазвичай рекомендую заповнити його ненульовою оцінкою - наприклад, ви можете заповнити пропущені значення середньою оцінкою, яку користувач дав поки що. 2) Підхід на основі SVD призначений лише для відомих користувачів та відомих елементів. Він не може обробляти нових користувачів або нових елементів. І як це зробити, якщо прийде новий користувач, ми нічого не знаємо про нього в цьому рамках, щоб передбачити.
TenaliRaman

1
@B_Miner Якщо ви хочете працювати з новими користувачами / елементами, ми повинні припустити, що ми маємо доступ до деяких функцій користувача та функцій елементів. Потім ви можете використовувати більш складну модель на зразок PDLF (модель прогнозного дискретного латентного фактора). Це дозволить вам обробляти нових користувачів / елементів, оскільки він працює з відомим простором функцій.
TenaliRaman

@TenaliRaman Не впевнений, чи побачиш це, але ось іде. Тому я використовував тематичні моделі (LDA) для створення функцій для користувачів (буквально користувачів) на основі прочитаних документів. Я просто середній за тематичними векторами, щоб отримати "вектор-тему користувача". Я хочу зробити щось подібне зі SVD (або ALS можливо). Скажімо, я обчислюю SVD за допомогою відомих даних про елементи користувача, а потім у мене з’являються нові користувачі, які «відвідують» кілька відомих елементів. У цьому випадку елементи векторів відомі, але користувацькі вектори невідомі. Чи можу я використовувати елементи векторів для обчислення вектора користувача чи мені потрібно ще раз обчислити SVD, використовуючи всі дані?
thecity2

чудова відповідь теналі. дуже корисний для розуміння концепції
Nihal

3

Це потрібно спробувати відповісти на питання "як це зробити" для тих, хто хоче практично реалізувати рекомендації з обмеженим SVD або перевірити вихідний код на предмет деталей. Для моделювання sparse-SVD можна використовувати програмне забезпечення FOSS, що не використовується на постійній основі. Так , наприклад, vowpal wabbit, libFM, або redsvd.

vowpal wabbitмає 3 реалізації алгоритмів "подібних до SVD" (кожен з них може бути обраний одним із 3 варіантів командного рядка). Строго кажучи, їх слід називати "приблизною, ітеративною, матричною факторизацією", а не чистою "класичною" SVD ", але вони тісно пов'язані з SVD. Ви можете вважати їх як дуже обчислювально ефективну приблизну SVD-факторизацію розріджених (переважно нулі) матриця.

Ось повний, працюючий рецепт для виконання рекомендацій щодо фільму в стилі Netflix vowpal wabbitта його "низько оціненого квадратичного" ( --lrq) варіанту, який, здається, найкраще працює для мене:

Файл формату набору даних ratings.vw(кожна оцінка в одному рядку за користувачем та фільмом):

5 |user 1 |movie 37
3 |user 2 |movie 1019
4 |user 1 |movie 25
1 |user 3 |movie 238
...

Якщо 1-е число - це рейтинг (від 1 до 5 зірок), за яким слід ідентифікатор користувача, який оцінив, та ідентифікатор фільму, який був оцінений.

Дані тесту у тому ж форматі, але можуть (необов'язково) пропускати стовпець оцінок:

 |user 1 |movie 234
 |user 12 |movie 1019
...

необов'язково, тому що для оцінки / тестування прогнозів нам потрібні рейтинги для порівняння прогнозів. Якщо ми опустимо рейтинги, vowpal wabbitусе ще прогнозуватиме рейтинги, але не зможе оцінити помилку прогнозування (прогнозовані значення проти фактичних значень у даних).

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

vw варіанти та аргументи, які нам потрібно використовувати:

  • --lrq <x><y><N> виявляє "низько оцінені квадратичні" латентні фактори.
  • <x><y>: "um" означає перекреслити проміжки імен u [sers] та m [ovie] у наборі даних. Зауважте, що лише 1-я літера у кожному просторі імен використовується з --lrqопцією.
  • <N>: N=14нижче - кількість прихованих факторів, які ми хочемо знайти
  • -f model_filename: запишіть остаточну модель в model_filename

Таким простим повним командним тренуванням було б:

    vw --lrq um14 -d ratings.vw -f ratings.model

Щойно у нас є ratings.modelмодельний файл, ми можемо використовувати його для прогнозування додаткових рейтингів нового набору даних more_ratings.vw:

    vw -i ratings.model -d more_ratings.vw -p more_ratings.predicted

Прогнози будуть записані у файл more_ratings.predicted.

Використовуючи demo/movielensв vowpalwabbitдереві джерел, я отримую ~ 0,693 МАЕ (середня абсолютна помилка) після тренування на 1 мільйон рейтингів користувачів / фільмів ml-1m.ratings.train.vwз 14 латентними факторами (мається на увазі, що середня матриця SVD є матрицею 14x14 рядків x стовпчиками) та тестування на незалежній тестовий набір ml-1m.ratings.test.vw. Наскільки добре 0,69 МАЕ? Для повного діапазону можливих прогнозів, включаючи неоцінений (0) випадок [0 до 5], похибка 0,69 становить ~ 13,8% (0,69 / 5,0) від повного діапазону, тобто приблизно 86,2% точності (1 - 0,138).

Ви можете знайти приклади та повну демонстрацію подібного набору даних (movielens) з документацією у vowpal wabbitвихідному дереві на github:

Примітки:

  • movielensДемо використовує кілька варіантів я опущені (для простоти) з мого прикладу: зокрема --loss_function quantile, --adaptiveі--invariant
  • --lrqРеалізація в vwнабагато швидше , ніж --rank, зокрема , при зберіганні і завантаженні моделей.

Кредити:

  • --rank Варіант vw був реалізований Джейком Хофманом
  • --lrq Варіант vw (з додатковим відмовою) був реалізований Полом Мінеро
  • vowpal wabbit (він же vw) є мозком дитини Джона Лангфорда

1

Я б сказав, що назва SVDвводить в оману. Насправді SVDметод у системі рекомендацій безпосередньо не використовує SVD-факторизацію. Натомість він використовує стохастичний градієнтний спуск для тренувань перекосів та факторних векторів.

Деталі SVDта SVD++алгоритми для системи рекомендацій можна знайти у розділах 5.3.1та 5.3.2книзі Francesco Ricci, Lior Rokach, Bracha Shapira, and Paul B. Kantor. Recommender Systems Handbook. 1st edition, 2010.

У Python існує добре налагоджений пакет, реалізований названими алгоритмами surprise. У своїй документації вони також згадують деталі цих алгоритмів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.