2015-03-31 1 views
4

Je participe à un concours de programmation, où j'ai des données où la première colonne est un utilisateur, la deuxième colonne est un film, et la troisième est un nombre dans le système d'évaluation de dix points.Prédire avec des matrices SVD

0 0 9 
0 1 8 
1 1 4 
1 2 6 
2 2 7 

Et je dois prévoir la troisième colonne (utilisateur, film,?):

0 2 
1 0 
2 0 
2 1 

Je sais aussi les réponses:

0 2 7.052009 
1 0 6.687943 
2 0 6.995272 
2 1 6.687943 

ces données dans une table: Lignes sont les utilisateurs 0, 1 et 2; les colonnes sont les films 0, 1 et 2; les cellules sont des scores, 0 ont pas voté:

 [,1] [,2] [,3] 
[1,] 9 8 0 
[2,] 0 4 6 
[3,] 0 0 7 

J'utilise R lang pour SVD get:

$d 
[1] 12.514311 9.197763 2.189331 

$u 
      [,1]  [,2]  [,3] 
[1,] 0.9318434 -0.3240669 0.1632436 
[2,] 0.3380257 0.6116879 -0.7152458 
[3,] 0.1319333 0.7216776 0.6795403 

$v 
      [,1]  [,2]  [,3] 
[1,] 0.6701600 -0.31709904 0.6710691 
[2,] 0.7037423 -0.01584988 -0.7102785 
[3,] 0.2358650 0.94825998 0.2125341 

Transposé v est:

  [,1]  [,2]  [,3] 
[1,] 0.6701600 0.7037423 0.2358650 
[2,] -0.31709904 -0.01584988 0.94825998 
[3,] 0.6710691 -0.7102785 0.2125341 

Et j'ai lu sur la prédiction de la classification des films en utilisant cette formule: enter image description here

Mais je ne comprends pas comment prédire évaluations comme ceci:

0 2 7.052009 
1 0 6.687943 
2 0 6.995272 
2 1 6.687943 

Pour ces données:

0 2 
1 0 
2 0 
2 1 

Répondre

5

Il y a plusieurs choses qui me semblent incorrectes avec votre exemple. Tout d'abord, lorsque vous n'avez pas de classement disponible pour une combinaison utilisateur/film spécifique, vous ne devez pas le remplir avec zéro. Cela indiquerait à la SVD ou à tout autre type d'analyse en composantes principales (PCA) que ce sont les rangs (qui sont artificiellement bas). De plus, les covariances calculées avec des données remplies de zéro seraient calculées sur la base d'un nombre incorrect d'observations.

Le gagnant du prix Netflix (link for more info) qui a utilisé l'approche SVD doit également avoir utilisé une sorte de routine PCA de données manquantes. Dans ce cas, les non-valeurs ne devraient pas être nulles, mais plutôt NaN, bien que je n'ai pas vu les détails de l'approche réelle qu'ils ont utilisée.

La deuxième question que j'ai est si "la réponse" que vous fournissez est vraiment basée sur le jeu de données plutôt petit que vous donnez dans l'exemple. Étant donné le jeu de données de 3 utilisateurs par 3, il y a très peu d'emplacements pour le calcul des corrélations entre utilisateurs, donc toute prédiction sera très mauvaise. Néanmoins, j'ai été capable de produire un résultat, mais cela ne correspond pas à votre réponse attendue. L'approche est appelée "Fonctions orthogonales empiriques soustraites récessivement" (RSEOF), qui est une approche PCA spécialement conçue pour gérer les données manquantes. Cela dit, je n'aurais pas beaucoup confiance dans les prédictions sans un ensemble de données d'entraînement plus important.

Alors, j'ai commencé en chargeant dans vos jeux de données d'origine et de prévision et remodelé les données de formation dans une matrice en utilisant acast du package reshape2:

