2015-03-31 71 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