8

我想实现一个基于老化的“对数”分数衰减,我试图找出 SUM/LOG 组合。在这里,您有当前查询的简化版本:

SELECT SUM(1) as total_score FROM posts
JOIN votes ON votes.post_id = posts.post_id
WHERE 1
GROUP BY post_id
ORDER BY total_score DESC

我目前正在执行 SELECT 'SUM(1) as total_score' 但我想修改查询以考虑投票的日期/年龄;今天的投票权重为 1,15 天前的投票权重接近 0.8,30 天前的投票权重接近 0。我将投票表 (vote_date) 中的日期字段存储为 unix_timestamp。

在此处输入图像描述

我并不真正关心 WHERE 条款;这很简单。我想弄清楚的是对数老化部分。

4

3 回答 3

3

我认为你的答案有两个部分。首先是加权函数,然后是 SQL 实现。

加权功能:

根据您的图表,您不想要对数权重而是抛物线。

从这里你必须解决

Xc = y

在哪里

X = [1 1 1 ;
    15^2 15 1;
    30^2 30 1];

y = [1;.8;0];

你得到 c = X^(-1)y 或在 matlab

c = X\y

现在你有了你所描绘的二次函数的适当的wieights;即 y = ax^2+bx+c 与 (a,b,c) =(-.0013,.0073,.9941)。

SQL部分:

您的选择语句应该看起来像(假设感兴趣的列名为“年龄”)

SELECT (-.0013*age*age + .0073*age + .9941) as age_weighted

希望能帮助到你

干杯


这是完整的 Matlab 代码(也可以仔细检查解决方案)

X = [1 1 1 ;
    15^2 15 1;
    30^2 30 1];

y = [1;.8;0];

c = X\y;

x= (1:30)';
y = [x.^2 x ones(30,1)]*c;

figure(1)
clf;hold on
plot(x,y)
plot([1 15 30],[1 .8 0],'o')

Matlab 输出

于 2012-11-07T14:51:42.710 回答
0

假设您有一个函数可以计算几天前 WEIGHT(age)的投票权重。age

那么您的查询将是

    SELECT SUM(WEIGHT(DATEDIFF(CURRENT_DATE, votes.date_vote_cast))) as total_score,
           posts.post_id
      FROM posts
      JOIN votes ON votes.post_id = posts.post_id
     WHERE votes.date_vote_cast <= CURRENT_DATE
       AND votes.date_vote_cast > CURRENT_DATE - INTERVAL 30 DAY
  GROUP BY post_id
  ORDER BY total_score DESC 

恐怕我不知道你想要什么功能WEIGHT(age)。但是你这样做了,你可以解决它。

于 2012-10-12T00:31:33.143 回答
0

我还没有完成 SQL 部分,但我找到了一个函数,可以提供你所追求的衰减,至少在数学上

y=(sqrt(900-(x^2)))/30

或者在你的情况下

score=(sqrt(900-(days^2)))/30

在此处输入图像描述

希望它可以帮助!

于 2012-10-12T00:42:07.250 回答