Ch.8 데이터를 무기로 삼기 위한 분석 기술
추천 시스템 item to item : 열람 / 구매한 아이템을 기반으로 다른 아이템을 추천 user to item : 과거의 행동 또는 데모그래픽 정보를 기반으로 흥미와 기호를 유추하고 아이템 추천
모듈의 종류 일반적으로 EC사이트에는 각 목적에 맞는 모듈이 있다
모듈
설명
예
리마인드
사용자의 과거 행동을 기반으로 아이템을 다시 제안해주는 것
-최근 보았던 상품
-한 번 더 구매하는 것
순위
열람 수, 구매 수 등을 기반으로 인기 있는 아이템을 제안해주는 것
-인기 순위
-급상승 순
콘텐츠베이
아이템의 추가 정보를 기반으로 다른 아이템을 추천해주는 것
해당 배우가 출연한 다른 작품
추천
서비스를 사용하는 사용자 전체의 행동 이력을 기반으로, 다음에 볼만한 아이템 또는 관련 아이템을 추측해 제안해주는 것
이 상품을 보았던 사람들은 이러한 상품들도 함께 았습니다
개별 추천
사용자 개인의 행동 이력을 기반으로 흥미 기호를 추측하고, 흥미 있어 할 만한 아이템을 제안해주는 것
당신만을 위한 추천
Item to Item : 아이템 사이의 유사도를 계산하고 순서를 생성하는 쿼리
WITH ratings AS (
SELECT user_id, product,
--상품 열람 수
SUM(CASE WHEN action='view' THEN 1 ELSE 0 END) AS view_count,
--상품 구매 수
SUM(CASE WHEN action='purchase' THEN 1 ELSE 0 END) AS purchase_count,
--열람 수와 구매 수에 3:7의 비율의 가중치 주어 평균 구하기
, (0.3 * SUM (CASE WHEN action = 'view' THEN 1 ELSE 0 END) + 0.7 * (SUM (CASE WHEN action ='purchase' THEN 1 ELSE 0) END ) AS score )
FROM action_log
GROUP BY user_id, product
)
SELECT r1.product AS target , r2.product as related,
-- 모든 아이템을 열람/구매한 사용자 수
COUNT (r1.user_id) AS users,
-- 스코어들을 곱하고 합계를 구해 유사도 계산하기
SUM (r1.score * r2.score ) AS score,
--상품의 유사도 순위 구하기
ROW NUMBER () OVER (PARTITION BY r1.product ORDER BY
SUM (r1.score * r2.score ) DESC) AS rank
-- 공통 사용자가 존재하는 상품의 페어 만들기
FROM ratings AS r1 JOIN ratings AS r2
ON r1.user_id = r2.user_id
-- 같은 아이템의 경우에는 페어 제외하기
WHERE r1.product <> r2.product
GROUP BY r1.product, r2.product
ORDER BY target, rank ;
2개의 같지 않은 아이템에 대한 사용자의 점수를 곱해 유사도를 집계한다. -'벡터의 내적'-
벡터 내적만 사용한 유사도는 정밀도에서 문제가 발생한다
접근수가 많은 아이템의 유사도가 상대적으로 높게 나온다 ex) A유저가 특정 아이템에 수 백, 수 천번 접근했다고 가정할 때, 이 접근 로그를 그대로 내적해서 사용하면 해당 아이템의 점수가 항상 높게 나온다
점수의 값이 어느 정도의 유사도를 나타내는지 점수만으로 알기 어렵다. EX) 아이템 A, B의 내적으로 유사도가 3.7이 나왔을 때, 해당 점수가 높은 것인지/낮은 것인지 판단할 수 없다
해당 문제를 '벡터 정규화'로 해결 : 벡터를 모두 같은 길이로 만든다 벡터의 길이는 두 점의 거리를 계산할 때 사용하는 유클리드 거리(Euclidean distance) 정의와 같다. 벡터의 크기(Norm)로 벡터의 각 수치를 나누면 벡터의 노름(크기)를 1로 만들 수 있다. 이렇게 정규화 하는 것을 1,2 정규화 또는 2노름 정규화
아이템 벡터를 정규화하는 쿼리
WITH ratings AS(
-- ratings 테이블 만들기
),
product_base_normalized_ratings AS (
-- 아이템 벡터 정규화하기
SELECT user_id, product, score,
SQRT (SUM (score * score) OVER (PARTITION BY product) AS norm),
score/ SQRT(SUM (score * score) OVER (PARTITION BY product ) AS norm_score)
FROM ratings
)
SELECT * FROM product_normalized_ratings;
-- 정규화했을 때 벡터의 크기는 반드시 1. 내적의 최댓값 1
정규화된 점수로 아이템의 유사도를 계산하는 쿼리
WITH ratings AS (
-- ratings 테이블 가져오기
), product_base_normalized_rating AS(
--product_base_normalized_rating 테이블 가져오기
)
SELECT r1.product AS target , r2.product AS related,
--모든 아이템을 열람/구매한 사용자 수
COUNT (r1.user_id) AS users ,
--스코어들을 곱하고 합계를 구해 유사도 계산하기
SUM (r1.score * r2.score ) AS score,
SUM (r1.norm_score * r2.norm_score) AS norm_score,
-- 상품의 유사도 순위 구하기
ROW_NUMBER() OVER (PARTITION BY r1.product ORDER BY SUM(r1.norm_score * r2.norm_score) DESC) AS rank
--공통 사용자가 존재함녀 상품 페어 만들기
FROM product_base_normalized_rating AS r1 JOIN
product_base_normalized_rating AS r2
ON r1.user_id = r2.user_id
GROUP BY r1.product, r2.product
ORDER BY target, rank ;
User to Item : 1) 사용자와 사용자의 유사도를 계산 2) 유사 사용자가 흥미를 가진 아이템을 구해야한다
사용자끼리의 유사도를 계산하는 쿼리
WITH ratings AS (
-- ratings 테이블
)
, user_base_normalizaed_ratings AS (
--사용자 벡터 정규화하기, product 별 partition by 한것을 user_id로 바꿔주었다.
SELECT user_id, product, score,
SQRT(SUM(score * score) OVER(PARTITION BY user_id)) AS norm,
score / SQRT (SUM (score * score ) OVER
(PARTITION BY user_idt)) AS norm_score
FROM ratings
)
, related_users AS (
-- 경향이 비슷한 사용자 찾기
SELECT r1.user_id, r2.user_id AS related_user,
COUNT (r1.product) AS products,
SUM(r1.norm_score*r2.norm_score) AS score,
ROW_NUMBER() OVER (PARTITION BY r1.user_id
ORDER BY SUM(r1.norm_score * r2.norm_score) DESC) AS rank
FROM user_base_normalized_ratings AS r1
JOIN user_base_normalized_ratings AS r2
ON r1.product = r2.product
WHERE r1.user_id <> r2.user_id
GROUP BY r1.user_id, r2.user_id
)
SELECT *
FROM related_users
ORDER BY user_id, rank ;
추천 시스템을 개선할 때의 포인트
가중치
필터
정렬
추천과 관련한 지표
지표
설명
Coverage
전체 사용자와 아이템 중에서 추천이 제공되는 사용자와 아이템의 비율을 나타내는 값
Confidence
(시스템적인) 추천 아이템의 신뢰도를 나타내는 값. 어떤 아이템을 추천하기 위해 사용한 데이터양이 많으면 Confidence도 높음
Trust
(사용자적인) 추천 아이템의 신뢰도를 나타내는 값. 사용자에게 추천이 제대로 되는지 물어보는 방법으로 얻어냄
Novelty
추천된 아이템의 신규성을 나타내는 값
Serendipity
뜻밖의 아이템을 추천하는지를 나타내는 값
Diversity
추천된 아이템의 다양성을 나타내는 값
Utility
서비스 추천의 유익성을 나타내는 값
Risk
리스크를 포함한 아이템등을 추천할 때 고려해야 함
Adaptivity
아이템이 업데이트와 유행 등의 변화에 잘 대응할 수 있는지 나타내는 값
Scalability
데이터의 양이 늘어났을 때 대응할 수 있는지 나타내는 값
Last updated
Was this helpful?