2014-10-05 2 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 

그래서 결국 나는 이런 식으로 뭔가를 원하는 : 스파 스 매트릭스 작성되는에서 dataframe의 데이터

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) 평가 다른 사용자와 영화의 경우에는 r을 사용합니다. 내 데이터 프레임에는이 코드를 사용하여이 사용자 항목 행렬을 만드는 데 약 30-45 분이 걸리는 행이 약 8500000 개 있습니다. 제안 사항을 얻고 싶습니다.

답변

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

+0

sparseMatrix 접근 방식이 두 번째 접근 방식보다 빠르게 작동합니다. 감사합니다. :) – user37940

9

이것은 루프보다 빠를 것입니다.

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] 
를 사용할 수 있습니다

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를 사용하는 경우가 많은 빠른 될 것입니다

df을 복사하지 않고 data.table로 변환합니다. 데이터 세트가 거대한 경우, 그 차이를 만들 수 있습니다 ...

+0

감사합니다 많이! – user37940

+1

그러나이 접근법에는 약간의 문제가 있습니다.이 접근법은 예를 들어 USERID와 MOVIEID를 올바르게 매핑하지 않습니다. USER 11이 교육 데이터에서 누락되어 이제 11 번에 사용자 12와 사용자 ID 12에 대한 사용자 ID와 영화 ID 등급이 표시되고 이후 모든 행이 1 씩 이동합니다. 내 기차 세트에 10916 명의 사용자가 있으며 계속 유지하려고합니다. 그들 모두 내 사용자 항목 매트릭스에, 만약 사용자가 나의 훈련 데이터에서 빠져있는 경우에 나는 전체 행 벡터를 0으로 표시 할 수 있기 때문에 훈련 데이터 데이터 프레임과 행렬의 불일치를 막을 수 있습니다. 접근, 감사 – user37940

관련 문제