复现Reddit Hot算法时始终返回0,求解决方案
解决Reddit Hot算法中指数衰减导致结果为0的问题
嘿,我来帮你搞定这个Reddit Hot算法的问题!你现在遇到的核心问题是那个指数衰减项exp(-8 * x * x)太激进了,导致结果很快就趋近于0,咱们一步步来拆解解决思路:
问题根源分析
你写的衰减公式exp(-8 * x * x)是二次指数衰减,衰减速度快到离谱:
- 当帖子发布1天后(
x=0),衰减项是exp(0)=1,没问题; - 发布2天后(
x=1),exp(-8*1²)=exp(-8)≈0.0003,已经几乎可以忽略; - 发布3天后(
x=2),exp(-8*4)=exp(-32),这个值小到在Python里直接显示为0。
这完全不符合Reddit原算法的设计——原算法的时间衰减是线性偏移,不是极端的二次指数衰减。
正确的解决思路
1. 还原Reddit原Hot算法的核心逻辑
Reddit的Hot算法公式核心是:
分数 = log(max(|点赞数-点踩数|, 1)) + (帖子发布时间戳 - 基准时间戳) / 45000
其中:
- 基准时间戳是2005年12月8日(对应Unix时间戳
1134028003),这是Reddit上线的时间; 45000秒(约12.5小时)是时间衰减的系数,意思是每过12.5小时,帖子的时间权重增加1分(和投票得分的权重对齐);- 还要区分投票差的正负:如果是正分(点赞>点踩),直接用log值;如果是负分,用-log的相反数。
2. 修正后的代码示例
import math from datetime import datetime def hot(self): # 原算法核心是计算点赞与点踩的差值,而不是只算点赞 vote_diff = self.upvotes - self.downvotes # 取绝对值的对数,避免0或负数的log问题 abs_vote = max(abs(vote_diff), 1) base_score = math.log(abs_vote) # Reddit的基准时间(2005年12月8日) reddit_epoch = datetime.fromtimestamp(1134028003) # 计算帖子发布到现在的总秒数,而不是天数(精度更高) time_diff_seconds = (datetime.now() - self.post.date).total_seconds() # 时间衰减项:每45000秒(约12.5小时)增加1分权重 time_factor = time_diff_seconds / 45000 # 根据投票差的正负调整基准分 if vote_diff > 0: final_score = base_score + time_factor elif vote_diff < 0: final_score = -base_score + time_factor else: final_score = time_factor # 投票差为0时,只看时间 print('Final:', final_score) return final_score
3. 如果坚持用指数衰减(非原算法)
如果你一定要保留指数衰减的逻辑,需要大幅降低衰减系数,同时把二次项改成一次项,让衰减更平缓。比如把公式改成exp(-0.08 * x),其中x是发布后的天数:
def hot(self): s = self.upvotes - self.downvotes base_score = math.log(max(abs(s), 1)) now = datetime.now() time_diff_days = (now - self.post.date).days # 平缓的一次指数衰减,系数0.08可根据需求调整 if time_diff_days > 1: decay_factor = math.exp(-0.08 * (time_diff_days - 1)) base_score *= decay_factor print('Final:', base_score) return base_score
这样哪怕帖子发布10天,衰减项是exp(-0.08*9)=exp(-0.72)≈0.487,还能保留接近一半的基础分,不会直接变成0。
内容的提问来源于stack exchange,提问作者Zorgan
相关产品推荐
相关产品推荐

