Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OpenRank] 关于全域 OpenRank 实现细节的讨论 #337

Open
frank-zsy opened this issue Dec 8, 2023 · 6 comments
Open

[OpenRank] 关于全域 OpenRank 实现细节的讨论 #337

frank-zsy opened this issue Dec 8, 2023 · 6 comments

Comments

@frank-zsy
Copy link

目前的全域 OpenRank 中,为了避免出现单个账号通过刷高自己的活跃情况来给自己和项目刷分的情况,使用了如下的一些规则:

  • 新出现的仓库和用户节点的初值均为 1
  • 用户在仓库上的活跃度仅影响用户与仓库之间边的边权,而不影响任何节点的 OpenRank 值

上面的设定有一个非常好的特性就是单用户的高活跃度基本不会影响到结果,尤其是给自己的仓库大量自动化行为的这种情况是可以较好处理的,典型的就类似这个仓库,开发者用自己的账号每分钟在仓库上新建一个 Issue,但只要这个开发者不在其他仓库上活跃,这个仓库的 OpenRank 就不会很高。

然而虽然规避了账号高度活跃带来的刷分问题,但由于无差别对待新增的仓库和用户节点,会导致可以通过大量创建仓库和用户账号的方式来提升局部的价值总量。例如

  • 在 OpenDigger 中,2023.02 的 OpenRank 数据偏高,原因是 OSS101 课程打卡贴中带来大量的新同学,其实这些同学有不少是 GitHub 的新用户,或首次活跃的,但由于初值价值为 1 导致了当月 OpenDigger 的 OpenRank 值偏高,这是用户节点初值带来的问题。
  • 而在 openEuler 中,按目前的计算,openEuler 社区的 OpenRank 值遥遥领先,究其根本,是由于其组织中包含超过 1 万个仓库,由于仓库的初值为 1,导致其组织的局部 OpenRank 值极高,即便其活跃开发者数量只有 Paddle 的一半左右,但其 OpenRank 却是 Paddle 的两倍左右,这是仓库节点初值带来的问题。

鉴于上面两个例子,我希望可以再仔细讨论一下全域 OpenRank 的实现细节,尤其是节点初值和价值转移的设计,希望可以在规避用户刷分的同时,也可以避免大量的用户和大量的仓库导致的局部 OpenRank 值过高的问题。

欢迎大家提提想法。

@frank-zsy
Copy link
Author

我这里先提一个思路,这个问题中最本质的一个问题应该是:在一个价值网络中,其价值到底从何而来

就全域协作价值网络而言,本质上来说,价值是来源于开发者的开发劳动,而活跃度本质上就是想体现这个劳动量的。

所以可能的一种修改方法为:

  • 对所有节点的初始价值和当月转移价值进行分开处理,之前初值和当月转移价值是同一个值,但初值是继承历史的价值,当月转移的是当月活跃带来的新的价值,两个应该进行区分。
  • 新增仓库节点和新增用户的初值均为 0,因为新建一个仓库和账号没有带来实质的价值。
  • 仓库每月的转移价值都是 0,因为仓库本身是不产生价值的。
  • 用户每月的转移价值与该用户当月的活跃度相关,但这里是最具挑战性的一个点。虽然这个设定符合常识,但一旦使用活跃度作为转移价值,就会导致可能的刷分行为,包括无法精细化识别的自动化行为等。有一种可能的方案是根据活跃度分布进行非线性归一化,并且设定一个阈值防止自动化行为将上限拉的太高。

大家看看有没有什么其他的想法和建议。

@frank-zsy
Copy link
Author

给出另一种可行方案:

  • 新增仓库节点和新增用户节点的初始 OpenRank 均为 0。
  • 用户节点在计算时,初始值除继承上个月的数值外,额外增加一个由当月活跃度带来的劳动价值。
  • 仓库节点初始值仅继承上月数值,不额外增加新的数值。

