基于页面浏览量/评论计算页面重要性的算法

11

我需要一个算法,能够根据页面的浏览量和评论数确定我的网站站点地图中适当的<priority>字段。

对于那些不熟悉站点地图的人来说,优先级字段用于指示页面相对于同一网站上的其他页面的重要性。它必须是介于0和1之间的十进制数。

该算法将接受两个参数,即viewCountcommentCount,并返回优先级值。例如:

GetPriority(100000, 100000); // Damn, a lot of views/comments! The returned value will be very close to 1, for example 0.995
GetPriority(3, 2); // Ok not many users are interested in this page, so for example it will return 0.082

2
请提供一个用于计算站点地图中优先级的公式,用于SO的计算。 - stacker
1
如果更多的浏览量(或评论)意味着更重要,那么您可以获得浏览量(或评论)的总最大数量m,然后您可以为每个页面将其浏览量(或评论)除以m。这将产生一个介于0和1之间的数字,并且“最重要”的(即最多浏览量或评论)网站将具有优先级1。 - phimuemue
@j_random_hacker 问题不在于顺序,而在于如何根据这些数据分配优先级值。假设我已经将它们排序好了,那么我需要将数据分成10组,并为每组设置不同的值:1.0、0.9、0.8、0.7、0.6、0.5、0.4、0.3、0.2、0.1、0.0。问题是我需要在SQL查询中完成这个任务,而且行甚至没有按照这个值排序。 - stacker
@stacker,我稍微整理了一下你的问题,希望你不介意 :O - Andreas Bonini
@stacker:抱歉我之前表述不够清楚。我的意思是,这些优先级数值只用于某个列表中最终结果的排序,对吧?因此这些数值本身并不重要,只有相对数值的顺序才重要。例如,你可以将所有优先级数值加倍,而含义不会改变,对吗?(我试图理解优先级字段的最终目的。) - j_random_hacker
显示剩余2条评论
6个回答

12

你提到要在SQL查询中完成这个操作,所以下面我将给出SQL示例。

如果您有一个名为Pages的表/视图,类似于下面这样:

Pages
-----
page_id:int
views:int  - indexed
comments:int - indexed

然后你可以通过编写以下代码来对它们进行排序

SELECT * FROM Pages
ORDER BY 
    (0.3+LOG10(10+views)/LOG10(10+(SELECT MAX(views) FROM Pages))) +       
    (0.7+LOG10(10+comments)/LOG10(10+(SELECT MAX(comments) FROM Pages)))

我有意选择了不同的权重来衡量浏览量和评论。如果在浏览/评论方面保持相等的权重可能会出现一个问题,即排名成为自我实现的预言——一个页面排名靠前,因此被访问得更频繁,从而获得更多的分数,所以它会显示在列表的顶部,再次被访问更频繁,并获得更多的分数……赋予评论更多的权重反映了这些评论需要真正的努力和展示了真正的兴趣。

上述公式将根据历史统计数据给出排名。因此,在最近一周内积累与另一篇文章相同数量的浏览量/评论的文章将被赋予相同的优先级。重复公式可能是有意义的,每次指定一个日期范围,并偏爱活动更高的页面,例如:

  0.3*(score for views/comments today) - live data
  0.3*(score for views/comments in the last week)
  0.25*(score for views/comments in the last month)
  0.15*(score for all views/comments, all time)
