아이템 기반 협업 필터링
협업 필터링은 여러 사용자에 대한 정보를 고려한 추천 형태다. '협업'이라는 단어는 사용자가 아이템을 추천하기 위해 서로 협력한다는 사실을 나타낸다. 실제 알고리즘에서는 사용자의 구매 내역 및 선호도가 고려된다. 그 시작은 행이 사용자에 해당하고 아이템이 열에 해당하는 평점 매트릭스다.
이 절에서는 아이템 기반 협업 필터링의 예를 보여준다. 새로운 사용자가 주어지면 알고리즘은 사용자의 구매 내역을 고려해 유사한 아이템을 추천한다. 핵심 알고리즘 구현은 다음 단계를 기반으로 한다.
- 각 아이템들에 대해, 유사한 사용자들에게 비슷한 평점을 받은 것을 바탕으로 서로 얼마나 유사한지 측정한다.
- 각 아이템에 대해, 가장 유사한 k개의 아이템들을 선별한다.
- 각 사용자에 대해, 사용자의 구매 내역과 가장 유사한 아이템을 선별한다.
이번 장에서는 IBCF 모델 작성에 대한 전반적인 접근 방식을 다룬다. 또한 자세한 내용은 언급될 세부 절에서 살펴본다.
트레이닝 및 테스트 세트 정의
우리는 MovieLense 데이터 세트(트레이닝 세트)의 일부를 사용해 모델을 만들고 나머지 부분(테스트 세트)은 구현한 모델에 적용한다. 이 장에서 다루려는 내용 범위를 벗어나므로 여기서 모델을 평가하지는 않지만, 테스트 세트 사용자에 한해 영화를 추천할 것이다.
두 개의 데이터 세트는 다음과 같다.
- 트레이닝 세트: 이 세트는 모델을 학습하기 위한 사용자가 들어있다.
- 테스트 세트: 이 세트는 영화를 추천하기 위한 사용자가 들어있다.
알고리즘은 데이터를 자동으로 정규화하며, MovieLense 관련 사용자와 영화가 포함된 ratings_movies를 사용할 수 있다. 이전 절에서 rating_movies는 100회 이상 평가된 영화와 영화를 50개 이상 평가한 MovieLense 사용자의 일부로 정의했다.
먼저 트레이닝 세트에 포함된 사용자는 TRUE고 그 외 사용자는 FALSE로 작성된 which_train 벡터를 무작위로 정의한다. 트레이닝 세트의 비율은 80%로 설정한다.
which_train <- sample(x = c(TRUE, FALSE), size = nrow(ratings_movies),
replace = TRUE, prob = c(0.8, 0.2))
head(which_train)
[1] TRUE TRUE TRUE FALSE TRUE FALSE
트레이닝 및 테스트 세트를 정의한다.
recc_data_train <- ratings_movies[which_train, ]
recc_data_test <- ratings_movies[!which_train, ]
각 사용자에게 아이템을 추천하기 위해 k-fold를 사용한다.
- 사용자를 무작위로 다섯 개의 그룹으로 나눈다.
- 하나의 그룹은 텟흐트 세트로, 나머지 그룹은 트레이닝 세트로 사용한다.
- 그룹별로 반복한다.
다음은 샘플 코드다.
which_set <- sample(x = 1:5, size = nrow(ratings_movies), replace = TRUE)
for(i_model in 1:5){
which_train <- which_set == i_model
recc_data_train <- ratings_movies[which_train, ]
recc_data_test <- ratings_movies[!which_train, ]
#Recommender 구성하기
}
이 패키지의 동작 방식을 알아보기 위해 데이터를 수동으로 트레이닝 및 테스트 세트로 나눈다. recommenderlab의 evaluationScheme 함수를 사용해 이 작업을 자동으로도 수행할 수 있다. 해당 함수는 4장. ' 추천 시스템의 평가'에서 모델을 평가하기 위해 사용될 것이다.
이제 모델을 생성하고 검증할 수 있다.
추천 모델 생성
모델을 생성하는 함수는 Recommender며 입력 값은 다음과 같다.
- 데이터 : 트레이닝 세트
- 방법 : 알고리즘 기법의 이름
- 매개변수 : 알고리즘 기법에 대한 선택적 설정 변수 값
아이템 기반 협업 필터링은 IBCF라고 부른다. 매개변수를 살펴본다.
recommender_models <- recommenderRegistry$get_entries(dataType = "realRatingMatrix")
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
몇 가지 관련 매개변수는 다음과 같다.
- k : 첫 번쨰 단계에서 알고리즘은 각 아이템에서 서로의 유사점을 계산한다. 다음 각 아이템에 대해 k개의 가장 유사한 아이템을 선별하고 저장한다.
- method: 유사도 함수다. 기본 설정은 cosind이며, 자주 쓰이는 다른 옵션은 pearson이다.
여기서는 기본값으로 설정할 수 있따. 매개변수를 변경하는 방법을 보여주기 위해 기본값인 k=30을 설정한다. 이제 추천 모델을 만들어본다.
recc_model <- Recommender(data = recc_data_train, method = "IBCF",
parameter = list(k = 30))
recc_model
Recommender of type ‘IBCF’ for ‘realRatingMatrix’
learned using 116 users.
class(recc_model)
[1] "Recommender"
attr(,"package")
[1] "recommenderlab"
recc_model 클래스는 recommender 클래스의 객체다.
추천 모델 탐색
getModel을 사용해 모델에 대한 설명과 매개변수 같은 몇 가지 세부 정보를 추출할 수 있다.
model_details <- getModel(recc_model)
model_details$description
[1] "IBCF: Reduced similarity matrix"
model_details$sim 구성 요소에는 유사도 매트릭스가 포함된다. 구조를 확인해본다.
class(model_details$sim)
[1] "dgCMatrix"
attr(,"package")
[1] "Matrix"
dim(model_details$sim)
[1] 332 332
예상대로 model_details$sim은 크기가 아이템 수와 같은 정사각형 매트릭스다. image를 사용해 매트릭스 일부를 탐색할 수 있다.
n_items_top <- 20
히트맵을 만들어본다.
image(model_details$sim[1:n_items_top, 1:n_items_top],
main = "Heatmap of the first rows and columns")
다음 그림은 첫 번째 행과 열의 히트맵을 표시한다.
대부분의 값은 0이다. 각 행에는 k 기준에 만족하는 요소만 포함돼 있기 때문이다. 확인해보자.
model_details$k
[1] 30
row_sums <- rowSums(model_details$sim > 0)
table(row_sums)
row_sums
30
332
예상대로 각 행은 0보다 큰 30개의 요소를 가지고 있다. 그러나 매트릭스는 대칭적으로 보이지 않는다. 사실, 각 열의 0이 아닌 요소의 수는 해당 영화가 다른 영화의 상위 k 번째에 얼마나 자주 포함됐느냐에 따라 달라진다. 열의 구성 요소 수 분포를 확인해본다.
col_sums <- colSums(model_details$sim > 0)
분포도를 작성해본다.
qplot(col_sums) + stat_bin(binwidth = 1) + ggtitle("Distribution of the column count")
예상대로 다른 많은 영화와 빗스한 몇 개의 영화가 있다. 어떤 영화가 대부분의 구성 요소에 대해 만족했는지 확인해보자.
which_max <- order(col_sums, decreasing = TRUE)[1:6]
rownames(model_details$sim)[which_max]
[1] "Down Periscope (1996)"
[2] "Peacemaker, The (1997)"
[3] "Edge, The (1997)"
[4] "Mimic (1997)"
[5] "Seven Years in Tibet (1997)"
[6] "Rosewood (1997)"
테스트 세트에 추천 모델 적용
이제 우리는 테스트 세트에 있는 사용자에게 영화를 추천할 수 있다. 각 사용자에게 추천할 아이템 수를 지정하는 n_recommended를 정의한다. 이 절에서는 가중치를 계산할 때 주로 사용되는 접근 방법을 보여줄 것이다.
n_recommender <- 6
각 사용자에 대해, 알고리즘은 평점을 매긴 영화를 추출한다. 그리고 각 영화에 대해, 유사도 매트릭스를 기반으로 모든 유사한 아이템을 식별한다. 그 후 알고리즘은 다음의 방식으로 각 유사 아이템의 순위를 매긴다.
- 해당 아이템과 관련된 구매 평점을 추출한다. 평점은 가중치로 사용된다.
- 해당 아이템과 관련된 구매 아이템의 유사도를 추출한다.
- 각 가중치에 관련 유사도를 곱한다.
- 모든 곱한 결과를 더한다.
다음으로 알고리즘은 상위 n개를 추천한다.
recc_predicted <- predict(object = recc_model, newdata = recc_data_test,
n = n_recommender)
recc_predicted
Recommendations as ‘topNList’ with n = 6 for 444 users.
recc_predicted 객체에는 추천 항목들이 들어있다. 구조를 살펴본다.
class(recc_predicted)
[1] "topNList"
attr(,"package")
[1] "recommenderlab"
slotNames(recc_predicted)
[1] "items" "ratings" "itemLabels" "n"
세부 항목은 다음과 같다.
- items : 각 사용자에 대한 추천 아이템들의 색인에 대한 목록
- itemLabels : 아이템의 이름
- n : 추천 수
예를 들어, 다음은 첫 번째 사용자를 위한 추천 항목들이다.
recc_predicted@items[[1]]
[1] 6 25 55 57 96 109
recc_predicted@item 레이블로부터 추천 영화를 추출할 수 있다.
recc_user_1 <- recc_predicted@items[[1]]
movies_user_1 <- recc_predicted@itemLabels[recc_user_1]
movies_user_1
[1] "Dead Man Walking (1995)"
[2] "Outbreak (1995)"
[3] "Dances with Wolves (1990)"
[4] "Snow White and the Seven Dwarfs (1937)"
[5] "Raiders of the Lost Ark (1981)"
[6] "Godfather: Part II, The (1974)"
각 사용자에 대한 추천 항목이 있는 매틀힉스를 정의할 수 있다.
recc_matrix <- sapply(recc_predicted@items, function(x){colnames(ratings_movies)[x]})
dim(recc_matrix)
[1] 6 444
처음 네 명의 사용자에 대한 추천 항목을 시각화해본다.
recc_matrix[, 1:4]
2 3 5
[1,] "Dead Man Walking (1995)" "Rock, The (1996)" "Being There (1979)"
[2,] "Outbreak (1995)" "Courage Under Fire (1996)" "Tombstone (1993)"
[3,] "Dances with Wolves (1990)" "Speed (1994)" "Conan the Barbarian (1981)"
[4,] "Snow White and the Seven Dwarfs (1937)" "Tomorrow Never Dies (1997)" "Pulp Fiction (1994)"
[5,] "Raiders of the Lost Ark (1981)" "Sleepless in Seattle (1993)" "Quiz Show (1994)"
[6,] "Godfather: Part II, The (1974)" "Clear and Present Danger (1994)" "Clear and Present Danger (1994)"
7
[1,] "Men in Black (1997)"
[2,] "Jackie Brown (1997)"
[3,] "Bound (1996)"
[4,] "Benny & Joon (1993)"
[5,] "Philadelphia (1993)"
[6,] "101 Dalmatians (1996)"
이제 가장 많이 추천된 영화를 확인할 수 있다. 이를 위해 모든 추천사항이 있는 벡터를 정의하고 빈도수 그래프를 작성한다.
number_of_items <- factor(table(recc_matrix))
chart_title <- "Distribution of the number of items for IBCF"
분포도를 작성해본다.
qplot(number_of_items) + ggtitle(chart_title)
다음 그림은 IBCF에 대한 아이템 수 분포를 보여준다.
IBCF와 비교할 때 분포도의 꼬리가 길다. 즉, 다른 영화들보다 훨씬 더 자주 추천되는 영화가 있음을 의미한다.
number_of_items_sorted <- sort(number_of_items, decreasing = TRUE)
number_of_items_top <- head(number_of_items_sorted, n = 4)
table_top <- data.frame(names(number_of_items_top), number_of_items_top)
table_top
names.number_of_items_top. number_of_items_top
Crash (1996) Crash (1996) 30
Lost Highway (1997) Lost Highway (1997) 30
Ace Ventura: Pet Detective (1994) Ace Ventura: Pet Detective (1994) 29
G.I. Jane (1997) G.I. Jane (1997) 28
IBCF는 유사도 매트릭스를 기준으로 아이템을 추천한다. 한 번 생성이 완료되면 초기 데이터를 사용할 필요가 없는 사전학습(eager-learning)모델이다. 각 아이템에 대해 가장 유사한 k개만 저장하므로 일단 모델을 생성하면 정보량이 적다. 이는 많은 양의 데이터가 있는 경우 장점이다.
또한 이 알고리즘은 효율적이고 확장성이 뛰어나므로 큰 평점 매트릭스에서 잘 작동하며, 다른 추천 모델보다 정확도가 좀 더 높다.
다음 절에서는 또 다른 기법 분야인 사용자 기반 협업 필터링을 살펴본다.
'R > R로 만드는 추천 시스템' 카테고리의 다른 글
추천 시스템의 평가 - 01 (0) | 2020.03.24 |
---|---|
추천 시스템 - 05 (0) | 2020.03.20 |
추천 시스템 - 03 (0) | 2020.03.19 |
추천 시스템 - 02 (0) | 2020.03.17 |
추천 시스템 - 01 (0) | 2020.03.17 |