用户节点的劳动价值计算方法为:min(1, log(activity + 1) / 5),会得到一个 0-1 之间的值。

这个算法的原因是活跃度本身具有幂律分布属性,先求一次对数,之后通过统计发现几乎都落在了 0 - 5 之间,除以 5 后在 0 - 1 之间,同时给出一个最大的上限是 1,目前按历史数据,除去机器人账号,自然人账号可以达到的峰值在 1.1 左右,因此感觉是可以接受的。

这样对整个价值网络解释为:

  • 价值网络中的所有价值均来自于每月的开发者活跃,没有其他任何的价值来源,因此单纯增加仓库或开发者数量无法带来局部价值提升。
  • 仓库节点不会创造价值,但会通过开发者的活跃产生价值,并且直接价值是可积累的。
  • 用户节点通过每月的活跃来创造价值,这个价值最终部分到仓库上,部分留在自身。次月时初始价值会用自身残留价值加上当月的活跃价值。
  • 但当仓库和开发者不再活跃时,价值将持续有每月 85% 的衰减。

@frank-zsy
Copy link
Author

目前暂将使用上述方法进行全域 OpenRank 计算,计算逻辑将放在 OpenDigger 的 global_openrank 定时任务中。

上述方法下得到的计算结果与现有结果相近,头部仓库与开发者排名相似,但包含了如下一些特点:

  • 网络价值来源于开发者活跃,而非新增仓库和新增开发者账号,故大量新建仓库和新建账号不会导致局部价值提升。
  • 开发者节点的总价值是逐渐积累的,大量新账号进入仓库的活跃不会导致仓库有明显的变化。
  • 开发者节点每月的新增加值与活跃程度有关,按照目前真实数据,大部分开源开发者将落在 0.5-0.7 区间内,少量可达 1,因此需要及时剔除自动化机器人账号。
  • 由于价值网络的价值来源于网络中所有仓库上活跃的开发者的活跃度,因此局部采样网络与全域网络结果非常相近。根据全域计算获取 OpenRank 头部 70 万个仓库重新计算全域 OpenRank,头部仓库排名几乎一致,数值也非常相近,采样网络的仓库 OpenRank 值略高于完整网络,比例约 2% 左右。原因是活跃度取对数使得活跃度具有边际效益递减效应,因此长尾仓库会较强的吸收开发者的 OpenRank,从而使得头部仓库的 OpenRank 偏低。而这也意味着我们可以直接使用 GitHub 和 Gitee 的融合网络来计算全域 OpenRank,且两个平台上的项目是可以横向对比的。如果后续增加多平台的开发者账号对应关系,使不同平台的同一开发者可以共用同一节点,则平台采样的影响会更小。

2023.11 月开始数据将使用上述方法,结果在 global_openrank 表中,原方式(新增节点初值为 1)结果将放在 global_openrank_legacy 表中、头部 70 万仓库数据将放在 global_openrank_subset 表中供后续进一步精细化分析。

@bifenglin
Copy link
Contributor

价值本身是一个很主观的评判,但是不妨碍我们使用数据科学的方法让这个主观的评判具备一定的依据。全域的github仓库类别很不一致,有一些是以协作为主的仓库,类似dio-lab-open-source , 大多数仓库是以代码为主。
为此我想可以更加细粒度的进行价值评判,全域用一种算法我认为是很难说服人的。
我认为可以对仓库类型进行挖掘,来更好的更细致化的使用openrank算法,从而提出一个OpenNetworkRank,可以根据以下维度:

  • 活动性: 根据仓库的活跃程度进行分类。这可以通过提交频率、发布频率、问题和拉取请求的数量及其响应时间来衡量。

  • 贡献者数量: 将仓库按照贡献者的数量分类。这不仅包括主要维护者,还包括偶尔的贡献者。

  • 仓库大小: 根据仓库的大小进行分类,这可以通过代码行数、文件数量或提交历史的长度来衡量。

  • 编程语言: 根据仓库中主要使用的编程语言进行分类。

  • 许可证类型: 按照仓库使用的开源许可证进行分类,例如 MIT、GPL、Apache 等。

  • 项目状态: 将仓库分类为活跃、维护中、过时或废弃等状态。

  • 社区参与度: 根据社区参与度进行分类,例如通过星标、观察者数量、分支数量和讨论的活跃程度来衡量。

  • 应用领域: 根据仓库所涉及的应用领域或行业进行分类,如数据科学、游戏开发、Web 开发等。

  • 依赖关系: 分析仓库依赖的其他库或项目,将其按照依赖复杂性分类。

  • 项目结构: 根据项目的结构和架构进行分类,例如单体应用、微服务、库或框架等。