library(reshape2) 
library(sinkr) (download from GitHub: https://github.com/menugget/sinkr) 

# Original data 
df1 <- data.frame(user=factor(c(0,0,1,1,2)), movie=factor(c(0,1,1,2,2)), rank=c(9,8,4,6,7)) 
df1 

# Data to predict 
df2 <-data.frame(user=factor(c(0,1,2,2)), movie=factor(c(2,0,0,1))) 
df2 

# Re-organize data into matrix(movies=rows, users=columns) 
m1 <- acast(df1, movie ~ user, fill=NaN) 
m1 

Ensuite, en utilisant la fonction eof du paquet sinkr (link) , nous effectuons la RSEOF:

# PCA of m1 (using recursive SVD) 
E <- eof(m1, method="svd", recursive=TRUE, center=FALSE, scale=FALSE) 
E$u 
E$A #(like "v" but with Lambda units added) 
E$Lambda 

valeurs prédites pour les NaN positions dans les données peuvent être obtenues par reconstru ction la matrice complète avec l'information PCA (En gros E$A %*% t(E$u)):

# Reconstruct full m1 matrix using PCs 
R <- eofRecon(E) 
R 

# Add predicted ranks to df2 
pos <- (as.numeric(df2$user)-1)*length(levels(df1$movie)) + as.numeric(df2$movie) 
pos 
df2$rank <- R[pos] 
df2 

L'objet df2 contient le spécifique prédit rangs pour les combinaisons utilisateur/film que vous avez spécifié dans votre jeu de données de prédiction:

user movie  rank 
1 0  2 9.246148 
2 1  0 7.535567 
3 2  0 6.292984 
4 2  1 5.661985 

I Personnellement, pensez que ces valeurs ont plus de sens que votre résultat attendu (tout autour de 7). Par exemple, quand on regarde la matrice des films (lignes) par les utilisateurs (colonnes), m1,

0 1 2 
0 9 NaN NaN 
1 8 4 NaN 
2 NaN 6 7 

j'attendre à ce que l'utilisateur « 0 » aimerait film « 2 » plus de film « 1 », étant donné que c'est la tendance pour l'utilisateur "1". Nous avons seulement des classements pour le film "1" en commun entre eux pour fonder nos prédictions. La valeur attendue était de 7,05, ce qui aurait été inférieur à celui du film "1" (c.-à-d. 8), alors que la prévision RSEOF est de 9,2.

J'espère que cela vous aide - mais, si votre réponse attendue est ce que vous photographiez, alors j'aurais des doutes sur la méthode utilisée par le "détenteur de la vérité". Il est plus probable que vous ayez simplement fourni une version plus petite de votre jeu de données, et nous n'allons donc pas arriver à la même réponse que dans votre exemple reproductible plus petit.

+0

"Tout d'abord, lorsque vous n'avez pas de classement disponible pour une combinaison utilisateur/film spécifique, vous ne devez pas le remplir avec zéro". C'est faux: c'est une approche standard prise dans les tâches d'achèvement de matrice. Voir toute référence sur le sujet (Wikipedia inclus). – vrume21

+0

@ vrume21 - Je crois que vous vous trompez. Les zéros ne peuvent être substitués qu'après avoir centré votre matrice. Si vous le faites à l'avance, vous fausserez fortement leur pondération. L'équivalent serait de remplacer les valeurs manquantes par la moyenne de chaque variable. –

3

Ceci est un problème d'achèvement de la matrice classique où nous remplaçons des valeurs inconnues avec des zéros dans la matrice de données. Vous devez d'abord prendre l'eigendecomposition de votre matrice de données (puisque c'est symétrique, mais SVD est équivalent, notez comment U == V). Alors vous avez A_pred = UEU^T, où A_pred est la version complète prédite de A (votre matrice de données). Ainsi, votre valeur prédite de A [i] [j] est simplement A_pred [i] [j].

+0

Merci beaucoup, mais je ne comprends pas. Puis-je avoir un exemple? – rel1x

+0

Qu'est-ce que vous ne comprenez pas? – vrume21

+0

Quelles devraient être mes prochaines étapes? Peut montrer l'exemple avec mes données comment prédire la notation? – rel1x