Подтвердить что ты не робот

Совместная фильтрация в MySQL?

Я пытаюсь создать сайт, который рекомендует пользователям (fx. books) пользователям на основе их предпочтений. До сих пор я читал O'Reilly "Коллективный разум" и множество других онлайн-статей. Тем не менее, все они имеют дело с единичными примерами рекомендаций, например, если вам нравится книга A, тогда вам может понравиться книга B.

То, что я пытаюсь сделать, - создать набор "предпочтительных узлов" для каждого пользователя на моем сайте. Скажем, пользователю нравится книга A, B и C. Затем, когда они добавляют книгу D, я не хочу, чтобы система рекомендовала другие книги, основанные исключительно на других пользователях, с книгой D. Я не хочу, чтобы система искала аналогичные "предпочтения-узлы" и рекомендуют книги на основе этого.

Здесь приведен пример из 4 узлов:

User1: 'book A'->'book B'->'book C'
User2: 'book A'->'book B'->'book C'->'book D'
user3: 'book X'->'book Y'->'book C'->'book Z'
user4: 'book W'->'book Q'->'book C'->'book Z'

Итак, система рекомендаций, описанная в материале, который я прочитал, порекомендует книгу Z для пользователя 1, потому что есть два человека, которые рекомендуют Z в сочетании с симпатией C (т.е. Z весит больше D), даже хотя пользователь с аналогичным "предпочтением - node", User2, был бы более квалифицирован, чтобы рекомендовать книгу D, потому что у него более похожий шаблон интереса.

У кого-нибудь из вас есть какой-то опыт? Есть ли какие-то вещи, которые я должен попробовать прочитать, или существуют ли какие-либо системы с открытым исходным кодом для этого?

Спасибо за ваше время!

Небольшое редактирование: я думаю, что алгоритм last.fm делает именно то, что я должен делать. Использование предпочтений деревьев людей, чтобы рекомендовать музыку более лично для людей. Вместо того, чтобы просто сказать "вам может понравиться B, потому что вам понравился A"

4b9b3361

Ответ 1

Создайте таблицу и вставьте тестовые данные:

CREATE TABLE `ub` (
  `user_id` int(11) NOT NULL,
  `book_id` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`,`book_id`),
  UNIQUE KEY `book_id` (`book_id`,`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into ub values (1, 'A'), (1, 'B'), (1, 'C');
insert into ub values (2, 'A'), (2, 'B'), (2, 'C'), (2,'D');
insert into ub values (3, 'X'), (3, 'Y'), (3, 'C'), (3,'Z');
insert into ub values (4, 'W'), (4, 'Q'), (4, 'C'), (4,'Z');

Присоедините тестовые данные к себе с помощью book_id и создайте временную таблицу для хранения каждого user_id и количества книг, которые она имеет вместе с целевым user_id:

create temporary table ub_rank as 
select similar.user_id,count(*) rank
from ub target 
join ub similar on target.book_id= similar.book_id and target.user_id != similar.user_id
where target.user_id = 1
group by similar.user_id;

select * from ub_rank;
+---------+------+
| user_id | rank |
+---------+------+
|       2 |    3 |
|       3 |    1 |
|       4 |    1 |
+---------+------+
3 rows in set (0.00 sec)

Мы видим, что user_id имеет 3 общего с user_id 1, но user_id 3 и user_id 4 имеют только 1 каждый.

Затем выберите все книги, которые есть у пользователей во временной таблице, которые не соответствуют целевым книгам user_id, и упорядочивайте их по рангу. Обратите внимание, что одна и та же книга может отображаться в разных списках пользователей, поэтому мы суммируем рейтинг для каждой книги, чтобы общие книги получали более высокий рейтинг.

select similar.book_id, sum(ub_rank.rank) total_rank
from ub_rank
join ub similar on ub_rank.user_id = similar.user_id 
left join ub target on target.user_id = 1 and target.book_id = similar.book_id
where target.book_id is null
group by similar.book_id
order by total_rank desc;

+---------+------------+
| book_id | total_rank |
+---------+------------+
| D       |          3 |
| Z       |          2 |
| X       |          1 |
| Y       |          1 |
| Q       |          1 |
| W       |          1 |
+---------+------------+
6 rows in set (0.00 sec)

Книга Z появилась в двух списках пользователей и была ранжирована выше X, Y, Q, W, которая появилась только в одном списке пользователей. Книга D сделана лучше всего потому, что она появилась в списке user_id 2, который имел 3 элемента вместе с целевым user_id 1.