{{ message }}

Instantly share code, notes, and snippets.

yanghua/reddit_hot_sortAlgorithm_analysis.md

Last active Sep 3, 2021
Reddit 最新热度排名算法分析

#source code

```cdef extern from "math.h":
double log10(double)
double sqrt(double)

epoch = datetime(1970, 1, 1, tzinfo = g.tz)

cpdef double epoch_seconds(date):
"""Returns the number of seconds from the epoch to date. Should
match the number returned by the equivalent function in
postgres."""
td = date - epoch
return td.days * 86400 + td.seconds + (float(td.microseconds) / 1000000)

cpdef long score(long ups, long downs):
return ups - downs

cpdef double hot(long ups, long downs, date):
return _hot(ups, downs, epoch_seconds(date))

cpdef double _hot(long ups, long downs, double date):
"""The hot formula. Should match the equivalent function in postgres."""
s = score(ups, downs)
order = log10(max(abs(s), 1))
if s > 0:
sign = 1
elif s < 0:
sign = -1
else:
sign = 0
seconds = date - 1134028003
return round(sign * order + seconds / 45000, 7)```

#analysis

```cdef extern from "math.h":
double log10(double)
double sqrt(double)```

`epoch = datetime(1970, 1, 1, tzinfo = g.tz)`

```cpdef double epoch_seconds(date):
"""Returns the number of seconds from the epoch to date. Should
match the number returned by the equivalent function in
postgres."""
td = date - epoch
return td.days * 86400 + td.seconds + (float(td.microseconds) / 1000000)```

```cpdef long score(long ups, long downs):
return ups - downs```

```cpdef double hot(long ups, long downs, date):
return _hot(ups, downs, epoch_seconds(date))```

```cpdef double _hot(long ups, long downs, double date):
"""The hot formula. Should match the equivalent function in postgres."""
s = score(ups, downs)
order = log10(max(abs(s), 1))
if s > 0:
sign = 1
elif s < 0:
sign = -1
else:
sign = 0
seconds = date - 1134028003
return round(sign * order + seconds / 45000, 7)```

s :得分，赞同数与反对数的差值

order :分解如下

abs(s) :得分的绝对值，忽略正负，下面简称为 x

max(x,1) :如果赞同数等于反对数，则结果为1,否则为x，对其结果下面简称为 y

log10(y) :此处为什么要选择进行log运算，目的是为了 平缓 跟风投票/后续投票的 影响力 (有些权重的意思) ，例如此处y为1，结果为0;y为10，结果为1;y为100，结果为2;y为1000，结果为3;投前10票的人，跟后面跟风投99票的人影响力等同。这在某种程度上对恶意刷排名有一定的抑制作用。对于该结果，下面简称为 z

sign :是一个标识，用于判断，该帖子的整体的趋势是被赞成还是被反对的，它很重要，因为在下面它直接决定了，它是评判热度的加分项还是减分项！

seconds :得出发帖时间，上面已经提到，这里的date变量存储的是发帖时间距离时间纪元的秒数，而此处的 1134028003 换算成日期时间为： 2005年12月8日7:46:43 对于该特殊时间的解释，网传是Reddit成立的时间，由此可见，seconds又是个相对时间的秒数，可以理解为相对发帖时间

round(sign * order + seconds / 45000, 7) :分解如下

sign * order :根据赞成数与反对数来计算得分，上面以及解释过，两者的差额越大，则order越高。但光凭差额还不够，需要看用户的投票趋势或方向（这是非常重要的）。因此sign直接影响热度（如果用户整体呈反对趋势，不认为它热度很高）。

seconds / 45000 :表示发帖时间越长，其排名越往下降，45000为12.5小时的秒数（即为半天），注意，seconds是一个相对时间，如果发帖时间越早，其越小，导致该值也就越小

round(sign * order + seconds / 45000, 7) ：保留小数点后的7位

`round(order + sign * seconds /45000, 7)`

to join this conversation on GitHub. Already have an account? Sign in to comment