这将确保“热门”页面比最近没有太多活动的类似得分页面具有更高的优先级。除了今天的得分以外,所有值都可以由定期存储过程在表中持久化,这样数据库就不必聚合许多评论/查看统计数据。仅当天的统计数据是“实时”计算的。进一步地,排名公式本身可以通过每日运行的存储过程计算和存储历史数据。
编辑:要获得严格范围从0.1到1.0,您应该像这样修改公式。但我强调一点-这只会增加开销并且是不必要的-优先级的绝对值并不重要-只有它们相对于其他网址的相对值重要。搜索引擎使用它们来回答问题,即URL A是否比URL B更重要/相关?它通过比较它们的优先级-哪一个最大-而不是它们的绝对值来做到这一点。
// 未归一化-x是某个页面ID un(x) = 0.3 * log(views(x)+10) / log(10+maxViews()) + 0.7 * log(comments(x)+10) / log(10+maxComments()) // 原公式(现在为伪代码)
最大值将为1.0,最小值将从1.0开始向下移动,随着更多的查看/评论被进行。
我们将un(0)定义为最小值,即(在上述公式中,views(x)和comments(x)都为0)
要获得从0.1到1.0的归一化公式,然后计算n(x),页面x的归一化优先级。
                  (1.0-un(x)) * (un(0)-0.1)
  n(x) = un(x) -  -------------------------    when un(0) != 1.0
                          1.0-un(0)

       = 0.1 otherwise.

@Stacker - 排名的绝对值重要吗?我认为只有相对排序很重要 - 绝对值仅用于定义排序。我是否遗漏了什么? - mdma
将范围明确地设置为0..1有什么更完美的意义吗?无论范围如何,它都会产生相同的结果。您可以将所有优先级设置在0.99-1.00的范围内,只要它们是相对有序的,这才是最重要的。在站点地图中,最低值为0.1并不是必需的。 - mdma
日志的作用是,如果您有一个页面有百万次访问量,一个页面有1000次访问量,而另一个页面只有1次访问量,您不会得到像1、0.0001和0.0000001这样的优先级。它将压缩动态范围,变成类似于0.9、0.5、0.1之类的数值。排序仍将保持相同,但需要更少的精度数字。 - mdma
使用平均值不会对相对顺序产生任何影响,您只是改变了比较基准。我的原始公式是“这一页距离最高分数有多远”,而您建议的是“这一页距离平均分数有多远”。所有页面仍将按相同顺序排序。 - mdma
3
请尝试在实践中使用该公式。SO不是学习数学的地方。如果您发现两个页面的相关优先级不如您所希望的那样,那么我们可以研究一下,因为可能存在您没有提及的细节。否则,我认为这将能够完成您想要的工作。 - mdma
显示剩余11条评论

4
你需要的不是算法,而是公式。
不幸的是,你并没有具体说明你想要的细节,所以我们无法为你提供公式。
相反,让我们一起解决这个问题。
你有两个输入参数,即viewCount和commentCount。你想返回一个单一的数字Priority。到目前为止,一切都很好。
你说Priority应该在0和1之间变化,但这并不重要。如果我们想出了一个我们喜欢的公式,但结果在0和N之间,我们可以将结果除以N——因此这个约束条件并不是很相关。
现在,我们需要决定评论与浏览量的相对权重。
如果页面A有100条评论和10次浏览,而页面B有10条评论和100次浏览,哪个应该有更高的优先级?或者,应该有相同的优先级吗?你需要确定什么是你对Priority定义的正确性。
例如,如果你决定评论比浏览量有价值5倍,那么我们可以从以下公式开始:
 Priority = 5 * Comments + Views

显然,这可以推广到其他情况。
Priority = A * Comments + B * Views

其中A和B是相对权重。

但有时候我们希望我们的权重是指数级别而不是线性的,比如

 Priority = Comment ^ A + Views ^ B

这将会给出一个与之前公式非常不同的曲线。

同样地,

 Priority = Comment ^ A * Views ^ B

如果权重相等,一个有20个评论和20个浏览量的页面将比一个有1个评论和40个浏览量的页面获得更高的价值。

因此,总结一下:

你真的应该制作一个带有浏览量和评论样本值的电子表格,然后尝试各种公式,直到找到符合你期望分布的公式。

我们无法为您完成此操作,因为我们不知道您如何评估价值。


4

优先级 = W1 * 浏览量 / 所有文章最大浏览量 + W2 * 评论数 / 所有文章最大评论数 其中W1+W2=1

个人认为,可以直接使用0.5*log_10(10+浏览量)/log_10(10+最大浏览量) + 0.5*log_10(10+评论数)/log_10(10+最大评论数)


