Je suis un peu confus avec la façon dont le SVD est utilisé dans le filtrage collaboratif. Supposons que j'ai un graphique social et que je construise une matrice d'adjacence à partir des bords, puis je prends un SVD (oublions la régularisation, les taux d'apprentissage, les optimisations de rareté, etc.), comment utiliser ce SVD pour améliorer mes recommandations?
Supposons que mon graphe social corresponde à instagram, et que j'ai été chargé de recommander des utilisateurs dans le service, basé uniquement sur le graphe social. Je voudrais d'abord construire une matrice de contiguïté , prendre le SVD, , choisir les premières valeurs propres, alors quoi?
Je créerais probablement un nouvel ensemble de matrices: alors que fait-on?
J'ai regardé sur le Web, et la plupart des liens se concentrent sur le calcul de la SVD, mais personne ne vous dit quoi en faire. Donc qu'est ce que je devrais faire?
la source
Réponses:
Cependant: avec la SVD pure vanille, vous pourriez avoir des problèmes pour recréer la matrice d'origine, sans parler de prédire les valeurs des éléments manquants. La règle générale utile dans ce domaine consiste à calculer la note moyenne par film et à soustraire cette moyenne pour chaque combinaison utilisateur / film, c'est-à-dire en soustrayant le biais du film de chaque utilisateur. Ensuite, il est recommandé d'exécuter SVD, et bien sûr, vous devrez enregistrer ces valeurs de biais quelque part, afin de recréer des évaluations ou de prévoir des valeurs inconnues. J'avais lu le post de Simon Funk sur SVD pour des recommandations - il a inventé une approche incrémentielle SVD pendant la compétition Netflix.
http://sifter.org/~simon/journal/20061211.html
Je suppose que la matrice dégradante A avant SVD est logique, car le proche cousin PCA de SVD fonctionne également de la même manière. En termes de calcul incrémental, Funk m'a dit que si vous ne dégradez pas, la première direction du gradient domine le reste du calcul. J'ai vu cela de première main, fondamentalement sans que les choses dégradantes ne fonctionnent pas.
la source
Je voudrais exprimer une opinion dissidente:
Bords manquants en tant que valeurs manquantes
Dans un problème de filtrage collaboratif, les connexions qui n'existent pas (l'utilisateur n'a pas évalué l'élément j , la personne x n'a pas ajouté la personne y ) sont généralement traitées comme des valeurs manquantes à prévoir, plutôt que comme des zéros. Autrement dit, si l'utilisateur i n'a pas évalué l'élément j , nous voulons deviner ce qu'il pourrait le noter s'il l' avait évalué. Si la personne x n'a pas friended y , nous voulons deviner comment il est probable qu'il avait envie à un ami lui. Les recommandations sont basées sur les valeurs reconstruites.je j X y je j X y
Lorsque vous prenez le SVD du graphique social (par exemple, branchez-le
svd()
), vous imputez essentiellement des zéros dans tous ces endroits manquants. Le fait que cela pose problème est plus évident dans la configuration de la classification des éléments utilisateur pour le filtrage collaboratif. Si j'avais un moyen de remplir de manière fiable les entrées manquantes, je n'aurais pas du tout besoin d'utiliser SVD. Je donnerais juste des recommandations basées sur les entrées remplies. Si je n'ai aucun moyen de le faire, je ne devrais pas les remplir avant de faire le SVD. *SVD avec valeurs manquantes
Bien sûr, la
svd()
fonction ne sait pas comment gérer les valeurs manquantes. Alors, qu'est-ce que tu es censé faire exactement? Eh bien, il existe un moyen de recadrer le problème commeC'est vraiment le problème que vous essayez de résoudre, et vous n'allez pas l'utiliser
svd()
pour le résoudre. Une façon qui a fonctionné pour moi (sur les données de prix Netflix) était la suivante:Essayer d'adapter les entrées à un modèle simple, par . Cela fait vraiment du bon travail.X^i , j= μ + αje+ βj
Attribuez à chaque utilisateur un k- vecteur u i et à chaque élément j un k- vecteur v j . (Dans votre cas, chaque personne obtient un vecteur k droit et gauche ). Vous finirez par prédire les résidus sous forme de produits scalaires: ∑ u i m v j mje k uje j k vj k ∑ uje suisvj m
Utilisez un algorithme pour trouver les vecteurs qui minimisent la distance à la matrice d'origine. Par exemple, utilisez ce papier
Bonne chance!
*: Ce que Tenali recommande, ce sont essentiellement les voisins les plus proches. Vous essayez de trouver des utilisateurs similaires et de faire des recommandations à ce sujet. Malheureusement, le problème de rareté (~ 99% de la matrice manque de valeurs), il est difficile de trouver les voisins les plus proches en utilisant la distance cosinus ou la similitude jaccard ou autre. Il recommande donc de faire un SVD de la matrice (avec des zéros imputés aux valeurs manquantes) pour compresser d'abord les utilisateurs dans un espace de fonctionnalités plus petit, puis y faire des comparaisons. Faire SVD-voisins les plus proches est bien, mais je recommanderais toujours de faire le SVD dans le bon sens (je veux dire ... à ma façon). Pas besoin de faire une imputation de valeur absurde!
la source
La raison pour laquelle personne ne vous dit quoi en faire est que si vous savez ce que fait SVD, alors il est un peu évident de savoir quoi en faire :-).
Étant donné que vos lignes et colonnes sont le même ensemble, je vais expliquer cela à travers une matrice différente A. Laissez la matrice A être telle que les lignes sont les utilisateurs et les colonnes sont les éléments que l'utilisateur aime. Notez que cette matrice n'a pas besoin d'être symétrique, mais dans votre cas, je suppose qu'elle se révèle être symétrique. Une façon de penser à SVD est la suivante: SVD trouve un espace d'entités caché où les utilisateurs et les éléments qu'ils aiment ont des vecteurs d'entités étroitement alignés.
Maintenant, si je vous donne deux vecteurs du même espace de fonctionnalités et vous demande de trouver s'ils sont similaires, quelle est la chose la plus simple à laquelle vous pouvez penser pour y parvenir? Produit scalaire.
la source
Il s'agit d'essayer de répondre à la partie «comment faire» de la question pour ceux qui souhaitent mettre en œuvre pratiquement des recommandations SVD clairsemées ou inspecter le code source pour plus de détails. Vous pouvez utiliser un logiciel FOSS standard pour modéliser un SVD clairsemé. Par exemple,
vowpal wabbit
,libFM
ouredsvd
.vowpal wabbit
a 3 implémentations d'algorithmes "de type SVD" (chacun sélectionnable par l'une des 3 options de ligne de commande). Strictement parlant, ceux-ci devraient être appelés "factorisation matricielle approximative et itérative" plutôt que pure "SVD" classique, mais ils sont étroitement liés à la SVD. Vous pouvez les considérer comme une factorisation SVD approximative très efficace d'un zéros) matrice.Voici une recette complète et pratique pour faire des recommandations de films de style Netflix avec
vowpal wabbit
et son--lrq
option "quadratique de bas rang" ( ) qui semble fonctionner le mieux pour moi:Fichier de format de jeu de données
ratings.vw
(chaque note sur une ligne par utilisateur et film):Où le 1er numéro est la note (1 à 5 étoiles) suivie de l'ID de l'utilisateur qui a évalué et et l'ID du film qui a été évalué.
Les données de test sont dans le même format mais peuvent (facultativement) omettre la colonne des évaluations:
éventuellement parce que pour évaluer / tester les prédictions, nous avons besoin de notes pour comparer les prédictions. Si nous omettons les notes,
vowpal wabbit
prédira toujours les notes mais ne sera pas en mesure d'estimer l'erreur de prédiction (valeurs prédites par rapport aux valeurs réelles dans les données).Pour nous entraîner, nous demandons
vowpal wabbit
de trouver un ensemble deN
facteurs d'interaction latents entre les utilisateurs et les films qu'ils aiment (ou n'aiment pas). Vous pouvez penser à cela comme trouver des thèmes communs où des utilisateurs similaires évaluent un sous-ensemble de films de la même manière et utiliser ces thèmes communs pour prédire comment un utilisateur évaluera un film qu'il n'a pas encore évalué.vw
options et arguments que nous devons utiliser:--lrq <x><y><N>
trouve des facteurs latents "quadratiques de bas rang".<x><y>
: "um" signifie traverser les espaces de noms u [sers] et m [ovie] dans l'ensemble de données. Notez que seule la 1ère lettre de chaque espace de nom est utilisée avec l'--lrq
option.<N>
:N=14
ci-dessous le nombre de facteurs latents que nous voulons trouver-f model_filename
: écrire le modèle final dansmodel_filename
Ainsi, une simple commande de formation complète serait:
Une fois que nous avons le
ratings.model
fichier modèle, nous pouvons l'utiliser pour prédire des évaluations supplémentaires sur un nouvel ensemble de donnéesmore_ratings.vw
:Les prédictions seront écrites dans le fichier
more_ratings.predicted
.En utilisant
demo/movielens
dans l'vowpalwabbit
arborescence source, j'obtiens ~ 0,693 MAE (Mean Absolute Error) après une formation sur 1 million de classements d'utilisateurs / filmsml-1m.ratings.train.vw
avec 14 facteurs latents (ce qui signifie que la matrice centrale SVD est une matrice de 14 x 14 lignes x colonnes) et des tests sur le indépendant test-setml-1m.ratings.test.vw
. Quelle est la qualité de 0,69 MAE? Pour la gamme complète des prédictions possibles, y compris le cas non évalué (0) [0 à 5], une erreur de 0,69 est d'environ 13,8% (0,69 / 5,0) de la gamme complète, soit environ 86,2% de précision (1 - 0,138).Vous pouvez trouver des exemples et une démo complète pour un ensemble de données similaire (movielens) avec de la documentation dans l'
vowpal wabbit
arborescence source sur github:--rank
option--lrq
optionRemarques:
movielens
démo utilise plusieurs options que j'OMISE (pour simplifier) de mon exemple: en particulier--loss_function quantile
,--adaptive
et--invariant
--lrq
implémentation envw
est beaucoup plus rapide que--rank
, notamment lors du stockage et du chargement des modèles.Crédits:
--rank
l'option vw a été implémentée par Jake Hofman--lrq
L'option vw (avec suppression facultative) a été implémentée par Paul Minerola source
Je dirais que le nom
SVD
est trompeur. En fait, laSVD
méthode du système de recommandation n'utilise pas directement la factorisation SVD. Au lieu de cela, il utilise la descente de gradient stochastique pour former les biais et les vecteurs de facteurs.Les détails du
SVD
et desSVD++
algorithmes pour le système de recommandation peuvent être trouvés dans les sections5.3.1
et5.3.2
du livreFrancesco Ricci, Lior Rokach, Bracha Shapira, and Paul B. Kantor. Recommender Systems Handbook. 1st edition, 2010
.En Python, un package bien établi implémenté ces algorithmes est nommé
surprise
. Dans sa documentation , ils mentionnent également les détails de ces algorithmes.la source