인기도 기반 추천 알고리즘(Hacker News Formula, Reddit Formula)
뉴스나 피드에 게시글 정렬 방법 중 **추천순** 혹은 **인기순**이라는 정렬 기준을 본적이 있을 것이다. 인기도를 기반으로 추천하는 고전적인 방법으로 비개인화 추천이지만 간단히 사용할 수 있기에 소개해보려 한다. 이번 글에서는 이 중 대표적인 Hacker News Formula와 Reddit Formula에 대해 알아보고자 한다.
Hacker News Formula
- 분자의
pageviews
는 조회수를 의미하며 작성자의 조회수를 제거하기 위해 1을 빼준다. - 분모의
age
는 뉴스 업로드 날짜로부터 현재까지 지난 기간(Hours)를 의미한다. 2를 더해주는 이유는 나와있지 않지만 아래의 2가지 이유정도가 있지 않을까 추측한다.- 분모가 0이 되지 않기위해
- 2가 아닌 1을 더하게되면 age가 0일 때 분모가 항상 1일 되기 때문에 gravity로 score를 조절할 수 없다
gravity
는age
가 커질수록 분모를 얼마나 더 크게 증가시킬 것인지 설정하는 상수이다. Hacker News에서는gravity
값을 1.8로 설정한다. 1보다 큰 값을 사용하므로써 시간이 지남에 따라 오래된 뉴스는 조회수가 높더라도 낮은 점수를 갖게 된다.
# Hacker News Formula
def hacker_news_formula(votes, item_hour_age, gravity=1.8):
return (votes - 1) / (item_hour_age+2)**gravity
Reddit Formula
term1
- _log_를 씌움으로써 초반 좋아요에 높은 점수를 주고 10 이상부터는 점수 상승 폭을 줄이는 역할을 한다.
- 음수가 되는 것을 막기 위해
ups - downs
가 1보다 작으면 1로 고정한다.
term2
- 시간이 지날수록 더 낮은 스코어를 반영하는 역할을 한다.
seconds
의 경우 Reddit이 오픈 한 후부터 게시글이 작성될 때까지의 절대적인 시간을 의미한다. 최신글일수록seconds
의 값이 커지게 된다. 때문에 오래된 포스팅일 수록 아주 많은 추천이 있어야 높은 score를 가질 수 있다.sign
의 경우ups-downs
가 0보다 크면 1, 0일 때는 0, 0보다 작을 때는 -1로 고정된다.- 분자의
45000
의 의미는 12.5 시간을 최신글이라는 기준으로 잡았기 때문에 45000초라는 상수를 사용한다.
import math
def reddit_formula(ups, downs, date):
s = ups - downs
order = math.log10(max(abs(s), 1))
if s > 0:
sign = 1
elif s < 0:
sign = -1
else:
sign = 0
seconds = date - 1134028003
return round(order + sign * seconds / 45000, 7)
References
- https://sungkee-book.tistory.com/10
- https://medium.com/jp-tech/how-are-popular-ranking-algorithms-such-as-reddit-and-hacker-news-working-724e639ed9f7