2010-03-14 11 views
12

Sono che prova per sviluppare un sito che consiglia gli elementi (libri fx.) Agli utenti in base alle loro preferenze. Finora, ho letto "Collective Intelligence" di O'Reilly e numerosi altri articoli online. Tutti, tuttavia, sembrano trattare singole istanze di raccomandazione, ad esempio se ti piace il libro A, potresti gradire il libro B.Filtraggio collaborativo in MySQL?

Quello che sto cercando di fare è creare un insieme di "nodi di preferenza" per ogni utente sul mio sito. Diciamo che a un utente piace il libro A, B e C. Quindi, quando aggiungono il libro D, non voglio che il sistema raccomandi altri libri basati esclusivamente su altri utenti con il libro D. Non voglio che il sistema cerchi simili 'nodi di preferenza' e consiglia libri basati su questo.

Ecco un esempio di 4 nodi:

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' 

Quindi un sistema di raccomandazione, come descritto nel materiale che ho letto, lo consigliano libro dalla Z alla User 1, perché ci sono due persone che si raccomanda Z la combinazione con Miking C (per esempio Z pesa più di D), anche se un utente con un simile "nodo di preferenza", Utente2, sarebbe più qualificato a raccomandare il libro D perché ha un modello di interesse più simile.

Così qualcuno di voi ha qualche esperienza con questo genere di cose? C'è qualche cosa che dovrei provare a leggere o esistono sistemi open source per questo?

Grazie per il vostro tempo!

Piccola modifica: Penso che l'algoritmo di last.fm stia facendo esattamente ciò che il mio sistema deve fare. Usare gli alberi delle preferenze delle persone per consigliare la musica più personalmente alle persone. Invece di limitarsi a dire "come si potrebbe B perché ti è piaciuto A"

risposta

32

creare una tabella e inserire i dati del test:

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'); 

Unire i dati di test su se stesso da libro_id, e creare una tabella temporanea per contenere ogni user_id e il numero di libri che ha in comune con l'obiettivo di 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) 

possiamo vedere che user_id ha 3 in comune con user_id 1, ma iD_utente 3 e 4 user_id hanno solo 1 ciascuno.

Successivamente, seleziona tutti i libri che gli utenti nella tabella temporanea hanno che non corrispondono ai libri del user_id di destinazione e disponili in ordine di classificazione. Si noti che lo stesso libro potrebbe apparire in elenchi di utenti diversi, quindi sommiamo le classifiche per ciascun libro in modo che i libri comuni ottengano un posizionamento più elevato.

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) 

Prenota Z è apparso in due elenchi di utenti, e così è stato classificato al di sopra X, Y, Q, W, che è apparso solo in lista di un utente. Il libro D ha fatto meglio perché è apparso nella lista user_id 2, che aveva in comune 3 elementi target user id 1.

+1

Wow, questa è una risposta davvero completa. Grazie mille! –

+0

questa è una risposta incredibile, ho usato una versione modificata di questo per il mio sito e funziona così bene. – Franco

Problemi correlati