【问题标题】:Predict with SVD matrixes使用 SVD 矩阵进行预测
【发布时间】:2015-03-31 16:42:20
【问题描述】:

我正在参加编程竞赛,我有数据,其中第一列是用户,第二列是电影,第三列是十分评分系统中的数字。

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 lang 来获取 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

我阅读了有关使用以下公式预测电影收视率的信息:

但我不明白如何预测这样的收视率:

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

对于这个数据:

0 2
1 0
2 0
2 1

【问题讨论】:

    标签: r algorithm linear-algebra pca svd


    【解决方案1】:

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

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

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

    这种方法称为“递归减法经验正交函数”(RSEOF),它是专门设计的用于处理缺失数据的 PCA 方法。也就是说,如果没有更大的训练数据集,我对预测不会有太大信心。

    所以,我首先加载您的原始数据集和预测数据集,然后使用 reshape2 包中的 acast 将训练数据重新整形为矩阵:

    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包(link)的eof函数,我们执行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位置的预测值可以通过使用PCA信息重构完整矩阵来获得(基本上是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
    

    对象df2 包含您在预测数据集中指定的用户/电影组合的特定预测排名:

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

    我个人认为这些值比您的预期结果更有意义(都在 7 左右)。例如,当按用户(列)查看电影(行)矩阵时,m1

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

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

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

    【讨论】:

    • “首先,当您没有可用于特定用户/电影组合的排名时,您不应将其填入零”。这是错误的:这是矩阵完成任务中采用的标准方法。请参阅有关该主题的任何参考资料(包括维基百科)。
    • @vrume21 - 我相信你错了。只有在您将矩阵居中后,才可以替换零。如果你事先这样做,那么你会强烈地扭曲它们的权重。等效的方法是将缺失值替换为每个变量的平均值。
    【解决方案2】:

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

    【讨论】:

    • 非常感谢,但我不明白。我可以举个例子吗?
    • 你有什么不明白的?
    • 我的下一步应该是什么?可以用我的数据展示如何预测评分的示例吗?
    • 您已经计算了 A_pred,因为您已经采用了 SVD。您需要预测的评级是 A 中值为零的评级,因此您在 A 和 A_pred 中有它们的索引。对于每对索引 (I,j),预测评分为 A_pred[i][j]。
    • 但我没有计算 A_pred 也不知道该怎么做。这是我的问题。
    猜你喜欢
    • 2013-12-01
    • 1970-01-01
    • 2019-03-18
    • 2014-02-26
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    相关资源
    最近更新 更多