【问题标题】:Algorithm to determine most popular article last week, month and year?确定上周、月份和年份最受欢迎文章的算法?
【发布时间】:2011-04-25 11:26:01
【问题描述】:

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

我一直在考虑这个问题,但我不是一个伟大的统计学家,所以我想我可以在这里得到一些意见。

以下是可用的变量:

  • 文章最初发表的时间 [日期]
  • 编辑推荐文章的时间 [日期](如果已推荐)
  • 文章从用户那里获得的投票数(上周、上个月、去年总计)
  • 文章被查看的次数(上周、上个月、去年总计)
  • 用户下载文章的次数(总计、上周、上个月、去年)
  • 对文章的评论(总计、上周、上个月、去年)
  • 用户将文章保存到其阅读列表的次数(总计、上周、上个月、去年)
  • 文章出现在“我们所能提供的最佳”(社论)列表中的次数(总计、上周、上个月、去年)
  • 文章被称为“本周文章”的时间 [日期](如果有的话)

现在我正在对每个变量进行加权,然后除以它被读取的次数。这几乎是我在阅读Weighted Means 后所能想到的。我最大的问题是有些用户文章总是在热门列表的顶部。可能是因为作者在“作弊”。

我正在考虑强调文章相对较新的重要性,但我不想仅仅因为它们有点旧而“惩罚”真正流行的文章。

有比我更擅长统计的人愿意帮助我吗?

谢谢!

【问题讨论】:

  • 在您了解可疑文章是如何被撞到之前,您无法制定对策。
  • 当然,我知道。由于无法确定用户之前是否已阅读、下载、投票或评论过该文章(匿名用户允许执行上述所有操作),因此总会有一些坏种子在系统中进行游戏。但是,我相信确定文章受欢迎程度的更好算法可能有助于缓解这个问题。我也不想让编辑的东西太高,让用户觉得他们在某种程度上不受控制。我只是要求一些输入:)
  • 难道没有机会根据“注册用户”/“匿名用户”进行权衡吗?在这样的评分中,我会给注册用户 cmets、投票、下载等更多的权重。然后,您已经带走了很大一部分可能的游戏。有关寻找作弊者的其他一些统计学家说明,请参阅我的回答 - 或在 stats.stackexchange.com 再次询问。

标签: algorithm math sorting statistics


【解决方案1】:

您可以使用异常值理论来检测异常。寻找异常值的一种非常幼稚的方法是使用mahalanobis distance。这是一种考虑数据分布的度量,并计算与中心的相对距离。可以解释为文章离中心有多少个标准差。然而,这也将包括真正非常受欢迎的文章,但它会给你一个奇怪的迹象。

第二种更通用的方法是构建模型。您可以将用户可以操纵的变量与与编辑器相关的变量进行回归。人们会期望用户和编辑会在某种程度上同意。如果他们不这样做,那么这再次表明有些事情很奇怪。

在这两种情况下,您都需要定义一些阈值并尝试在此基础上找到一些权重。一种可能的方法是使用平方根马氏距离作为反权重。如果您远离中心,您的分数将被拉低。同样可以使用模型中的残差来完成。在这里,您甚至可以考虑登录。如果编辑器分数低于基于用户分数的预期值,则残差将为负数。如果编辑器分数高于基于用户分数的预期值,则残差为正,并且文章不太可能被玩弄。这允许您定义一些规则来重新衡量给定的分数。

R 中的一个例子:

代码:

#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】:

    我认为加权均值方法是一种很好的方法。但我认为你需要解决两件事。

    1. 如何衡量标准。
    2. 如何防止系统“博弈”

    如何衡量标准

    此问题属于Multi-Criteria Decision Analysis 的域。您的方法是Weighted Sum Model。在任何计算决策过程中,对标准进行排序通常是该过程中最困难的部分。我建议您采取成对比较的方法:您认为每个标准与其他标准相比有多重要?为自己建立一个这样的表:

        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),这是一个很好的错误指示:这意味着您与您的相对排名不一致,因此请返回并重新检查它们。我忘记了这个程序的名称,cmets 在这里会很有帮助。这都是有据可查的。

    现在,这一切对您来说可能有点武断。它们是您从自己的脑海中提取出来的大部分数字。所以我建议抽取大约 30 篇文章的样本,并按照“你的直觉”所说的应该排序的方式对它们进行排序(通常你比用数字表达的更直观)。确定数字,直到它们产生接近该顺序的东西。

    防止游戏

    这是第二个重要方面。无论你使用什么系统,如果你不能阻止“作弊”,它最终会失败。你需要能够限制投票(一个 IP 应该能够推荐一个故事两次吗?)。您需要能够防止垃圾邮件 cmets。标准越重要,就越需要防止它被人玩弄。

    【讨论】:

    • 谢谢!我会继续建造那张桌子。 :) 已经有一个系统可以防止游戏(在一定程度上),但我也会考虑改进它。
    【解决方案3】:

    有多种方法可以做到这一点,哪种方法适合您将取决于您的实际数据集以及您希望特定文章的结果。不过,作为一个粗略的修改,我建议将阅读次数移至加权数字并除以文章的年龄,因为文章越旧,每个类别中的数字就越多。

    例如

    // 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)
    

    【讨论】:

    • 谢谢。我会研究年龄参数,看看我是否能得到更好的结果。我倾向于同意马克的观点,其中最困难的部分是我将如何加权每个变量。我会看看我得出了什么结果,并通过检查日志记录程序来调查文章的“真实性”。
    猜你喜欢
    • 1970-01-01
    • 2016-06-25
    • 2012-12-16
    • 2023-03-24
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    相关资源
    最近更新 更多