2

我正在研究基于 Reddit 模型的帖子系统的时间衰减算法:http: //amix.dk/blog/post/19588

我的工作端口在这里:

public class Calculation
{
    protected DateTime Epoch = new DateTime(1970, 1, 1);

    protected long EpochSeconds(DateTime dt)
    {
        var ts = dt.Subtract(Convert.ToDateTime("1/1/1970 8:00:00 AM"));

        return ((((((ts.Days * 24) + ts.Hours) * 60) + ts.Minutes) * 60) + ts.Seconds);
    }

    protected int Score(int upVotes, int downVotes)
    {
        return upVotes - downVotes;
    }

    public double HotScore(int upVotes, int downVotes, DateTime date)
    {
        var s = Score(upVotes, downVotes);
        var order = Math.Log(Math.Max(Math.Abs(s), 1), 10);
        var sign = Math.Sign(s);
        var seconds = EpochSeconds(date) - 1134028003;
        return Math.Round(order + sign * ((double)seconds / 45000), 7);
    }
}

根据提供的链接的模型输出,我应该会在 0-13 小时看到逐渐衰减,然后急剧衰减。

我看到的是非常均匀的衰减,并且得分远高于原始代码的输出(原始代码:3480-3471)。

这是我的测试方式:

        Calculation c = new Calculation();
        double now = c.HotScore(100, 2, DateTime.Now);
        double fivehoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-5));
        double tenhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-10));
        double elevenhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-11));
        double twelvehoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-12));
        double thirteenhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-13));
        double fiftyhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-50));
        double onehundredhoursago = c.HotScore(100, 2, DateTime.Now.AddHours(-100));
        Console.WriteLine(now.ToString());
        Console.WriteLine(fivehoursago.ToString());
        Console.WriteLine(tenhoursago.ToString());
        Console.WriteLine(elevenhoursago.ToString());
        Console.WriteLine(twelvehoursago.ToString());
        Console.WriteLine(thirteenhoursago.ToString());
        Console.WriteLine(fiftyhoursago.ToString());
        Console.WriteLine(onehundredhoursago.ToString());
        Console.ReadLine();

输出值:

now:               4675.2993816
five hours:        4674.8993816
ten hours:         4674.4993816
eleven hours:      4674.4193816
twelve hours:      4674.3393816
thirteen hours:    4674.2593816
fifty hours:       4671.2993816
one-hundred hours: 4667.2993816

显然,它的工作正常,但有些不对劲。这可能与缺乏真正的 *nix Epoch 支持或缺乏类似的微秒计算有关,但有些地方不太对劲。

可能的参考资源:http: //blogs.msdn.com/b/brada/archive/2004/03/20/93332.aspx http://codeclimber.net.nz/archive/2007/07/10/convert-a -unix-timestamp-to-a-.net-datetime.aspx

4

1 回答 1

3

您的主要问题是热算法是时间相关的。您计算的热门分数是DateTime.Now,而文章写于 2010 年 11 月 23 日(请看文章底部)。

经过反复试验,数据似乎是在大约 2010-11-23 07:35 计算的。尝试使用该值而不是DateTime.Now,您应该得到与图中所示数据大致相同的结果。

请注意,您可以对代码进行以下改进:

public class Calculation
{
    private static readonly DateTime Epoch = new DateTime(1970, 1, 1);

    private double EpochSeconds(DateTime dt)
    {
        return (dt - Epoch).TotalSeconds;
    }

    private int Score(int upVotes, int downVotes)
    {
        return upVotes - downVotes;
    }

    public double HotScore(int upVotes, int downVotes, DateTime date)
    {
        int s = Score(upVotes, downVotes);
        double order = Math.Log(Math.Max(Math.Abs(s), 1), 10);
        int sign = Math.Sign(s);
        double seconds = EpochSeconds(date) - 1134028003;
        return Math.Round(order + sign * seconds / 45000, 7);
    }
}

我的结果:

3479.0956039
3478.6956039
3478.2956039
3478.2156039
3478.1356039
3478.0556039
3475.0956039
3471.0956039

变化:

  • 使用声明的 Epoch 而不是 1970-01-01 08:00:00 的转换(我认为 08:00 是一个错误)。
  • a - b您可以使用;减去两个日期 这与原始 Python 代码相同a.Subtract(b)但更简洁。
  • 时间跨度确实为您提供微秒精度(刻度是最小单位,等于 100 纳秒)。
  • 此外,TotalSeconds 为您提供时间跨度内的总秒数;无需重新计算。小数部分甚至可以为您提供微秒精度。
  • 通过从 EpochSeconds 返回 double,您可以保持此精度。
  • 使数据类型显式而不是var清楚地指示什么变量是什么(它们与方法签名匹配,因此没有隐式向上转换)。
  • 将不需要protectedprivate更改Epoch为常量。
于 2012-08-08T00:29:56.790 回答