Non-personalized recommendations
이 장에서는 추천을 찾을 수 있지만, 개인화된 것은 아닙니다. 그렇다고 해서 이 장이 덜 중요하다는 의미는 아닙니다.
비개인화된 추천을 사용하는 것도 흥미로운 콘텐츠를 보여줄 수 있음을 알게 될 것입니다.
당신의 사이트가 콘텐츠를 정렬해야 하는 이유를 보여주는 예시들을 보게 될 것이고, 인기 있는 것을 보여주고 다른 사용자들의 관심 항목을 강조하는 차트를 만드는 방법을 배울 것입니다.
쇼핑 바구니를 기반으로 아이템셋을 생성하여 연관 규칙을 계산하는 방법을 배우고, 그 규칙을 사용하여 시드된 추천을 생성할 것입니다.
MovieGEEKs 예제 사이트의 핵심 구성 요소이며 추천을 제공하는 추천자 구성 요소가 어떻게 구현되는지 볼 수 있을 것입니다.
차트는 매우 유용하며 추가하기 쉽습니다. 구매된 항목의 수를 세는 것뿐만 아니라 다양한 방법으로 데이터를 차트로 만들 수 있습니다.
정렬되지 않은 콘텐츠를 제시하는 것은 좋지 않습니다. 콘텐츠는 대부분의 사용자가 관심 있어 할 것으로 생각되는 순서대로 정렬되어야 합니다. 영화나 책의 경우 출시 날짜별로, 쿠폰의 경우 절약된 금액별로 정렬할 수 있습니다.
연관 규칙은 함께 구매된 것을 기반으로 하며, 자주 함께 구매된(FBT) 추천을 보여주는 데 사용됩니다. 규칙의 유용성은 지지도와 신뢰도 지표를 보며 계산됩니다.
추천을 데이터베이스에 저장하는 것이 좋습니다; 이는 추천 시스템이 더 빠르게 응답하게 만들 것입니다. 반면에, 그것들을 계산하는 데는 시간이 걸리고 공간을 차지합니다.
데이터베이스에 있는 추천에 버전 번호를 추가하면 한 번에 여러 버전을 데이터베이스에 가질 수 있습니다. 이는 생산에 사용되는 것을 가지고 있으면서 준비가 되었을 때 새로운 것으로 전환할 수 있음을 의미합니다. 하지만 더 중요한 것은, 현재 사용 중인 추천에 문제가 발생한 경우 이전 버전으로 돌아갈 수 있다는 것입니다.
목록 5.1 SQL 쿼리를 나열하여 가장 많이 판매된 제품을 가져옵니다
SELECT content_id,
mov.title, # content_id, 영화 제목 및 카운트를 가져옵니다
count(*) as sold
FROM collector_log log # 로그 테이블에서 구매 카운트를 가져옵니다
JOIN moviegeeks_movie mov
ON log.content_id = mov.movie_id # movie ID를 사용하여 movie 테이블과 로그 테이블을 연결합니다
WHERE event like 'buy'
GROUP BY content_id, mov.title #content_id 와 title group by
ORDER BY sold desc # 판매열별 주문 내림차순
목록 5.2 추천서의 차트 방법 / views.py
def chart(request, take=10):
sorted_items = PopularityBasedRecs().recommend_items_from_log(take)
ids = [i['content_id'] for i in sorted_items]
ms = {m['movie_id']: m['title'] for m in
Movie.objects.filter(movie_id__in=ids).values('title','movie_id')}
sorted_items = [{'movie_id': i['content_id'],
'title': ms[i['content_id']]} \
for i in sorted_items]
data = { 'data': sorted_items }
return JsonResponse(data, safe=False)
목록 5.3 recs의 recommend_items_from_log 메서드 /popularity_ recommender.py
def recommend_items_from_log(self, num=6):
items = Log.objects.values('content_id')
items = items.filter(event='buy').annotate(Count('user_id'))
sorted_items = sorted(items, key=lambda item: -float(item['user_id__count']))
return sorted_items[:num]
목록 5.4 가장 오래된 영화 먼저 받기
movies = selected.movies.order_by('year')
목록 5.5 최신 영화 먼저 받기
movies = selected.movies.order_by('-year')
목록 5.6 로그에서 구매 이벤트 검색
def retrieve_buy_events():
sql = """
SELECT *
FROM Collector_log
WHERE event = 'buy'
ORDER BY session_id, content_id
"""
cursor = data_helper.get_query_cursor(sql)
data = data_helper.dictfetchall(cursor)
return data
목록 5.7 목록 작성 및 사전에 추가
def generate_transactions(data):
transactions = dict()
for trans_item in data:
id = trans_item["session_id"]
if id not in transactions:
transactions[id] = []
transactions[id].append(trans_item["content_id"])
return transactions
목록 5.8 주파수 집합에 대한 지원 및 신뢰도 계산
def calculate_support_confidence(transactions, min_sup=0.01):
N = len(transactions)
one_itemsets = calculate_itemsets_one(transactions, min_sup)
two_itemsets = calculate_itemsets_two(transactions, one_itemsets, min_sup)
rules = calculate_association_rules(one_itemsets, two_itemsets, N)
return sorted(rules)
목록 5.9 하나의 요소만으로 아이템 세트 목록 작성
def calculate_itemsets_one(transactions, min_sup=0.01):
N = len(transactions)
temp = defaultdict(int)
one_itemsets = dict()
for key, items in transactions.items():
for item in items:
inx = frozenset({item})1 temp[inx] += 1
# remove all items that is not supported.
for key, itemset in temp.items():
if itemset > min_sup * N:
one_itemsets[key] = itemset
return one_itemsets
목록 5.10 2가지 요소를 포함한 아이템 세트 목록 작성
def calculate_itemsets_two(transactions, one_itemsets, min_sup=0.01):
two_itemsets = defaultdict(int)
for key, items in transactions.items():
items = list(set(items))
if (len(items) > 2):
for perm in combinations(items, 2):
if has_support(perm, one_itemsets):
two_itemsets[frozenset(perm)] += 1
목록 5.11 연관규칙 계산
def calculate_association_rules(one_itemsets, two_itemsets, N):
timestamp = datetime.now()
rules = []
for source, source_freq in one_itemsets.items():
for key, group_freq in two_itemsets.items():
if source.issubset(key):
target = key.difference(source)
support = group_freq / N
confidence = group_freq / source_freq
rules.append((timestamp, next(iter(source)), next(iter(target)), confidence, support))
return rules
목록 5.12 특정 소스의 최신 버전에서 연결 규칙을 검색하기 위해 SQL 나열
WITH currentversion as
(SELECT version
FROM version
WHERE type = 'association_rules'
ORDER BY version desc
LIMIT 1)
SELECT *
FROM seeded_recs recs
WHERE source = '<the source id>'
AND recs.version = currentversion
목록 5.13 연관규칙 산출
python –m builder.association_rules_calculator
5.14 연관규칙을 사용한 시드 추천 규칙 나열
def get_association_rules_for(request, content_id, take=6):
data = SeededRecs.objects.filter(source=content_id) \
.order_by('-confidence') \
.values('target', 'confidence', 'support')[:take]
return JsonResponse(dict(data=list(data)), safe=False)