추천 결과 평가
정확성을 측정하는 또 다른 방법은 추천 결과들을 긍정적인 평점을 가진 구매와 비교하는 것이다. 이를 지원하는 recommenderlab 패키지의 함수는 evaluate며, 다음과 같은 매개변수를 지정할 수 있다.
- x : 평가 체계를 포함하는 객체다.
- method : 추천 기법이다.
- n : 사용자별로 추천할 아이템 수다. 벡터로 지정할 수 있으며, 이 경우 함수는 n별로 추천 성능을 평가한다.
이미 rating_threshold <- 3 으로 임계 값을 정했고, 이 매개변수는 eval_sets 내부에 저장돼 있다. progress = FALSE 매개변수로 진행 내용을 나타내지 않는다.
results <- evaluate(x = eval_sets, method = model_to_evaluate, n = seq(10, 100, 10))
class(results)
[1] "evaluationResults"
attr(,"package")
[1] "recommenderlab"
결과 객체는 평가 결과가 포함된 evaluationResults 객체다. getConfusionMatrix 함수를 사용해 혼동 매트릭스를 추출할 수 있다. 목록의 각 요소는 k-fold로 분할된 덩어리들과 일치한다. 먼저 첫 번째 요소를 살펴본다.
head(getConfusionMatrix(results)[[1]])
TP FP FN TN precision recall TPR FPR
10 2.735714 7.264286 66.90714 240.0929 0.2735714 0.04048274 0.04048274 0.02900863
20 5.157143 14.842857 64.48571 232.5143 0.2578571 0.07489076 0.07489076 0.05952170
30 7.507143 22.492857 62.13571 224.8643 0.2502381 0.10857708 0.10857708 0.09042978
40 9.857143 30.142857 59.78571 217.2143 0.2464286 0.14588682 0.14588682 0.12152718
50 11.950000 38.050000 57.69286 209.3071 0.2390000 0.17504078 0.17504078 0.15349698
60 13.900000 46.071429 55.74286 201.2857 0.2317772 0.20381563 0.20381563 0.18611840
처음 네 개의 열은 참과 거짓에 대한 긍정과 부정을 포함하며 다음과 같다.
- TP(True Positive) : 구매됐으며 추천된 아이템
- FP(False Positive) : 구매되지 않았으며 추천되지 않은 아이템
- FN(False Negative) : 구매됐으나 추천된 아이템이 아님
- TN(True Negative) : 구매되지 않았으나 추천된 아이템이 아님
완벽한(오버피팅된)모델은 TP와 TN만을 가지게 된다.
만일 동시에 모든 분할을 고려하려면 다음처럼 요약한다.
columns_to_sum <- c("TP", "FP", "FN", "TN")
indices_summed <- Reduce("+", getConfusionMatrix(results))[, columns_to_sum]
head(indices_summed)
TP FP FN TN
10 11.07857 28.92143 281.5429 946.4571
20 21.12143 58.87857 271.5000 916.5000
30 30.76429 89.23571 261.8571 886.1429
40 39.84286 120.15714 252.7786 855.2214
50 48.72143 151.27857 243.9000 824.1000
60 57.42143 182.55000 235.2000 792.8286
대신에 avg(resulgts)를 사용할 수도 있는 점에 유의하자.
나머지 네 개의 열은 성능 지표를 포함하고 있으며 모든 fold에 대한 요약은 어렵다. 하짐나 이를 시각화할 수 있다.
먼저 다음의 요인을 나타내는 ROC 곡선을 만들어본다.
- TPR(True Positive Rate) : 구매된 아이템 중 추천 아이템의 비율이다. TP를 구매한 아이템 수 (TP + FN)로 나눈 값이다.
- FPR(False Positive Rate) : 구매되지 않은 아이템 중 추천 아이템의 비율이다. FP를 구매하지 않은 아이템 수(FP + TN)로 나눈 값이다.
plot함수는 ROC 곡선을 사용한 도표를 만든다. 레이블을 표시하기 위해 annotate = TRUE를 매개변수로 추가한다.
plot(results, annotate = TRUE, main = "ROC curve")
다음 도표는 ROC 곡선을 보여준다.
정확도 평가 지표는 다음의 두 가지다.
- 정확도(Precision) : 추천된 아이템 중 구매 비율이다. FP를 긍정의 수(TP + FP)로 나눈 값이다.
- 재현력(Recall) : 구매된 아이템 중 추천 아이템의 비율이다. TP의 수를 구매한 아이템 수(TP + FN)로 나눈 값으로 TPR(True Positive Rate)과 같다.
추천된 아이템의 구매 비율이 낮으면 일반적으로 정확도가 감소한다. 반면에 추천된 아이템의 구매 비율이 높을수록 재현력이 증가한다.
plot(results, "prec/rec", annotate = TRUE, main = "Precision-recall")
다음 도표는 정확도별 재현력을 보여준다.
이 도표는 정확도와 재현력 간의 반비례 관계를 보여준다. 그래프는 완벽하게 단조적이지는 않지만 추세는 예상대로다.
이제까지 모델을 평가하는 방법을 살펴봤다. 이어서 두 개 이상의 모델을 비교하는 방법을 살펴본다.
가장 적합한 모델 식별
지금까지 모델을 평가하는 방법을 알아봤다. 성능 지표는 다양한 모델 또는 매개변수를 비교하는 데 유용하다. 같은 데이터에 여러 기법을 적용하고 성능 지표를 비교하면 가장 적합한 추천 방식을 선택할 수 있따. 다양한 평가 지표가 존재하므로 객관적인 방법은 없다.
이전에 알아본 k-fold 평가 구조로 시작해본다. 이는 eval_sets에 저장돼 있다
모델 비교
서로 다른 모델을 비교하기 위해 먼저 모델을 정의해야 한다. 각 모델은 이름과 매겨변수를 가진 목록에 저장된다. 목록의 구성 요소는 다음과 같다.
- name : 모델의 이름이다.
- param : 매개변수의 목록이다. 모든 매개변수가 기본값으로 사용되면 NULL이 될 수 있다.
예를 들어 매개변수 k를 20으로 설정한 아이템 기반 협업 필터링을 정의할 수 있다.
list(name = "IBCF", param = list(k = 20))
다른 모델을 평가하기 위해 목록을 정의할 수 있다. 다음과 같이 필터링을 구성할 수 있다.
- 코사인을 거리 함수로 사용하는 아이템 기반 협업 필터링
- 피어슨 상관 계수를 거리 함수로 사용하는 아이템 기반 협업 필터링
- 거리 함수로 코사인을 사용하는 사용자 기반 협업 필터링
- 피어슨 상관 계수를 거리함수로 사용하는 사용자 기반 협업 필터링
- 베이스라인을 가지는 무작위 추천
위의 내용은 다음 코드처럼 정의된다.
models_to_evaluate <- list(IBCF_cos = list(name = "IBCF", param = list(method = "cosine")),
IBCF_cor = list(name = "IBCF", param = list(method = "pearson")),
UBCF_cos = list(name = "UBCF", param = list(method = "cosine")),
UBCF_cor = list(name = "UBCF", param = list(method = "pearson")),
random = list(name = "RANDOM", param = NULL))
모델을 올바르게 평가하기 위해서는 아이템 수를 변경해가며 테스트할 필요가 있다. 예를 들어 사용자별로 최대 100편의 영화를 추천할 수 있다. 추천 결과로 이미 큰 수이므로 더 큰 값을 포함시킬 필요는 없다.
n_recommendation <- c(1, 5, seq(10, 100, 10))
모델을 실행하고 평가할 준비가 됐다. 이전까지와 마찬가지로 evaluate 함수가 사용된다. 유일한 차이점은 method가 모델의 목록이라는 것이다.
list_results <- evaluate(x = eval_sets, method = models_to_evaluate, n = n_recommendations)
class(list_results)
[1] "evaluationResultList"
attr(,"package")
[1] "recommenderlab"
list_results 객체는 evaluationResultlist 객체 유형이며 리스트로 처리될 수 있다. 첫 번째 요소를 살펴본다.
class(list_results[[1]])
[1] "evaluationResults"
attr(,"package")
[1] "recommenderlab"
list_results의 첫 번쨰 요소는 evaluationResults 객체며 이 객체는 하나의 모델만 사용한 evaluate 실행 결과와 같다. 우리는 모든 요소에 대해 같은지를 확인할 수 있다.
sapply(list_results, class) == "evaluationResults"
IBCF_cos IBCF_cor UBCF_cos UBCF_cor random
TRUE TRUE TRUE TRUE TRUE
list_results의 각 요소는 evaluationResults 객체 유형이다. avg를 사용해 평균 혼동 매트릭스를 추출할 수 있다.
avg_matrices <- lapply(list_results, avg)
이제 avg_matrices를 사용한 성능 평가를 할 수 있다. 예를 들어 코사인 거리 기반의 IBCF를 살펴본다.
head(avg_matrices$IBCF_cos[, 5:8])
precision recall TPR FPR
1 0.3446429 0.004978807 0.004978807 0.002642675
5 0.2882143 0.020177261 0.020177261 0.014419975
10 0.2769643 0.038316771 0.038316771 0.029362285
20 0.2640179 0.072745653 0.072745653 0.059986253
30 0.2563690 0.106272444 0.106272444 0.091119121
40 0.2490179 0.138071941 0.138071941 0.122980469
이전에 알아본 모든 평가 지표가 있다. 다음으로 이러한 평가 지표를 살펴보고 최적의 성능 모델을 파악해본다.
'R > R로 만드는 추천 시스템' 카테고리의 다른 글
사례 연구 : 나만의 추천 시스템 만들기 - 01 (0) | 2020.03.30 |
---|---|
추천 시스템의 평가 - 04 (0) | 2020.03.29 |
추천 시스템의 평가 - 02 (0) | 2020.03.24 |
추천 시스템의 평가 - 01 (0) | 2020.03.24 |
추천 시스템 - 05 (0) | 2020.03.20 |