2014-10-05 36 views
11

Tôi đang thực hiện bài tập nơi tôi đang cố xây dựng mô hình lọc cộng tác cho dữ liệu giải thưởng Netflix. Dữ liệu mà tôi đang sử dụng nằm trong tệp CSV mà tôi dễ dàng nhập vào khung dữ liệu. Bây giờ những gì tôi cần làm là tạo một ma trận thưa thớt bao gồm các Người dùng dưới dạng hàng và Phim làm các cột và mỗi ô được lấp đầy bởi giá trị xếp hạng tương ứng. Khi tôi cố gắng vạch ra các giá trị trong khung dữ liệu, tôi cần chạy một vòng lặp cho mỗi hàng trong khung dữ liệu, điều này tốn nhiều thời gian trong R, vui lòng bất cứ ai đề xuất cách tiếp cận tốt hơn. Đây là đoạn mã mẫu và dữ liệu:Tạo Ma trận thưa thớt từ khung dữ liệu

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); 
} 

mẫu dữ liệu trong dataframe từ đó ma trận thưa thớt đang được tạo:

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

Vì vậy, cuối cùng tôi muốn một cái gì đó như thế này: Các cột là ID phim và các hàng là ID người dùng

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 

Vì vậy, diễn giải là một cái gì đó như thế này: người dùng 2 xếp hạng phim 1 là 3 sao, người dùng 3 đánh giá phim 2 là 3 sta r, v.v .. cho những người dùng và phim khác. Có khoảng 8500000 hàng trong khung dữ liệu của tôi mà mã của tôi chỉ mất khoảng 30-45 phút để tạo ma trận mục người dùng này, tôi muốn nhận bất kỳ đề xuất nào

Trả lời

12

Gói Matrix có một constructor tạo đặc biệt cho loại dữ liệu của bạn:

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

Nếu không, bạn có thể thích biết về tính năng thú vị đó của hàm [ được gọi là lập chỉ mục ma trận. Bạn có thể thử:

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); 
} 

(nhưng tôi chắc chắn sẽ giới thiệu các phương pháp sparseMatrix trên này.)

+0

Cảm ơn rất nhiều !!!, điều này hoạt động hoàn toàn tốt đẹp. – user37940

+0

Cách tiếp cận sparseMatrix hoạt động nhanh hơn phương pháp thứ hai, cảm ơn bạn. :) – user37940

9

Điều này có thể sẽ nhanh hơn vòng lặp.

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 

Nếu bạn sử dụng data.tables, nó sẽ được rất nhiều nhanh hơn:

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

Và như tôi chắc chắn rằng ai đó sẽ chỉ ra, bạn có thể sử dụng thay vì

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

Điều này chuyển đổi df thành dữ liệu. Có thể đặt tại chỗ (không cần tạo bản sao). nếu dữ liệu của bạn là rất lớn, có thể làm cho một sự khác biệt ...

+0

Thanks a lot !!! – user37940

+1

Tuy nhiên, có một vấn đề nhỏ với phương pháp này, cách tiếp cận này không vạch ra chính xác USERID và MOVIEID cho ví dụ. 11 người dùng bị thiếu dữ liệu huấn luyện vì vậy bây giờ trong hàng 11 Tôi có ID người dùng và ID phim cho người dùng 12 và sau đó tất cả các hàng được chuyển bởi 1, tôi có 10916 người dùng trong tập huấn và tôi muốn giữ tất cả chúng trong ma trận Mục người dùng của tôi, trong trường hợp người dùng bị thiếu dữ liệu đào tạo của tôi, tôi có thể đánh dấu toàn bộ hàng vectơ là 0, điều này sẽ ngăn chặn bất kỳ sự không phù hợp nào trong khung dữ liệu huấn luyện và ma trận của tôi. phương pháp tiếp cận, nhờ – user37940

Các vấn đề liên quan