2014-10-05 142 views
11

我正在做一個任務,我試圖爲Netflix獎品數據構建一個協作過濾模型。我使用的數據是一個CSV文件,我可以輕鬆導入到數據框中。現在我需要做的是創建一個由用戶組成的稀疏矩陣作爲行和電影列,每個單元格填充相應的評估值。當我嘗試繪製數據框中的值時,我需要爲數據框中的每一行運行循環,這在R中花費了大量時間,請任何人都可以提出更好的方法。下面是示例代碼和數據:從數據幀創建稀疏矩陣

MovieID UserID Rating 
1  1  2  3 
2  2  3  3 
3  2  4  4 
4  2  6  3 
5  2  7  3 

所以在最後我想是這樣的:

buildUserMovieMatrix <- function(trainingData) 
{ 
    UIMatrix <- Matrix(0, nrow = max(trainingData$UserID), ncol = max(trainingData$MovieID), sparse = T); 
    for(i in 1:nrow(trainingData)) 
    { 
    UIMatrix[trainingData$UserID[i], trainingData$MovieID[i]] = trainingData$Rating[i]; 
    } 
    return(UIMatrix); 
} 

從正在創建稀疏矩陣在數據幀的數據樣本 列是電影ID和行中的用戶ID

1 2 3 4 5 6 7 
1 0 0 0 0 0 0 0 
2 3 0 0 0 0 0 0 
3 0 3 0 0 0 0 0 
4 0 4 0 0 0 0 0 
5 0 0 0 0 0 0 0 
6 0 3 0 0 0 0 0 
7 0 3 0 0 0 0 0 

所以解釋是這樣的:用戶2級電影1爲3星級,用戶3額定電影2爲3 STA r等等其他用戶和電影。我的數據框中有大約8500000行,我的代碼只需要大約30-45分鐘來創建此用戶項目矩陣,我想獲得任何建議

回答

12

Matrix包有你的類型的數據,特別是做了一個構造函數:

library(Matrix) 
UIMatrix <- sparseMatrix(i = trainingData$UserID, 
         j = trainingData$MovieID, 
         x = trainingData$Rating) 

否則,你可能會喜歡寂寂稱爲矩陣索引的[函數的很酷的功能。你可以嘗試:

buildUserMovieMatrix <- function(trainingData) { 
    UIMatrix <- Matrix(0, nrow = max(trainingData$UserID), 
         ncol = max(trainingData$MovieID), sparse = TRUE); 
    UIMatrix[cbind(trainingData$UserID, 
       trainingData$MovieID)] <- trainingData$Rating; 
    return(UIMatrix); 
} 

(但我肯定會推薦在這個的sparseMatrix方法。)

+0

非常感謝!!!,這工作絕對好。 – user37940 2014-10-05 23:43:14

+0

sparseMatrix方法比第二種方法更快,謝謝。 :) – user37940 2014-10-05 23:50:45

9

這可能會比循環更快。

library(reshape2) 
m <- dcast(df,UserID~MovieID,fill=0)[-1] 
m 
# 1 2 
# 1 3 0 
# 2 0 3 
# 3 0 4 
# 4 0 3 
# 5 0 3 

如果使用data.tables,這將是很多更快:

library(data.table) 
DT <- as.data.table(df) 
m <- dcast(DT,UserID~MovieID,fill=0)[-1] 

而且我敢肯定有人會指出,你可以用這個代替

setDT(df) 
m <- dcast(df,UserID~MovieID,fill=0)[-1] 

這將df轉換爲data.table(無需複製)。如果你的數據集是巨大的,是可以有所作爲...

+0

非常感謝! – user37940 2014-10-05 22:54:16

+1

雖然這種方法存在一個小問題,但這種方法並沒有正確地映射出USERID和MOVIEID,例如,用戶11從訓練數據中缺失,所以現在在第11行中我有用戶ID和用戶12的電影ID等級,並且隨後所有行都被移位了1,我的火車中有10916個用戶,並且我想保留所有這些都在我的用戶項目矩陣中,如果用戶從我的訓練數據中缺失,我可以將整行矢量標記爲零,這樣可以防止訓練數據數據框架和我的矩陣中的任何不匹配,您可以建議其他用戶方法,謝謝 – user37940 2014-10-05 23:24:07