log_10 有什么用?为什么要将观看/评论数加上10?你能解释一下你的算法吗? - stacker
2
@stacker log10 的作用是将一个广泛的范围压缩到一个较小的范围内。例如,最大浏览量的页面排名第一,而浏览量少于 10 倍的页面排名远远低于 10 倍。当浏览量从几个到数十万个时,这通常非常有用。+10 是为了避免计算 log(0) - log(0) 未定义 - 有些人说它是负无穷 - 但无论如何,log(0) 在这里没有用处,因此该公式添加了一个常数以避免它。 - mdma
1
@stacker 这也是为了避免除以零的情况。Log(1)等于0,因此当没有maxViews时,你会得到一个除以零的错误。坚持使用10,这是最安全的选择,并且对最终结果几乎没有影响。 - mdma
@Stacker - 随着您的maxViews / maxComments增加,这将发生变化-公式是动态的。 - mdma
这是一个不错的算法,但仍有改进的空间。 - stacker
显示剩余4条评论

2
我知道这个问题已经被问了一段时间,但我遇到了类似的问题,并有了不同的解决方案。
当您想要对某些事物进行排名,并且有多个因素用于执行该排名时,您正在执行称为多标准决策分析(MCDA)的操作。请参见:http://en.wikipedia.org/wiki/Multi-criteria_decision_analysis 有几种处理此类问题的方法。在您的情况下,您的标准具有不同的“单位”。一个是评论单位,另一个是浏览量单位。此外,您可能根据您制定的任何业务规则赋予不同的权重。
在这种情况下,最好的解决方案是称为加权乘积模型的东西。请参见:http://en.wikipedia.org/wiki/Weighted_product_model 其要点是将每个标准转换为百分比(如先前建议的那样),然后将该百分比提高到X的幂,其中X是介于0和1之间的数字。此数字表示您的权重。您的总权重应该加起来为1。
最后,您将每个结果相乘以得出排名。如果排名大于1,则分子页面的排名高于分母页面。
每个页面都将通过执行以下操作与其他页面进行比较:
- p1C = 页面1的评论 - p1V = 页面1的浏览量 - p2C = 页面2的评论 - p2V = 页面2的浏览量 - wC = 评论权重 - wV = 浏览量权重
排名=(p1C / p2C)^(wC)*(p1V / p2V)^(wV)
最终结果是按其排名排序的页面列表。
我使用C#实现了这一点,通过对实现IComparable的对象集合进行排序。

1

有几位海报在没有概念上的澄清下,基本上提倡您使用线性回归来确定网页浏览量和评论计数的加权函数以建立优先级。

对于您的问题,这种技术非常容易实现,其基本概念在线性回归模型的维基百科文章中有很好的描述。

如何将其应用于您的问题的快速摘要是:

  1. 确定最适合所有站点网页的视图和评论计数数据的线条参数,即使用线性回归。
  2. 使用线条参数来推导您的视图/计数参数的优先级函数。

如果您不想从基本数学公式开始从头实现它(使用网络,数字配方等),则基本线性回归的代码示例不难跟踪。此外,任何通用数学软件包,如Matlab、R等,都带有线性回归函数。


0

最朴素的方法如下:

v[i]为页面i的浏览量,c[i]为页面i的评论数,则定义页面i的相对浏览权重为

r_v(i) = v[i]/(sum_j v[j])

其中sum_j v[j]是所有页面上v[.]的总和。同样地,定义页面i的相对评论权重为

r_c(i) = c[i]/(sum_j c[j]).

现在你想要一个常量参数 p:0

<

p < 1,它表示对评论的重要性。p = 0 表示只有评论是重要的,p = 1 表示只有观看次数是重要的,而 p = 0.5 则给予相等的权重。
然后将优先级设置为:
p*r_v(i) + (1-p)*r_c(i)

这可能过于简单化,但很可能是最好的起点。

我正在寻找更复杂的算法,可以给出绝对值。 - stacker
绝对值是什么意思?你能再解释一下吗? - Il-Bhima

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