본문 바로가기

R/R로 만드는 추천 시스템

추천 시스템 - 01

반응형

이 장에서는 일반적으로 알려진 추천 기법들을 알아보며, 일부는 R을 사용해 구현해본다.

다음 추천 기법들을 알아본다.

  • 협업 필터링(Collaborative filtering) : 우리가 자세히 알아볼 추천 기법 중 하나다. 유사한 사용자 또는 아이템에 대한 정보를 기반으로 한 알고리즘이며 두 가지 종류로 나눈다.
  1. 아이템 기반 협업 필터링(Item-based collaborative filtering) : 사용자가 이전에 구매한것들과 가장 유사한 아이템을 추천한다.
  2. 사용자 기반 협업 필터링(User-based collaborative filtering) : 유사한 사용자가 가장 선호하는 아이템을 사용자에게 추천한다.
  • 콘텐츠 기반 필터링(Content-based filtering) : 개별 사용자를 위한 추천 기법이다. 사용자의 프로필을 정의하고 그것과 일치하는 아이템을 선별한다.
  • 하이브리드 필터링(Hybrid filtering) : 서로 다른 기법들을 결합한다.
  • 지식 기반 필터링(Knowledge-based filtering) : 사용자 및 아이템에 대한 명시적인 지식을 이용한다.

추천 시스템을 위한 R 패키지 : recommenderlab

이 장에서는 협업 필터링을 위한 R 패키지 recommenderlab을 사용해 추천 시스템을 구현한다. 이 절에서는 해당 패키지에 대한 개요를 설명한다. 우선 설치하지 않았다면 패키지를 설치한다.

if(!"recommenderlab" %in% rownames(install.packages())){
  install.packages("recommenderlab")
}

이제  패키지를 로드할 수 있고 도움말 기능을 사용해 설명서를 살펴볼 수 있다.

library(recommenderlab)
help(package = "recommenderlab")

위의 명령을 RStudio에서 실행하면 몇 가지 링크가 포함된 도움말 파일과 함수 목록이 열린다.

이 장에서 다루는 예제에는 임의의 난수를 생성하는 요소가 포함돼 있으므로 같은 결과를 내는 코드를 재현하기 위해 다음을 실행한다.

set.seed(1)

이제 recommenderlab을 사용할 준비가 됐다.

 

데이터 세트

recommenderlab은 다른 R 패키지들처럼 내장된 함수들을 사용해볼 수 있는 몇 가지 데이터 세트를 포함한다.

data_package <- data(package = "recommenderlab")
data_package$results[,"Item"]

Jester5k, MSWeb, MovieLense

예제는 영화와 관련된 MovieLense 데이터 세트를 사용한다. 이 데이터 세트에는 영화에 대한 사용자들의 평점이 들어있다. 데이터를 로드하고 살펴본다.

data("MovieLense")
MovieLense
943 x 1664 rating matrix of class ‘realRatingMatrix’ with 99392 ratings.

MovieLense의 각 행은 사용자를 나타내고 각 열은 영화를 나타낸다. 사용자와 영화 사이에 943x1664 = 1,500,000 이상의 데이터 조합이 있으므로 전체 행과 열을 저장하려면 1,500,000개 이상의 셀이 필요하다. 단, 모든 사용자가 전체 영화를 보지 않았으므로 100,000개 미만의 평점이 있으며 나머지는 비어있는 희소 매트릭스(sparse matrix)다. recommenderlab 패키지는 이와 같은 데이터를 간결한 방식으로 저장할 수 있다.

 

평점 매트릭스를 위한 클래스

MovieLense에 대해 자세히 살펴본다.

class(MovieLense)
[1] "realRatingMatrix"
attr(,"package")
[1] "recommenderlab"

realRatingMatrix 클래스는 recommenderlab에 정의돼 있고, objectsojectb는 희소 평점 매트릭스를 포함한다. 이 클래스의 객체에 적용 가능한 방법을 살펴본다.

methods(class = class(MovieLense))
 [1] [                      [<-                   
 [3] binarize               calcPredictionAccuracy
 [5] coerce                 colCounts             
 [7] colMeans               colSds                
 [9] colSums                denormalize           
[11] dim                    dimnames              
[13] dimnames<-             dissimilarity         
[15] evaluationScheme       getData.frame         
[17] getList                getNormalize          
[19] getRatingMatrix        getRatings            
[21] getTopNLists           image                 
[23] normalize              nratings              
[25] Recommender            removeKnownRatings    
[27] rowCounts              rowMeans              
[29] rowSds                 rowSums               
[31] sample                 show                  
[33] similarity            
see '?methods' for accessing help and source code

몇 가지 방법들은 매트릭스를 더욱 최적화된 방법으로 다룰 수 있도록 돼 있다.

 

예를 들면, dim을 사용해 행과 열의 수를 추출하고 colSum을 사용해 각 열의 합을 계산할 수 있다. 또한 추천 시스템에 특화된 새로운 방법도 있다.

 

일반적으로 평점 매트릭스는 희소 매트릭스다. 따라서 realRatingMatrix 클래스는 희소 매트릭스에 대해 간결한 저장을 지원한다. 이제 MovieLense 크기와 해당 R 매트릭스를 비교해본다.

object.size(MovieLense)
1409432 bytes

object.size(as(MovieLense, "matrix"))
12761360 bytes

여기서 recommenderlab 매트릭스가 얼마나 더 간결한지 계산해본다.

object.size(as(MovieLense, "matrix")) / object.size(MovieLense)
9.1 bytes

예상대로 movieLense는 동등한 표준 R 매트릭스보다 공간을 훨씬 작게 차지한다. 비율은 약 1:9며, 그 이유는 MovieLense의 희소성 때문이다. 표준 R 매트릭스 객체는 누락된 값을 모두 0으로 저장하므로 15배 더 많은 셀을 저장한다.

 

유사도 매트릭스 계산

협업 필터링 알고리즘은 사용자 간 또는 아이템 간 유사도 측정을 기반으로 한다. 이를 위해 recommenderlab은 유사도 계산 함수를 포함하고 있으며, 지원되는 방법은 cosine, pearson, jaccard다.

 

예를 들어, 처음 다섯 명의 사용자가 서로 얼마나 유사한지, 코사인 거리를 사용해 계산해본다.

similarity_users <- similarity(MovieLense[1:4,], method = "cosine",
                               which = "users")

similarity_users  객체는 다른 정보도 포함하고 있다. 이를 바로 확인해본다.

class(similarity_users)
[1] "dist"

예상대로, similarity_users는 거리를 포함하는 객체다. dist는 기본 R 클래스이므로 다른 형태로도 사용될 수 있다. 예를 들어 계층적 클러스터링 모델을 구축하기 위해 hclust를 사용할 수 있다.

또한 similarity_users를 매트릭스로 변환해 시각화할 수도 있다.

as.matrix(similarity_users)
          1         2         3         4
1 0.0000000 0.9605820 0.8339504 0.9192637
2 0.9605820 0.0000000 0.9268716 0.9370341
3 0.8339504 0.9268716 0.0000000 0.9130323
4 0.9192637 0.9370341 0.9130323 0.0000000

이미지를 사용한 매트릭스 시각화도 가능하다. 각 행과 열은 사용자에 해당하며 각 셀은 두 사용자 간의 유사도에 해당한다.

image(as.matrix(similarity_users), main = "User similarity")

같은 방식으로 처음 네 개 아이템 간의 유사도를 계산하고 시각화할 수 있다.

similarity_items <- similarity(MovieLense[, 1:4],
                               method = "cosine", which = "items")

as.matrix(similarity_items)
                  Toy Story (1995) GoldenEye (1995)
Toy Story (1995)         0.0000000        0.9487374
GoldenEye (1995)         0.9487374        0.0000000
Four Rooms (1995)        0.9132997        0.9088797
Get Shorty (1995)        0.9429069        0.9394926
                  Four Rooms (1995) Get Shorty (1995)
Toy Story (1995)          0.9132997         0.9429069
GoldenEye (1995)          0.9088797         0.9394926
Four Rooms (1995)         0.0000000         0.8991940
Get Shorty (1995)         0.8991940         0.0000000

 

앞의 사용자 간 유사도 시각화와 같이 이미지를 사용해 매트릭스를 시각화할 수 있다.

image(as.matrix(similarity_items), main = "Item similarity")

유사도는 협업 필터링 모델의 기본이 된다.

 

추천 모델

recommenderlab 패키지에는 추천 알고리즘에 대한 몇 가지 옵션이 있다. recommender Registry$get_entries 명령어를 통해 realRatingMatrix 객체에 적용 가능한 모델을 표시해본다.

recommender_models <- recommenderRegistry$get_entries(dataType = "realRatingMatrix")

recommender_models 객체에는 모델에 대한 정보가 포함돼 있다. 먼저 이를 확인해본다.

names(recommender_models)
 [1] "ALS_realRatingMatrix"         
 [2] "ALS_implicit_realRatingMatrix"
 [3] "IBCF_realRatingMatrix"        
 [4] "LIBMF_realRatingMatrix"       
 [5] "POPULAR_realRatingMatrix"     
 [6] "RANDOM_realRatingMatrix"      
 [7] "RERECOMMEND_realRatingMatrix" 
 [8] "SVD_realRatingMatrix"         
 [9] "SVDF_realRatingMatrix"        
[10] "UBCF_realRatingMatrix" 

각 모델에 대한 설명을 살펴본다.

lapply(recommender_models, "[[", "description")
$ALS_realRatingMatrix
[1] "Recommender for explicit ratings based on latent factors, calculated by alternating least squares algorithm."

$ALS_implicit_realRatingMatrix
[1] "Recommender for implicit data based on latent factors, calculated by alternating least squares algorithm."

$IBCF_realRatingMatrix
[1] "Recommender based on item-based collaborative filtering."

$LIBMF_realRatingMatrix
[1] "Matrix factorization with LIBMF via package recosystem (https://cran.r-project.org/web/packages/recosystem/vignettes/introduction.html)."

$POPULAR_realRatingMatrix
[1] "Recommender based on item popularity."

$RANDOM_realRatingMatrix
[1] "Produce random recommendations (real ratings)."

$RERECOMMEND_realRatingMatrix
[1] "Re-recommends highly rated items (real ratings)."

$SVD_realRatingMatrix
[1] "Recommender based on SVD approximation with column-mean imputation."

$SVDF_realRatingMatrix
[1] "Recommender based on Funk SVD with gradient descend (https://sifter.org/~simon/journal/20061211.html)."

$UBCF_realRatingMatrix
[1] "Recommender based on user-based collaborative filtering."

 

이 모델 중에서 우리는 IBCF와 UBCF를 사용한다.

recommender_models 객체에는 매개변수(Parameter)와 같은 다른 정보도 들어있다.

 

recommender_models$IBCF_realRatingMatrix$parameters
$k
[1] 30

$method
[1] "Cosine"

$normalize
[1] "center"

$normalize_sim_matrix
[1] FALSE

$alpha
[1] 0.5

$na_as_zero
[1] FALSE

 

패키지 및 사용 사례에 대한 자세한 설명을 보려면 패키지 부가 기능을 이용해본다.

즉, help(package = "recommenderlab")을 입력하면 모든 자료를 찾을 수 있다.

 

 recommenderlab은 추천을 위한 훌륭하고 유연한 패키지다. 이를 다른 R 도구와 결합해 사용한다면 데이터를 탐색하고 추천 모델을 개발하는 강력한 도구가 될 수 있다.

 

다음 절에서 몇 가지 도구를 사용해 recommenderlab의 데이터 세트를 살펴본다.

반응형