然后不同的类型,我们定制一套openrank算法,再根据leaderrank算法或者其他网络算法进行结合,将不同社区再链接起来最终形成全域,这样是不是说服力更高一些?

@bifenglin
Copy link
Contributor

给出另一种可行方案:

  • 新增仓库节点和新增用户节点的初始 OpenRank 均为 0。
  • 用户节点在计算时,初始值除继承上个月的数值外,额外增加一个由当月活跃度带来的劳动价值。
  • 仓库节点初始值仅继承上月数值,不额外增加新的数值。

用户节点的劳动价值计算方法为:min(1, log(activity + 1) / 5),会得到一个 0-1 之间的值。

这个算法的原因是活跃度本身具有幂律分布属性,先求一次对数,之后通过统计发现几乎都落在了 0 - 5 之间,除以 5 后在 0 - 1 之间,同时给出一个最大的上限是 1,目前按历史数据,除去机器人账号,自然人账号可以达到的峰值在 1.1 左右,因此感觉是可以接受的。

这样对整个价值网络解释为:

  • 价值网络中的所有价值均来自于每月的开发者活跃,没有其他任何的价值来源,因此单纯增加仓库或开发者数量无法带来局部价值提升。
  • 仓库节点不会创造价值,但会通过开发者的活跃产生价值,并且直接价值是可积累的。
  • 用户节点通过每月的活跃来创造价值,这个价值最终部分到仓库上,部分留在自身。次月时初始价值会用自身残留价值加上当月的活跃价值。
  • 但当仓库和开发者不再活跃时,价值将持续有每月 85% 的衰减。

我看主要是对开发者初值进行设计,min(1, log(activity + 1) / 5) 为何不变成 min(1, log(activity + 1)/ max(log(activity))?第二个就是初值计算,那么继承的上个月的值是上个月初值的值还是上个月计算后的值?

@frank-zsy
Copy link
Author

我看主要是对开发者初值进行设计,min(1, log(activity + 1) / 5) 为何不变成 min(1, log(activity + 1)/ max(log(activity))?第二个就是初值计算,那么继承的上个月的值是上个月初值的值还是上个月计算后的值?

1、 这里其实是针对自然人可活跃上限还是做了一个人为的限定,在目前这种设计下,开发者的每月 OpenRank 增量取决于活跃度,因此保证账号是自然人非常重要。目前虽然我们尽可能剔除了机器人账号,但不排除未来可能出现新的机器人账号的情况,此时如果我们没有及时排除这个自动化账号,同时又没有给定一个上限,则可能导致该账号将上限拉高,从而导致自然人开发者的整体增量被压缩,这显然是不合理的。这里上限为 5,则表示开发者每月 OpenRank 增量的活跃度上限是 148 左右,这是一个相对合理的数字,当超过这个活跃度时,我们就不再增加其增量,也符合经济学中的边际效益递减理论。

2、继承的是上个月计算后的值,这样才能保证整个网络中的总体价值是全部是活跃度带来的,如果继承上个月的初值则是讲不通的,因为其实这个初值的一部分已经传递到了其他仓库节点上。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants