2015-03-31 73 views
4

我参加编程比赛,其中第一列是用户,第二列是电影,第三列是十分制评分系统中的数字。用SVD矩阵预测

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

而且我预测第三列(用户,电影,?):

0 2 
1 0 
2 0 
2 1 

而且我知道答案:

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

此表中的数据:行是用户0,1和2;列是电影0,1和2;细胞是得分,0未投票:

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

我用[R郎为GET SVD:

$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 

换位v是:

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

和我读到预测电影等级使用此公式: enter image description here

但我不知道如何预测评级是这样的:

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

对于这个数据:

0 2 
1 0 
2 0 
2 1 

回答

5

在你的例子中,有几件事对我来说似乎不正确。首先,当您没有可用于特定用户/电影组合的排名时,则不应将其填入零。这将告诉SVD或任何其他类型的主成分分析(PCA),这些是排名(这是人为低)。此外,用零填充数据计算的协方差将基于不正确的观察数来计算。

使用SVD方法的Netflix获奖者(link for more info)也必须使用某种丢失数据的PCA例程。在这种情况下,非值不应该为零,而应该是NaN,尽管我没有看到他们使用的实际方法的细节。

我的第二个问题是,如果您提供的“答案”确实基于您在示例中给出的相当小的数据集。给定3个用户由3个电影数据集组成,用户之间的相关性计算位置非常少,因此任何预测都会很差。尽管如此,我能够产生一个结果,但它不符合您的预期答案。

该方法被称为“递归减去经验正交函数”(RSEOF),这是专门设计的PCA方法来处理丢失的数据。也就是说,如果没有更大的训练数据集,我对预测没有多大信心。

于是,我开始在原始和预测的数据集加载并重塑了训练数据为使用acastreshape2包矩阵:

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 

然后使用sinkr包的eof功能(link)中,我们执行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 

用于在数据中的位置NaN预测值可以通过reconstru获得

# 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 

对象df2包含的具体预测行列,你在你的预测数据集中指定的用户/电影组合:

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

我与PCA信息(基本上E$A %*% t(E$u))电视机的全矩阵个人认为这些价值观比你期望的结果更有意义(全部7)。例如,看的时候在看电影(行)由用户(列),m1的矩阵,

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

我希望用户“0”希望电影“2”比电影更“1”,给予这是用户“1”的趋势。我们只有电影“1”的排名是他们之间的共同点,以此作为我们预测的基础。您的期望值为7.05,低于电影“1”(即8),而RSEOF预测值为9.2。

我希望这可以帮助你 - 但是,如果你的预期答案是你所拍摄的,那么我会怀疑“真相持有者”使用的方法。更可能的是,您仅提供了较小版本的数据集,因此我们不会得到与您的较小可重现示例中相同的答案。

+0

“首先,当您没有可用于特定用户/电影组合的排名时,则不应将其填入零。”这是错误的:这是在矩阵完成任务中采用的标准方法。查看关于这个主题的任何参考(包括维基百科)。 – vrume21 2015-04-10 12:46:53

+0

@ vrume21 - 我相信你错了。只有在将矩阵居中后,零才可以被替换。如果你事先这样做,那么你会严重偏斜他们的权重。相当于用每个变量的均值代替缺失值。 – 2015-04-10 12:57:43

3

这是一个典型的矩阵完成的问题,我们在数据矩阵零替换未知值。你首先需要对数据矩阵进行特征分解(因为它是对称的,但是SVD是等价的,请注意U == V)。然后你有A_pred = UEU^T,其中A_pred是A(你的数据矩阵)的预测完整版本。因此,你的A [i] [j]的预测值就是A_pred [i] [j]。

+0

非常感谢,但我不明白。我能举一个例子吗? – rel1x 2015-04-04 05:02:59

+0

你不明白什么? – vrume21 2015-04-04 15:36:24

+0

我应该怎样做下一步?可以用我的数据显示例子如何预测评分? – rel1x 2015-04-05 05:33:37