算法:确定上周、上月和去年最受欢迎的文章?

7

我正在处理一个项目,需要按照文章的受欢迎程度(上周、上个月和去年)对用户提交的文章列表进行排序。

我已经思考了一段时间,但是我不是一个很好的统计学家,所以我想在这里得到一些意见。

以下是可用的变量:

  • 文章最初发布时间 [日期]
  • 如果有的话,编辑推荐文章的时间 [日期]
  • 用户投票数(总数、最近一周、最近一个月、最近一年)
  • 文章被查看次数(总数、最近一周、最近一个月、最近一年)
  • 用户下载文章的次数(总数、最近一周、最近一个月、最近一年)
  • 文章评论数(总数、最近一周、最近一个月、最近一年)
  • 用户将文章保存到阅读列表中的次数(总数、最近一周、最近一个月、最近一年)
  • 文章被列为“我们所提供的最佳内容”(编辑)列表的次数(总数、最近一周、最近一个月、最近一年)
  • 文章被评为“本周文章”时间 [日期](如果有的话)

现在我正在对每个变量进行一些加权处理,并通过阅读次数进行分割。这基本上是我在阅读加权平均值后能想到的全部内容。我的最大问题是,有些用户文章总是在热门列表的顶部。可能是因为作者在“作弊”。

我考虑强调文章相对较新的重要性,但我不想因为它们有点旧就“惩罚”那些真正受欢迎的文章。

有没有比我更具统计学技能的人愿意帮助我?

谢谢!


除非你理解了可疑文章是如何被顶起的,否则你无法制定对策。 - Dialecticus
当然,我知道这个。由于没有确定的方法来判断用户是否在阅读、下载、投票或评论文章之前(匿名用户可以进行以上所有操作),总会有一些不良分子操纵系统。然而,我相信一个更好的算法来确定一篇文章的受欢迎程度可能会有所帮助。我也不想过分强调编辑内容的重要性,让用户觉得他们没有控制权。我只是想听听大家的意见 :) - AmITheRWord
有没有可能根据“注册用户”/“匿名用户”进行权重评估?在这样的评分中,我会给予注册用户的评论、投票、下载等更多的权重。这样你就可以消除大部分可能的作弊行为。关于寻找作弊者的其他统计学笔记,请参阅我的答案-或者再次在stats.stackexchange.com上提问。 - Joris Meys
3个回答

5
我认为加权平均方法是一个不错的选择。但我认为您需要解决两个问题。
  1. 如何给标准加权。
  2. 如何防止“操纵”系统

如何给标准加权

这个问题属于多标准决策分析的范畴。您的方法是加权和模型。在任何计算决策过程中,对标准进行排名通常是最困难的部分。我建议您采用成对比较的方法:您认为每个标准与其他标准相比有多重要?建立类似以下表格:

    c1     c2    c3   ...

c1  1      4      2

c2  1/4    1     1/2

c3  1/2    2      1

...

这表明C1的重要性是C2的4倍,而C2的重要性是C3的一半。使用有限的权重池,例如1.0,因为这很容易。将其分配到标准上,我们有4 * C1 + 2 * C3 + C2 = 1或大约C1 = 4/7C3 = 2/7C2 = 1/7。当出现差异(例如,如果您认为C1 = 2*C2 = 3*C3,但C3 = 2*C2),那么这是一个好的错误指示:这意味着您在相对排名方面不一致,因此请返回并重新检查它们。我忘记了这个过程的名称,评论会很有帮助。这都有很好的文献记录。
现在,在这一点上,所有这些可能似乎有点武断。它们大多数是你自己想出来的数字。所以我建议取30篇文章样本,并按照“直觉”告诉你应该排序的方式对它们进行排名(通常你比你可以用数字表达更具直觉)。调整数字,直到它们产生接近那种排序的东西。

防止游戏作弊

这是第二个重要方面。无论您使用什么系统,如果无法防止“作弊”,最终都将失败。您需要能够限制投票(一个IP地址是否可以推荐一个故事两次?)。您需要能够防止垃圾评论。标准越重要,就越需要防止其被人为操纵。


