Personalized Recommendation
-> 사용자의 활동 로그를 활용하여 프로파일 생성
1. 연관 추천을 이용한 개인화
2. 유사한 사용자 기반의 개인화(kNN)
: user의 History는 event의 집합이다.
이 event는 어떤 item을 클릭하거나 구매한 timestamp가 존재한다.
연관 추천을 이용한 개인화
- 관련이 있는 Item A,B,C가 시간 순서에 따라 행동 로그가 생겼을때, C가 가장 최근에 발생한 item이기 때문에 가중치 1을 부여하고 나머지 B,A는 순서에 따라 0.7, 0.5의 가중치를 부여한다는 컨셉
- 스코어링
어떤 user가 아이템 j에 대해서 가지는 스코어 값은
어떤 user History에 있는 이 event에서 어떤 item과 다른 item j가 시간이 지남에 따라 r(t)를 곱해서 사용
-> 과거 이력에 대해서는 결합 가중치를 낮춘다는 컨셉
유사한 사용자 기반의 개인화(kNN - k Nearest Neighbor)
- 유사한 사용자들을 찾아서 구매, 좋아요 등의 상품들을 합쳐서 추천
어떤 user가 j에 대해서 어떤 스코어 값을 갖는가.
SU : U와 취향이 유사한 사용자 집합의 유사도
(u와 v의 유사도) * (v가 j에 가졌던 유사도)
item 기반의 유사도 추천(최근 이력 반영)
어떤 유저에 대한 로그 확인(event log + product info)
query = f'''
select a.session_id, a.event_timestamp, a.user_no, b.*
from cmc_event a join cmc_product b on b.item_no = a.item_no
where user_no = '++MXKfwkOw4VFn9HkVCRrw=='
and event_timestamp between '2021-07-18' and '2021-07-25'
order by event_timestamp desc
limit 20;
'''
result = executeQuery(query)
result
displayItemDetailInRows(result)
item 기반의 유사도 추천
query1 = f'''
with rec as (
--시간에 따른 디케입스??값 구하기
select b.b_item_no, sum(a.time_weight * b.sim) score
from (
--12시간마다 0.9씩 감소하도록(시간에 따른 가중치 적용)
select item_no, pow(0.9, (date_part('day', to_timestamp('2021-07-25', 'YYYY-MM-DD') - event_timestamp) * 24 + date_part('hour', to_timestamp('2021-07-25', 'YYYY-MM-DD') - event_timestamp))/12) time_weight
from cmc_event
where user_no = '++MXKfwkOw4VFn9HkVCRrw=='
and event_timestamp between '2021-07-18' and '2021-07-25'
order by event_timestamp desc
limit 10
) a
join
(
--3. 유사한 아이템 값을 찾을 때 top 20개만
select a_item_no, b_item_no, sim
from (
select a_item_no, b_item_no, sim, row_number() over (partition by a_item_no order by sim desc) rank
from (
--2. 세션 기반의 유사도로 유사한 아이템 찾기
select a.item_no a_item_no, b.item_no b_item_no, sum(a.w * b.w) sim
from cmc_session_product_click_w a
join cmc_session_product_click_w b on a.session_id = b.session_id and a.item_no != b.item_no
where a.item_no in (
--1. 해당 상품에 대한 최근 10개의 로그
select item_no
from cmc_event
where user_no = '++MXKfwkOw4VFn9HkVCRrw=='
and event_timestamp between '2021-07-18' and '2021-07-25'
order by event_timestamp desc
limit 10 )
group by a.item_no, b.item_no ) t
) t
where rank <= 20
) as b on a.item_no = b.a_item_no
group by b.b_item_no
order by score desc
limit 20 )
select a.score, b.*
from rec a join cmc_product b on a.b_item_no = b.item_no;
'''
result1 = executeQuery(query1)
print('User Hisotry')
displayItemInRows(result)
print('Recommended Items')
displayItemInRows(result1)
사용자 기반의 유사도 추천(이력 기반)
query2 = '''
with rec as (
-- 아이템 20개 추천하기
select b.item_no, sum(a.sim * b.w) score
from (
-- 유사한 사용자가 클릭하거나 구매한 데이터
select b.user_no, sum(a.w * b.w) sim
from cmc_user_product_click_w a
join cmc_user_product_click_w b
on a.item_no = b.item_no
and a.user_no != b.user_no
where a.user_no = '++MXKfwkOw4VFn9HkVCRrw=='
group by b.user_no
order by sim desc
limit 20 ) a
join cmc_user_product_click_w b
on b.user_no = a.user_no
group by b.item_no
order by score desc
limit 20)
select a.score, b.*
from rec a join cmc_product b on a.item_no = b.item_no
'''
result2 = executeQuery(query2)
print('User-based Recommended Items')
displayItemInRows(result2)
클릭된 아이템을 모두 추천하는 것이 아닌 구매하거나, 좋아요를 하거나 장바구니에 담은것들 중 추천
query3 = '''
with rec as (
select b.item_no, sum(sim * event_weight * time_weight) score
from (
select b.user_no, sum(a.w * b.w) sim
from cmc_user_product_click_w a join cmc_user_product_click_w b on a.item_no = b.item_no and a.user_no != b.user_no
where a.user_no = '++MXKfwkOw4VFn9HkVCRrw=='
group by b.user_no
order by sim desc
limit 20 ) a
join (
select user_no, item_no,
case
when event_name = 'purchase_success' then 3
when event_name = 'add_to_cart' then 2
when event_name = 'like_item' then 1
end event_weight,
pow(0.9, (date_part('day', to_timestamp('2021-07-25', 'YYYY-MM-DD') - event_timestamp) * 24 + date_part('hour', to_timestamp('2021-07-25', 'YYYY-MM-DD') - event_timestamp))/12) time_weight
from cmc_event
where event_timestamp between '2021-07-18' and '2021-07-25'
and event_name in ('purchase_success', 'like_item', 'add_to_cart')
) b on b.user_no = a.user_no
group by b.item_no
order by score desc
limit 20)
select a.score, b.*
from rec a join cmc_product b on a.item_no = b.item_no
'''
result3 = executeQuery(query3)
displayItemInRows(result3)
출처 : The RED : 현실 데이터를 활용한 추천시스템 구현 A to Z by 번개장터 CTO 이동주
'Learning > Recommendation System' 카테고리의 다른 글
04-2. 그래프 기반 추천(Graph-based) (0) | 2022.06.22 |
---|---|
04-1. 고급 추천(Beyond Accuracy) (0) | 2022.06.13 |
03-3. Related Recommendation (0) | 2022.06.02 |
03-2. Best Recommendation (0) | 2022.06.02 |
03-1. E-commerce 상품 추천(트랜잭션 데이터 기반) (0) | 2022.05.16 |