본문 바로가기

Learning/Recommendation System

03-4. Personalized Recommendation

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)

User History
item-based Recommended items


사용자 기반의 유사도 추천(이력 기반)
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)

User-based Recommended items

클릭된 아이템을 모두 추천하는 것이 아닌 구매하거나, 좋아요를 하거나 장바구니에 담은것들 중 추천
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 이동주

링크 : https://fastcampus.app/course-detail/205535