谢谢!我会开始建立那个表格。 :) 已经有一个系统来防止作弊(在一定程度上),但我也会考虑改进它。 - AmITheRWord

3
您可以使用异常理论来检测异常情况。寻找异常值的一种非常天真的方法是使用mahalanobis距离。这是一种考虑到数据分布的度量,并计算相对于中心的距离。它可以解释为文章距离中心有多少个标准偏差。然而,这也将包括真正非常受欢迎的文章,但它给出了第一个指示,表明某些内容很奇怪。
第二种更普遍的方法是建立模型。您可以对用户可操作的变量和与编辑相关的变量进行回归。人们会期望用户和编辑在某种程度上达成一致。如果他们没有达成一致,则再次表明存在异常情况。
在这两种情况下,你需要定义一些阈值并尝试找到基于此的一些加权。一种可能的方法是使用平方根马氏距离作为反向权重。如果你远离中心,你的分数将会下降。同样的方法也可以使用模型残差。在这里,你甚至可以考虑符号。如果编辑得分低于基于用户得分预期的得分,残差将为负。如果编辑得分高于基于用户得分预期的得分,残差为正,并且文章很可能没有被操纵。这使你可以定义一些规则来重新加权给定的分数。
R语言示例:

alt text

代码:

#Test data frame generated at random
test <- data.frame(
  quoted = rpois(100,12),
  seen = rbinom(100,60,0.3),
  download = rbinom(100,30,0.3)
)
#Create some link between user-vars and editorial
test <- within(test,{
  editorial = round((quoted+seen+download)/10+rpois(100,1))
})
#add two test cases
test[101,]<-c(20,18,13,0) #bad article, hyped by few spammers
test[102,]<-c(20,18,13,8) # genuinely good article

# mahalanobis distances
mah <- mahalanobis(test,colMeans(test),cov(test))
# simple linear modelling
mod <- lm(editorial~quoted*seen*download,data=test)

# the plots
op <- par(mfrow=c(1,2))
hist(mah,breaks=20,col="grey",main="Mahalanobis distance")
points(mah[101],0,col="red",pch=19)
points(mah[102],0,,col="darkgreen",pch=19)
legend("topright",legend=c("high rated by editors","gamed"),
  pch=19,col=c("darkgreen","red"))

hist(resid(mod),breaks=20,col="grey",main="Residuals model",xlim=c(-6,4))
points(resid(mod)[101],0,col="red",pch=19)
points(resid(mod)[102],0,,col="darkgreen",pch=19)

par(op)

2

有很多方法可以实现这个目标,而哪种方法适用于您将取决于您的实际数据集和您对特定文章的期望结果。然而,粗略地重新处理一下的话,我建议将已阅读次数移到加权数字中,并按文章的年龄进行划分,因为文章越老,在每个类别中的数字越高的可能性就越大。

例如:

// x[i] = any given variable above
// w[i] = weighting for that variable
// age = days since published OR 
//      days since editor recommendation OR 
//      average of both OR 
//      ...
score = (x[1]w[1] + ... + x[n]w[n])/age

你希望提升新文章的推广度,但又不想惩罚那些真正受欢迎的老文章,这需要考虑如何区分一篇文章是否真正受欢迎。然后使用“真实性”算法来对投票或浏览量进行加权,而不是采用静态加权。你还可以将任何其他加权更改为函数形式,而不是常量形式,从而可以对任何你想要的变量拥有非线性加权。
// Fw = some non-linear function
// (possibly multi-variable) that calculates
// a sub-score for the given variable(s)  
score = (Fw1(x[1]) + ... + FwN(x[n]))/FwAge(age)

谢谢。我会研究一下年龄参数,看看是否能得到更好的结果。我倾向于同意马克的观点,即最困难的部分是如何权衡每个变量。我会查看日志记录过程,了解文章的真实性,并观察结果。 - AmITheRWord

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接