추천 시스템 성능 평가에 자주 쓰이는 Precision@K와 Recall@K의 정의, 계산 예시, 파이썬 구현을 다루는 글이다. 추천 모델도 비지도학습에 속해 성능 평가가 중요한데 지표가 여러 개라 각각의 의미를 구분해두는 것이 먼저다. 두 지표를 함수로 만들고 전체 사용자에 대해 평균을 내는 평가 루프까지 이어진다.
핵심 포인트- Precision@K는 추천한 K개 중 사용자가 실제로 관심 있는 아이템의 비율이다.
- Recall@K는 사용자가 관심 있는 전체 아이템 중 추천 K개에 포함된 비율이다.
- Average of Precision@k와 AP@K는 다르다. 전자는 각 추천의 Precision@k 평균이고 후자는 서로 다른 k에 대한 Precision 평균이다.
- 두 지표의 공통 분자는 hit 수이며 Top-K 예측과 실제 관심 아이템의 교집합 크기다.
- 평가할 때 학습 데이터에 이미 피드백이 있는 아이템은 예측값에서 걸러내야 한다.
상세 정리- 평가의 위치: 머신러닝은 모델 구축만큼 성능 평가가 중요하고 추천 시스템도 예외가 아니다. Precision/Recall@K 외에 MAP, NDCG@K 등이 쓰인다.
- Precision 정의: 예측값 중 옳게 예측한 비율이며, 추천에서는 모델이 추천한 아이템 중 사용자가 관심 있는 것의 비율로 해석된다.
- Recall 정의: 실제 옳은 것 중 옳다고 예측한 비율이며, 추천에서는 사용자가 실제 관심 있는 아이템 중 모델이 추천한 것의 비율이다.
- 계산 예시: k=5이고 사용자의 관심 아이템이 6개, 그중 추천 안에 3개가 들어 있으면 Precision@5는 0.6, Recall@5는 0.5다.
- 두 지표의 분모가 다르다는 점이 핵심이다. Precision은 추천 개수로, Recall은 사용자의 전체 관심 아이템 수로 나눈다.
- 지표 함수 구현: _compute_precision_recall은 targets, predictions, k를 받아 predictions를 k만큼 슬라이싱한 뒤 targets와의 교집합 크기를 num_hit으로 구한다.
- hit의 의미: k개 추천 아이템 중 사용자가 실제로 관심 있는 상품이 존재하는 경우이며 혼동행렬의 TP에 해당한다.
- 평가 함수 구현: evaluate_ranking은 학습 모델과 train/test 피벗 테이블, k를 받아 사용자별로 반복하며 지표를 모은다.
- 다중 k 지원: k를 리스트로도 받게 해 서로 다른 K 값을 한 번에 비교할 수 있도록 했다.
- 예측 필터링: model.predict로 얻은 예측을 argsort한 뒤 train에 피드백이 있는 아이템 인덱스 집합에 속한 것을 제거한다. 이미 반응한 상품을 다시 추천했다고 점수를 주면 안 되기 때문이다.
- 정답 집합: test 피벗 테이블에서 해당 사용자의 피드백이 있는 열 인덱스가 targets가 된다.
- 예외 처리: 테스트 데이터에 피드백이 없는 사용자는 row.indices가 비어 있어 건너뛴다.
- 최종 집계: 사용자별 precision과 recall을 k별 리스트에 모은 뒤 numpy로 평균을 내 Average of Precision@k와 Recall@k를 반환한다.
- 자료 형식: train과 test는 csr 형식의 피벗 테이블이며 행이 사용자, 열이 아이템이다.
왜 읽나추천 모델을 만들어놓고 평가 코드를 처음 짤 때 두 지표의 분모 차이와 학습 데이터 제외 처리를 그대로 옮겨쓸 수 있다.