🛒 Motore di Raccomandazione — Filtraggio Collaborativo dal Vivo
Simulatore interattivo di sistema di raccomandazione: una matrice di valutazioni utente-prodotto viene fattorizzata in vettori di gusto latenti — osserva le raccomandazioni aggiornarsi in tempo reale mentre un utente valuta altri prodotti.
Informazioni sul Filtraggio Collaborativo e la Fattorizzazione di Matrici
I sistemi di raccomandazione come quelli dietro i negozi online, i servizi di streaming e le piattaforme di marketing automation raramente sanno *perché* a un cliente piace un prodotto — vedono solo una tabella sparsa di chi ha valutato cosa. La fattorizzazione di matrici è la tecnica che trasforma quella tabella sparsa in previsioni: rappresenta ogni utente e ogni prodotto come un breve vettore di «fattori latenti» nello stesso spazio, appreso in modo che il prodotto scalare tra il vettore di un utente e quello di un prodotto ricostruisca le valutazioni effettivamente osservate. I prodotti che un utente non ha ancora valutato ottengono gratuitamente un punteggio previsto, semplicemente perché il loro vettore latente si trova vicino a prodotti che l'utente ha già valutato positivamente.
Questa simulazione addestra un vero modello di fattorizzazione di matrici di rango 2 con discesa del gradiente stocastica, interamente nel browser. Dieci utenti sintetici e dodici prodotti generano una matrice sparsa di valutazioni da 1 a 5 stelle a partire da fattori di gusto reali nascosti più rumore; il modello non vede mai quei vettori reali — vede solo le stelle sparse e deve ricostruire da zero uno spazio di gusto 2D sensato. Clicca su un utente per vedere le sue valutazioni osservate e le raccomandazioni top-N del modello dal vivo, poi aggiungi una nuova valutazione e osserva alcuni passi di gradiente extra spostare il punto di quell'utente — e la sua lista di raccomandazioni — in una nuova posizione.
Domande frequenti
Cos'è il filtraggio collaborativo?
Il filtraggio collaborativo prevede cosa piacerà a un utente in base ai pattern di valutazione dell'intera comunità, non su attributi di prodotto codificati a mano. L'idea di fondo è che utenti che si sono trovati d'accordo in passato probabilmente saranno d'accordo di nuovo. La fattorizzazione di matrici è la forma moderna del filtraggio collaborativo: comprime la matrice sparsa di valutazioni utente-prodotto in due piccole matrici dense di vettori latenti — una riga per utente, una per prodotto — il cui prodotto scalare ricostruisce le valutazioni osservate e, cosa cruciale, generalizza a quelle non osservate.
Cosa rappresenta effettivamente un fattore latente?
Un fattore latente è una dimensione che il modello inventa durante l'addestramento per spiegare i pattern di accordo nei dati di valutazione — non è scelto né etichettato da un essere umano. In questa simulazione ogni utente e prodotto finisce con un vettore 2D; i due assi potrebbero corrispondere vagamente a qualcosa come pratico-contro-giocoso o economico-contro-premium, ma il modello non vede mai quelle etichette. Vede solo numeri, e la discesa del gradiente scopre qualunque sistema di coordinate predica meglio le stelle osservate.
Cos'è il problema del cold-start per i nuovi utenti?
Un utente nuovo di zecca senza valutazioni ha un vettore latente che è solo la sua inizializzazione casuale — non porta alcun segnale sul suo gusto, quindi le previsioni per lui non sono migliori della valutazione media globale più rumore. Questo è il problema del cold-start: il filtraggio collaborativo ha bisogno di alcune interazioni osservate prima di poter collocare un utente in modo significativo nello spazio latente. In questo simulatore puoi osservarlo direttamente — aggiungi una singola valutazione per un utente e il suo punto salta visibilmente verso i prodotti che ha valutato positivamente.
Perché la loss viene calcolata solo sulle valutazioni osservate?
La matrice delle valutazioni è deliberatamente sparsa — ogni utente ha valutato solo una manciata del catalogo, quindi la stragrande maggioranza delle celle è semplicemente sconosciuta, non zero. Addestrare il modello a prevedere uno 0 o un valore medio per ogni voce non osservata gli insegnerebbe attivamente la cosa sbagliata. Invece, la loss dell'errore quadratico somma solo sulle coppie (utente, prodotto) che hanno realmente una valutazione a stelle: L = Σ(osservati) (r_ui − r̂_ui)². I gradienti fluiscono solo attraverso le celle con feedback reale, e i vettori latenti per le coppie non valutate vengono portati in posizioni sensate semplicemente condividendo righe e colonne con le celle osservate.
Cosa fa il termine di regolarizzazione?
L'obiettivo di addestramento aggiunge λ(‖u‖² + ‖p‖²) alla loss dell'errore quadratico, penalizzando i vettori latenti con magnitudine elevata. Senza di esso, un utente o un prodotto con pochissime valutazioni osservate può derivare verso un vettore estremo che si adatta quasi perfettamente a quei uno o due punti dati ma prevede in modo selvaggio per tutto il resto — un classico overfitting su dati sparsi. La regolarizzazione riporta i vettori verso lo zero a meno che i dati non forniscano prove ripetute e forti per spingerli più lontano, scambiando un po' di accuratezza sul training per una generalizzazione molto migliore.
Come cambia dal vivo le raccomandazioni l'aggiunta di una nuova valutazione?
Quando valuti un prodotto per l'utente selezionato, quella singola tripla (utente, prodotto, valutazione) viene aggiunta all'insieme osservato e l'ottimizzatore esegue un ulteriore lotto di passi di SGD concentrati sui dati aggiornati. Poiché i vettori utente e prodotto sono parametri condivisi, bastano pochi passi di gradiente extra per spostare la posizione latente dell'utente verso prodotti con fattori simili — puoi vedere il punto muoversi nel grafico a dispersione e la lista top-N prevista riordinarsi in meno di un secondo, senza riaddestrare da zero.
Perché usare la discesa del gradiente invece di risolvere direttamente per i fattori?
Se ogni voce della matrice delle valutazioni fosse osservata, la scomposizione ai valori singolari (SVD) potrebbe calcolare i fattori ottimali di rango basso direttamente in forma chiusa. Ma le vere matrici di valutazione sono estremamente sparse — un utente ha valutato una frazione minuscola del catalogo — quindi la SVD classica non è definita per le voci mancanti. La discesa del gradiente stocastica aggira elegantemente il problema: tocca solo le celle osservate, scala fino a milioni di valutazioni perché ogni aggiornamento è O(K) per valutazione, e supporta naturalmente aggiornamenti incrementali quando arrivano nuove valutazioni.
Perché l'RMSE si stabilizza invece di raggiungere lo zero?
Le valutazioni sintetiche in questa simulazione sono generate da fattori latenti reali più rumore casuale, quindi anche un modello perfetto non può prevedere esattamente le stelle rumorose ogni volta — esiste un pavimento di errore irriducibile fissato dalla varianza del rumore. Anche la regolarizzazione scambia deliberatamente un po' di accuratezza sul training per la generalizzazione. In pratica questo è salutare: un modello che porta l'RMSE a zero con solo due dimensioni latenti e poche valutazioni per utente sta quasi certamente memorizzando il rumore invece di imparare il gusto.
What does a latent factor actually represent?
A latent factor is a dimension the model invents during training to explain patterns of agreement in the rating data — it is not chosen or labelled by a human. In this simulation each user and product ends up with a 2D vector; the two axes might loosely correspond to something like practical-vs-playful or cheap-vs-premium purchasing taste, but the model never sees those labels. It only sees numbers, and gradient descent discovers whatever coordinate system best predicts the observed stars. That is why the axes have no fixed meaning across different training runs — only the relative positions of points to each other are meaningful.
What is the cold-start problem for new users?
A brand-new user with zero ratings has a latent vector that is just its random initialisation — it carries no signal about their taste, so predictions for them are no better than the global average rating plus noise. This is the cold-start problem: collaborative filtering needs some observed interactions before it can place a user meaningfully in latent space. In this simulator you can watch it directly — add a single rating for a user and their point visibly jumps toward the products they rated highly, and the recommendation list reorders immediately.
Why is the loss only computed over observed ratings?
The rating matrix is deliberately sparse — each user has only rated a handful of the catalogue, so the vast majority of entries are simply unknown, not zero. Training the model to predict a 0 or an average value for every unobserved entry would actively teach it the wrong thing (that unrated products are disliked). Instead, the squared-error loss sums only over the (user, item) pairs that actually have a star rating: L = Σ(observed) (r_ui − r̂_ui)². Gradients only flow through cells with real feedback, and the latent vectors for unrated pairs are pulled into sensible positions purely by sharing rows and columns with observed cells.
What does the regularization term do?
The training objective adds λ(‖u‖² + ‖p‖²) to the squared-error loss, penalising latent vectors with large magnitude. Without it, a user or product with very few observed ratings can drift to an extreme vector that fits those one or two data points almost perfectly but predicts wildly for everything else — classic overfitting on sparse data. Regularization shrinks vectors toward zero unless the data provides strong repeated evidence to push them further out, trading a little training accuracy for much better generalisation to the unrated products that recommendations actually depend on.
How does adding a new rating change the recommendations live?
When you rate a product for the selected user, that single (user, item, rating) triple is added to the observed set and the optimiser runs a further batch of SGD passes focused on the updated data. Because the user and product vectors are shared parameters, a handful of extra gradient steps is enough to nudge the user's latent position toward products with similar factors — you can watch the point move in the scatter plot and the top-N predicted list reorder within a second, without retraining from scratch.
Why use gradient descent instead of solving for the factors directly?
If every entry of the rating matrix were observed, singular value decomposition (SVD) could compute the optimal low-rank factors directly in closed form. But real rating matrices are extremely sparse — a user has rated a tiny fraction of the catalogue — so classical SVD is undefined for the missing entries. Stochastic gradient descent sidesteps this cleanly: it only ever touches observed cells, scales to millions of ratings because each update is O(K) per rating, and naturally supports incremental updates when new ratings arrive, which is exactly what the live retraining in this simulation relies on.
Why does RMSE plateau instead of reaching zero?
The synthetic ratings in this simulation are generated from ground-truth latent factors plus random noise, so even a perfect model cannot predict the exact noisy stars every time — there is an irreducible error floor set by the noise variance. Regularization also deliberately trades a little training-set accuracy for generalisation, further preventing RMSE from reaching zero. In practice this is healthy: a model that drives observed-set RMSE to zero with only two latent dimensions and a handful of ratings per user is almost certainly memorising noise rather than learning taste.
A user-item rating matrix factors into latent taste vectors — watch recommendations update live as a user rates more products.
3D · renderer Three.js / WebGL · target 60 FPS · funziona interamente lato client, senza installazione