我正在开展一个项目,我需要根据受欢迎程度(上周,上个月和去年)对用户提交的文章进行排序。
我一直在考虑这个问题,但我不是一个很好的统治者,所以我想我可以在这里得到一些意见。
以下是可用的变量:
现在我正在对每个变量进行一些加权,然后除以读取的次数。在阅读Weighted Means之后,我几乎可以想到这一切。我最大的问题是有一些用户文章总是位于热门列表的顶部。可能是因为作者是“作弊”。
我正在考虑强调文章相对较新的重要性,但我不想因为它们有点老而“惩罚”真正受欢迎的文章。
任何一个比我更有统计学意识的人愿意帮助我吗?
谢谢!
答案 0 :(得分:5)
我认为加权均值方法是一个很好的方法。但我认为你需要做两件事。
此问题属于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倍,是C3重要的一半。使用有限的权重池,比如1.0,因为这很容易。按照我们4 * C1 + 2 * C3 + C2 = 1
或大致C1 = 4/7
,C3 = 2/7
,C2 = 1/7
的条件进行分发。如果出现差异(例如,如果您认为C1 = 2*C2 = 3*C3
,但C3 = 2*C2
),这是一个很好的错误指示:这意味着您与您的相对排名不一致,所以请返回并重新检查它们。我忘记了这个程序的名称,评论在这里会有所帮助。这些都有很好的记录。
现在,在这一点上,这对你来说似乎有点武断。它们大部分都是你从自己的头脑中抽出的数字。所以我建议你抽取大约30篇文章的样本并按照“你的直觉”的方式对它们进行排序,说它们应该被订购(通常你比你能用数字表达的更直观)。 Finagle数字直到他们产生接近该排序的东西。
这是第二个重要方面。无论你使用什么系统,如果你不能阻止“作弊”,它最终会失败。您需要能够限制投票(如果IP能够推荐两次故事吗?)。您需要能够阻止垃圾评论。标准越重要,就越需要防止它被游戏化。
答案 1 :(得分:3)
您可以使用离群理论来检测异常。寻找异常值的一种非常天真的方法是使用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)
有很多方法可以做到这一点,对您有用的方法将取决于您的实际数据集以及您对特定文章的期望。尽管如此,我建议将读取的时间移到加权数字并除以文章的年龄,因为文章越老,每个类别中的数字越高越有可能。
例如
// 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)