具体实施方式
为了更好的理解上述技术方案,下面通过附图以及具体实施例对本说明书实施例的技术方案做详细的说明,应当理解本说明书实施例以及实施例中的具体特征是对本说明书实施例技术方案的详细的说明,而不是对本说明书技术方案的限定,在不冲突的情况下,本说明书实施例以及实施例中的技术特征可以相互组合。
请参见图1,为本说明书实施例的社区动态调整应用场景示意图。终端100位于用户侧,与网络侧的服务器200通信。用户可通过终端100中的APP或网站产生实时事件。服务器200收集各个终端产生的实时事件,构建实时社区构图,并基于实时事件进行动态社区调整。本说明书实施例可应用于交易异常识别和犯罪团伙识别等风控场景,也可应用于好友推荐、兴趣物品推荐等场景。
首先,对本说明书实施例中的相关概念进行解释。
图(Graph):点集合和边集合(Edge Set&Node Set),边集合中的每一条边都有唯一的出发点、唯一的到达点。出发点和到达点都是该图点集合的成员。
有权图(Weighted Graph):是一种每条边都带有权重的图。
社区发现(Community Detection):将图的点集合划分为若干个子集,所有子集之和为该图的点集,而每一个点都唯一属于一个子集。这样的子集被称为社区。
动态图(Dynamic Graph):是一种点集合和边集合随时间发生变化的图。对于某一张特定的图来说,当前的时间的点集合、边集合相较于过去任一时间来说,其成员可能发生改变。这种改变是可以是以下一种或者多种的组合:点集合中的点发生增删、边集合的边发生增删以及边集合的权重发生改变。
第一方面,本说明书实施例提供一种社区动态调整方法,请参考图2,包括步骤S201-S203。
S201:在获得实时事件时,获得从上一次采用增量调整模式进行社区调整的第一开始时刻和上一次采用全量调整模式进行社区调整的第二开始时刻;
S202:确定从第一开始时刻至当前时刻期间累计的第一相关信息以及从第二开始时刻至当前时刻期间累计的第二相关信息;
S203:如果第一相关信息满足第一预设条件,采用增量调整模式进行社区调整,如果第二相关信息满足第二预设条件,采用全量调整模式进行社区调整。
进一步,在执行本实施例中的方法之前,需要进行全量初始化,全量初始化可通过如下步骤实现:获取预定时间段内的历史事件,基于历史事件,按预设构图方法确定初始社区构图,采用第一预设社区发现算法对初始社区构图中的节点进行社区划分,其中,初始社区构图中每个节点对应有该节点所属的社区标签。
具体的,在本实施例中,首先获取预定时间段内的历史事件,预设时间段可以预先指定,比如:在进行全局初始化时刻之前的10天、20天或30天内的历史事件。对于事件描述,本实施例并不限制历史事件的格式,在具体实施过程中,在不同的应用场景历史事件的格式是可以不一样的。但为了方便描述,历史事件一般可以抽象为如下表1所示:
表1各种场景下的历史事件
主体ID |
客体ID |
事件时间 |
事件类型 |
事件属性 |
成功与否 |
用户1 |
商品1 |
2016/2/1 |
购买 |
金额299 |
成功 |
用户1 |
IP1,设备1 |
2016/1/1 |
登录 |
- |
失败 |
银行卡1 |
用户2 |
2015/10/3 |
转账/充值 |
金额:500 |
成功 |
其中,主体ID逻辑上是事件的发起方,客体ID逻辑上是事件的承受方。主体ID、客体ID都可以是多个ID。例如在电商场景中主体ID可以是用户ID,客体ID可以是商品ID,表1的第一行是描述购买事件的例子。如果某个用户在某一个设备或者IP上登录可以描述为表1第二行的样子。如果某一银行卡向某一个用户转账可以描述为表1第三行的样子。
进而,在获得到历史事件后,按照预设构图方法对获得的历史事件进行构图,得到初始社区构图。预设构图方法需要定义以下各个内容:1、以什么作为点。2、满足什么样的条件则在点和点之间建立边。3、按照一定的算法计算出每一条边的权重值。
本实施例也不限制具体的构图规则。不同的场景、不同实现中可以采用不同的构图规则。对于上述表1中第一行的例子,其预设构图方法可以是:以用户为点,若在半年内两个用户都购买过两个以上相同的商品,则将两个用户连接起来,边的权重可以是两个用户购买过相同商品的个数,也可以是各种User-CF算法中的用户相似度。
对于上述表1中第一行的例子,还可以是:以用户和商品为点,若用户在一年之内成功购买过这个商品则将用户和该商品连接起来,边权重的值是当前时刻与用户最近一次购买该商品的时间差的倒数。
对于上述表1中第二行的例子,其预设构图方法可以是:以用户、设备、IP为点,若用户成功登陆,则将这笔登陆事件中涉及的用户、设备、IP两两连接起来,边权重可以是登录的次数,也可以是将时间考虑进去的更复杂的形式。
对于上述表1中第三行的例子,其预设构图方法可以是:以用户、银行卡为点,若发生过成功的转账/充值则将该用户和该银行卡连接起来,其权重可以是历史上所有转账金额之和,也可以是将时间考虑进去的更复杂的形式。
由此可以定义一个点(点i)和另一个点(点j)之间的权重可以写成定义为:wi,j(t)=f(Ei(t),Ej(t),t),其中,Ei(t)和Ej(t)是反生在时间t之前涉及到点i和点j的所有事件。对于一部分情况,点i和点j之间的权重只涉及点i和点j共同参与的事件,边的权重退化为:wi,j(t)=f(Eij(t),t),其中,Eij(t)表示在时间t之前同时涉及到点i和点j的所有事件。对于某些并没有把时间因素考虑进去的情况,边的权重退化为:wi,j(t)=f(Eij(t)),在这种情况下,若[t,t+Δτ)这段时间段内,没有同时涉及到点i和点j的事件发生,则可以得到wij(t+Δτ)=wij(t)。
在基于历史事件完成初始社区构图后,可以采用第一预设社区发现算法对初始社区构图中的节点进行社区划分,其中,初始社区构图中每个节点对应有该节点所属的社区标签。
具体的,在本实施例中,针对上述构建的初始社区构图上给运行一个或多个第一预设社区发现算法,这样,每一个点得到一个该节点所属社区的社区标签。第一预设社区发现方法可以是标签传播算法(LPA,Label Propagation Algorithm),可以是快速折叠算法(FU,Fast Unfolding),可以是JME算法(Join Merge Exchange)。
其中,标签传播算法流程简述如下:
Step1:图上的每一个点都以自己点id作为自己的标签;
Step2:每一个点都从自己的邻居那获取各邻居标签;
Step3:每一个点收到来自所有邻居的标签之后,将收到标签中出现最多的作为自己的标签(如果有权图则是权重和最高的那个)。如果出现标签数相同多的标签,则在这些出现最多的标签中任选一个作为自己的标签;
Step4:将每个点上的标签作为自己的社区标签输出。
其中,快速折叠算法流程简述如下:
Step1:图上的每一个点都以自己作为社区;
Step2:对于图的每一个点串行逐个的计算模块度增益,其中,模块度增益指的是:一个点有p个邻居节点,每一个邻居节点都唯一属于一个社区,这个节点的p个邻居节点属于q个社区。显然q<=p。对于q个社区中的每一个社区c,都计算该点脱离该点现在的社区,加入c社区所带来的模块度增量;从而得到了q个模块度增量。取这q个模块度增量中最大的作为该点的模块度增益,而该点模块度增量对应的社区为该点的目标社区。如果该点的模块度增益大于0,则该点脱离当前社区,加入目标社区;
Step3:重复Step2直到所有点都不发生变化;
Step4:将Step3得到的每一个社区当成点,重复Step2直到所有社区不发生变化;
Step5:将每个点上的标签作为自己的社区标签输出。
在通过初始社区构图得到初始社区划分后,在每次接收到实时事件时,均会对社区构图进行实时调整。所以,在每次接收到实时事件时,基于本次接收到的实时事件,对上一次实时社区构图进行调整,得到本次实时社区构图,其中,在第一次接收到实时事件时,基于第一次接收到的实时事件,对初始社区构图进行实时调整,得到第一次实时社区构图。其中,基于本次接收到的实时事件,对上一次实时社区构图进行调整,得到本次实时社区构图,具体通过如下步骤实现:确定本次接收到的实时事件涉及的点边信息;基于点边信息,根据预设构图方法对上一次实时社区构图进行点边的增改,得到本次实时社区构图。
具体的,在本实施例中,获得实时事件之后,查询该实时事件所涉及到的点边信息,根据预设构图方法更新点边,同前述描述,本实施例并不限制预设构图方法。一般来说,但预设构图方法有以下特性:1、有新的边出现则在构图上增加这条新的边。2、有新的点出现则在构图上增加新的点。3、若是构图中涉及一条已有的边,则判断这条边的权重是否需要修改。同样的,实时更新社区构图采用预设构图方法也是包括以下三个主要内容:1、以什么作为点。2、满足什么样的条件则在点和点之间建立边。3、按照一定的算法计算出每一条边的权重值。一般来说,在同样的场景中,实时更新采用的构图规则的和全量初始化采用的构图规则是一致的。
这里以用户的登录事件为例,来描述一下如何依据历史事件和实时事件进行构图更新。例如在这种场景中用户采用的预设构图方法为:以用户、设备、IP为点,若用户成功登陆,则将这笔登陆事件中涉及的用户、设备、IP两两连接起来,边权重为当前时刻减去事件时间的天数加1的倒数之和,即:
其中,Eij(t)表示在时间t之前同时涉及到点i和点j的所有事件,dt是当前时刻所对应的天数,dx是事件x发生时间对应的天数。表2为历史事件的一个例子,例子中只涉及User1和User2两个用户的行为。按照上面描述的预设构图方法得到图1中的构图。
表2登录场景下的历史事件
主体ID |
客体ID |
事件时间 |
事件类型 |
事件属性 |
成功与否 |
User1 |
Ip1/Device1 |
2018/5/26 |
登录 |
- |
成功 |
User1 |
Ip2/Device2 |
2018/5/27 |
登录 |
- |
成功 |
User1 |
Ip1/Device2 |
2018/5/29 |
登录 |
- |
失败 |
User1 |
Ip2/Device2 |
2018/5/29 |
登录 |
- |
成功 |
User1 |
Ip2/Device2 |
2018/5/29 |
登录 |
- |
成功 |
User2 |
Ip3/Device3 |
2018/5/29 |
登录 |
- |
失败 |
User2 |
Ip3/- |
2018/5/29 |
登录 |
- |
成功 |
具体地,应该加入点为:User1、Ip1、Device1、Ip2、Device2、User2、Ip3,后文中简称为U1、I1、D1、I2、D2、U2、I3。应该加入的边为:U1-I1、U1-D1、I1-D1、U1-I2、U1-D2、I2-D2、U2-I3。假设是在2018年5月30日运行这个全量初始化的,那么这七条边的权重分别为:
表3为2018年5月30日增量事件的例子,例子中只涉及到User1和User2的两个用户的行为。
表3登录场景下的增量事件
主体ID |
客体ID |
事件时间 |
事件类型 |
事件属性 |
成功与否 |
User1 |
Ip1/Device2 |
2018/5/30 |
登录 |
- |
成功 |
User2 |
Ip3/Device3 |
2018/5/30 |
登录 |
- |
成功 |
处理表3中的第1条事件的时候,首先在构图中查询User1、Ip1、Device2相关的点边。发现User1、Ip1、Device2这3个点都存在,因此不需要添加新的点。而User1-Ip1这条边已经存在,所以不需添加这条新边,但是由于这笔新的事件边权重却需要调整。边权重应该被调整成如下:
而User1-Device2这条边已经存在,所以不需添加这条新边,但是由于这笔新的事件边权重却需要调整。边权重应该被调整成如下:
由此可见,在这种预设构图方法下,边的新权重等于老权重加上增量值,没有必要获取相关点的所有历史事件重新计算的。即在这种预设构图方法下有如下的特性:
wi,j(t2)=wi,j(t1)+Δwi,j(t1,t2)
这种特性是有利于增量计算的,不同的预设构图方法有不同的特性,不同的实现中可以平衡计算量和业务效果,来设计预设构图方法。而Ip1-Device2这条边不存在,因此将这条边加上,经计算这条边的权重为1。此时构图变为图4中的样子。
处理表3中的第2条事件的时候,首先在构图中查询User2、Ip3、Device3相关的点边。发现User2、Ip3这2个点都存在,因此需要添加新点:Device3。而User2-Ip3这条边已经存在,所以不需添加这条新边,但是由于这笔新的事件边权重却需要调整。边权重应该被调整成如下:
而User2-Device3、Ip3-Device3这两条边并不存在,因此添加这两条边,经计算这两条边的权重都为1。此时构图变为图5中的样子。
其中,在图3-图5中,图3是构图全量初始化之后的初始社区构图,图4是消费第一条消息的实时社区构图,虚线的边为新加的边,圈中的值为调整后的边权重。图5是消费第二条消息的例子,虚线的边为新加的边,圈中的值为调整后的边权重。
进而,在每次获得实时事件后,均需要按前述方式对社区构图进行更新,得到本次对应的实时社区构图。进而,在每次获得实时事件时,均需要确定是否对社区进行动态调整。若需要调整,则判断是用增量调整模式,还是用全量调整模式。这种判断逻辑是每过一段时间,或者每消费一定数目的实时事件,则触发一次。
在确定上一次的社区调整是否完毕后,由于在每次进行社区调整时,均会记录调整开始时刻。所以,在判断是否需要对社区进行动态调整时,首先通过步骤S201获得从上一次采用增量调整模式进行社区调整的第一开始时刻,以及上一次采用全量调整模式进行社区调整的第二开始时刻。进而通过步骤S202获得第一开始时刻至当前时刻的时间段内累计的第一相关信息,获得第二开始时刻至当前时刻的时间段内累计的第二相关信息。其中,第一相关信息包括从第一开始时刻至当前时刻期间累计经过的第一时长或累计的实时事件对应的新增节点的第一数量;以及确定第二相关信息包括从第二开始时刻至当前时刻期间累计经过的第二时长或累计的实时事件对应的改动边的第一数量。
然后通过步骤S203确定是否进行社区调整以及采用哪种模式进行调整。具体的,如果第一时长达到第一预设时长T1或第一数量达到第一预设数值P1,确定第一相关信息满足第一预设条件,采用增量调整模式进行社区调整。如果第二时长达到第二预设时长T2或第二数量达到第二预设数值P2,确定第二相关信息满足第二预设条件,采用全量调整模式进行社区调整,其中,T1<T2且P1<P2。
具体的,在本实施例中,关于T1、T2、P1、P2的设置,不同的数值将带来不同的特性,这里举几个例子来说明。例如:如果P1、P2都设置为0,T1设置为10分钟,T2设置为1天,就意味着每天做一次全量调整,每10分钟做一次增量调整。又如:如果P2、T1设置为0,T2设置为6个小时,P1设置为1000,就意味着每6个小时做一次全量调整,每加入1000个节点做一次增量调整。又如:T1、T2设置为0,而P1、P2大于0,就意味着每增改P2个改动边则做一次全量调整,每新增P1个新增节点则做一次增量调整。T1、T2、P1、P2这四个阈值的选取和场景、预设构图方法、以及需求有关,在改系统运行时用户也可以动态调整这四个参数。一般来说,这四个参数越小,则触发社区调整次数越多、社区划分越实时。这四个参数越大,则触发社区调整次数越少、社区划分更新地越慢。在具体实施过程中,可根据实际需要进行设定,在此,本申请不做限制。本实施例中的方法,提供给用户若干个可动态调整的参数。这些参数可帮助用户平衡本实施例中的方法的计算消耗,和本实施例中的方法的实时性。
进一步,在本实施例中,采用增量调整模式进行社区调整时,是基于本次实时社区构图来进行社区调整,具体的,可通过如下步骤实现:
确定距当前时刻最接近的一次的社区调整的第三开始时刻,获得从第三开始时刻至当前时刻期间新增的节点,将每个新增的节点标记为第一活性节点,将本次实时社区构图中除新增的节点之外的其余节点标记为第一惰性节点,其中,第三开始时刻为第一开始时刻或第二开始时刻;
基于第一惰性节点的所属的社区标签以及本次实时社区构图,采用第二预设社区发现算法对第一活性节点进行社区划分,确定每个第一活性节点所属的社区标签。
具体的,在本实施例中,首先,将距当前时刻最接近的一次的社区调整(可以是增量调整模式也可以是全量调整模式进行的社区调整)开始到这一次社区调整开始之间新加入的点标记为活性节点。其余节点不标记,被默认为惰性节点。然后,将每一个活性节点的社区标签标记为自己的点ID。惰性节点不做操作,仍然保持为原有社区标签。接着,在这些活性点上跑一个第二预设社区发现算法,此时只有活性点参与算法流程,而惰性点可以提供算法所需的信息,也可以被动的参与计算。第二预设社区发现算法可以是前述部分的标签传播算法、快速折叠算法或者JME算法,当然,还可以是其它社区发现算法,在此,本申请不做限制。
举例来说,这个第二预设社区发现算法是标签传播算法,则具体的算法运行步骤为:
步骤3.a:每个活性点从自己的邻居中获得社区标签。
步骤3.b:每个活性点收到来自所有邻居节点的社区标签之后,将收到社区标签中出现最多次的社区标签作为该节点的社区标签,如果本次实时社区构图为有权图,则是权重和最高的那个邻近节点的社区标签作为该节点的社区标签。如果出现社区标签次数最多次数相同,则在这些出现最多的社区标签中任选一个作为该节点的社区标签。
步骤3.c:重复3.a、3.b若干轮,若干轮之后,每个活性点都得到自己新的社区标签。
举例来说,第二预设社区发现算法是JME算法,则该算法具体执行包括如下步骤:
JME算法主要分为三个部分。这三个部分的迭代循环执行的最大轮数分别为R1、R2、R3,这三个部分中的节点可以分P1、P2、P3个批次参与执行。R1、R2、R3、P1、P2、P3都可以预先指定,一般满足如下条件即可:R1、R2、R3、P1、P2、P3均为正整数,且R1是P1的整数倍,R2是P2的整数倍,R3是P3的整数倍。
步骤0:轮数设为0。进入步骤1。
步骤1:若当前轮数大于等于R1,对于本次实时构图中每个所属社区的成员数不大于1个且邻居节点集合不为空的节点,在社区关系图中建立一个节点ID为该节点的社区ID的节点,并且将社区关系图中该节点的成员集合中加入本次实时构图中该节点的节点ID。进入步骤4。否则,对于本次实时构图中每个满足条件的节点n,对于该节点邻居社区集合中的除自己所属社区的每个社区,计算节点n到该社区的模块度增量,得到若干个模块度增量。假定将其中最大的模块度增量称为该节点n的模块度增益,最大的模块度增量对应的社区为节点n的目标社区。若节点n的邻居社区集合中的多个社区的模块度增益同时最大,则目标社区可以选择这多个社区中的任意一个。若节点n的模块度增益大于0,则向目标社区对应的节点发出加入请求,进入步骤2。其中,该“满足条件”指:该节点所属社区的成员数不大于1个,且该节点ID对P1取模等于轮数对P1取模。
步骤2:对于本次实时构图中每个收到加入请求的节点,按照一定方式判断是否同意收到的请求。若该节点同意了任何一个收到的加入请求,且社区关系图中没有以该节点的社区ID作为节点ID的节点,则在社区关系图中创建一个节点ID为该节点的社区ID的节点(假定称为节点l),并且将该节点的节点ID加入到节点l的成员集合中。进入步骤3。
其中,该“一定方式”指:对于每个接收到加入请求的节点,若该节点在上一步骤中没有发出过加入请求,则同意所有发至该节点的加入请求。否则,在所有的接收到的加入请求中,同意满足一定条件的请求,拒绝不满足该一定条件的加入请求。若在所有的接收到的加入请求中,没有满足该一定条件的,则拒绝所有收到的加入请求。对于该节点收到的每个加入请求,若同意该加入请求,则向提出该加入请求的节点发送同意消息。该“一定条件”指的:发送加入请求的节点所属社区和自己目标社区一致,且发送加入请求的节点的点度数小于该节点的点度数或者发送加入请求的节点的点度数等于该节点的点度数,且发送加入请求节点的节点ID大于该节点的节点ID。
步骤3:对于本次实时构图中每个收到同意消息的节点,将该节点的社区ID设置为该节点的目标社区。并且在社区关系图中节点ID为目标社区的节点的成员集合中加上该节点的节点ID,轮数加1,返回步骤1。
步骤4:删除社区关系图中成员集合为空的节点。对于社区关系图中每个成员集合不为空的节点,按照一定方式进行计算并且根据计算结果在社区关系图中添加边。将轮数置0,进入步骤5。其中,该“一定方式”指:对于社区关系图中任意一个节点,创建一个空的邻居权重表。遍历其成员集合,对于成员集合中的每一个ID,找到本次实时构图中节点ID和这个ID相同的节点(称作成员节点)。对于每个成员节点遍历其邻居节点集合。对于该成员节点的每个邻居节点,拿到该邻居节点的社区ID,查看邻居权重表中是否存在该社区ID。若不存在则在邻居权重表插入一条以该社区ID为键,以相关边的边权重为值的一条记录。否则,找到邻居权重表中键为该社区ID的记录,将这条记录的值加上相关边的边权重。该相关边的边权重指:本次实时构图中以该成员节点为起始节点、该邻居节点为终节点的边的边权重之和。对于社区关系图中任意一个邻居权重表不为空的节点,遍历其邻居权重表。对于邻居权重表上的每条记录,拿出该记录的键和值。创建一条以该节点为起始节点、节点ID和该记录的键一样的节点为终节点、边权重为该记录的值的边。对于社区关系图中的任意节点删除邻居权重表。
步骤5:若轮数不小于P2且在最近的P2轮中没有任何节点成功合并,结束算法。若轮数不小于R2,则进入步骤8。否则,对于社区关系图中每个满足条件的节点n,对于该节点邻居社区集合中的除自己以外的每个节点,计算节点n和该节点的模块度增量,得到若干个社区模块度增量。其中,最大的社区模块度增量称为该节点的社区模块度增益,最大的社区模块度增量对应的节点为该节点的最优合并点。若该节点的邻居节点集合中的多个节点的社区模块度增益同时最大,则最优合并点是这多个节点中的任意一个。若该节点社区模块度增益大于0,则向最优合并点发出合并请求。进入步骤6。其中,该“满足条件”指:该节点的节点ID的整数部分对P2取模等于轮数对P2取模。比如,节点ID为C50,则该节点ID的整数部分为50。
步骤6:对于社区关系图中每个收到合并请求的节点,按照一定方式判断是否同意收到的合并请求。若同意某个合并请求,则向该合并请求的发起节点发送同意合并消息。进入步骤7。其中,该“一定方式”指:对于任意一个收到合并请求的节点,若该节点在上一步骤中没有发出过合并请求,则遍历收到的全部合并请求。计算该节点到每个对该节点发出合并请求的节点的社区模块度增量,得到一组社区模块度增量。选取其中最大的社区模块度增量所对应的合并请求,同意该合并请求,拒绝其他的合并请求(若收到的合并请求中的多个节点的社区模块度增益同时最大,则选择其中任意一个)。否则,在接收到的所有合并请求中,同意满足一定条件的合并请求,拒绝不满足该一定条件的合并请求。若在接收到的所有合并请求中,没有满足该一定条件的,则拒绝接收到的所有合并请求。其中,该“一定条件”指:发送合并请求的节点和该节点的最优合并点区一致且发送合并请求的节点的点度数小于该节点的点度数,或者发送合并请求的节点的点度数等于该节点的点度数,且发送合并请求节点的节点ID的整数部分大于该节点的节点ID的整数部分。
步骤7:对于社区关系图中每个收到同意合并消息的节点:往最优合并点5的成员集合中加入自己成员集合全部的元素。遍历以自己为起始节点的每条边,获得该边的边权重(假定称为权重w)和终节点(假定称为节点m)。若节点m不是该节点的最优合并点的邻居节点,则创建一条起始节点为最优合并点、终节点为节点m、边权重为权重w的边。否则将权重w加到起始节点为最优合并点、终节点为节点m的这条边上。遍历以自己为终节点的每条非自环边。获得该边的边权重(假定称为权重v)和终节点(假定称为节点n)。若不存在一条起始节点为节点n、终节点为最优合并点的边,则创建一条这样的边,并且使得该边权重为权重v。否则,将起始节点为节点n、终节点为最优合并点的边的边权重加上权重v。最后在社区关系图中删除该节点,以及以删除该节点为起始节点或者终节点的所有边,轮数加1,返回步骤5。
步骤8:对于社区关系图中每个节点,遍历其成员集合。对于社区关系图上的任意一个节点(假定称为节点c)的成员集合中的任意一个元素,找到原始图中节点ID和该元素相等的节点,将该节点的社区ID改成节点c的节点ID。删除社区关系图中全部的边,将轮数置0,进入步骤9。
步骤9:若轮数不小于P3且在最近的P3轮中没有任何节点发生社区变更,或者轮数不小于R3,则返回步骤4。否则,对于本次实时构图中每个点计算并记录其模块度增益以及相应的目标社区。计算该节点的已有增益。若该节点的已有增益不小于该节点的模块度增益,则将该节点标记为最优划分点,进入步骤10。
步骤10:对于本次实时构图中满足一定条件的点,提出社区变更请求。进入步骤11。其中,该“一定条件”指:该节点未被标记为最优划分节点,且该节点ID对P3取模等于轮数对P3取模。
步骤11:对于本次实时构图中每个在上一步骤提出社区变更请求的节点,计算该节点的变更增益。若其变更增益大于该节点的已有增益,该节点变更社区。清除本次实时构图上所有最优划分点标记,轮数加1,返回步骤9。
其中,JME算法中的步骤1将只有活性点运行,步骤2、3照常。JME算法中的步骤4、8只有活性点、活性点所属社区以及活性点的邻接社区运行。步骤5只有活性点的所属社区运行,6、7两步照常。步骤9、10只有活性点运行,11、12两步照常。
以下是进一步解释,在该算法的第一部分中,只有活性点会计算目标社区并发起申请。在该算法的第二部分中,只有活性点的所属社区会计算最优合并点,并发出请求。在该算法的第三部分中,只有活性点会计算模块度增益、目标社区和已有增益,惰性点都默认为最优划分,也只有活性点才允许提出变更申请。在上述提到的三条中,发起申请的对象可以是活性点,也可以是惰性点。若接受到申请的是惰性点,则惰性点会按照原方法处理这个申请;因此说惰性点是被动参与计算。在步骤4、8中参与计算的惰性点,是和活性点同一社区的惰性点,或者是活性点邻居社区的惰性点。他们之所以参加了步骤4、8,是为了给这些活性点提供信息,例如:计算活性点所属社区的社区度数,邻居社区的社区度数。将只包括惰性点的社区称作为惰性社区。在生成社区关系图时,惰性社区和惰性社区之间的关系是不需要计算的。
其中,在增量调整模式进行社区调整的执行过程中,不会考虑实时事件对点、边的任何修改。执行过程中对点边的修改,会到增量调整模式进行社区调整执行结束之后才生效。
进一步,在本实施例中,采用全量调整模式进行社区调整时,是基于本次实时社区构图来进行社区调整,具体的,可通过如下步骤实现:
确定从第二开始时刻至当前时刻期间满足第三预设条件的第一边,对本次实时构图中除第一边之外的其余边进行权重更新,确定更新后的实时社区构图,将权重值更新后的边标记为已改动边;
确定更新后的实时社区构图中存在已改动边的目标社区,在目标社区满足第四预设条件时,将目标社区包含的节点标记为第二活性节点;
将更新后的实时社区构图中除第二活性节点之外的其余节点标记为第二惰性节点;
确定每个第二活性节点以各自为社区,每个第二惰性节点保持原有的社区标签,基于第二惰性节点的所属的社区标签以及更新后的实时社区构图,采用第三预设社区发现算法对第二活性节点进行社区划分,重新确定每个第二活性节点所属的社区标签。
其中,如果从第二开始时刻至当前时刻期间,本次实时构图中存在两个节点间累计发生的实时事件的数量为0,且两个节点间的边的权重值没有发生改变,确定两个节点间的边为满足第三预设条件的第一边。
其中,在目标社区满足第四预设条件时,将目标社区包含的节点标记为第二活性节点,包括:获取更新后的实时社区构图的第一度数;获取目标社区的第二度数;从目标社区中各边的权重值中确定出最小权重值;如果第一度数与最小权重值的乘积小于预设系数与第二度数平方的乘积,确定目标社区满足第四预设条件,将目标社区包含的节点标记为第二活性节点。
具体的,在本实施例中,首先,将距当前时刻最接近的一次的社区调整(可以是增量调整模式也可以是全量调整模式进行的社区调整)开始到这一次社区调整开始之间新加入的点标记为活性节点。进一步,对于本次实时社区构图上的每一条边,如果该边满足第三预设条件,表明该边不需要做修订,而对于本次实时构图中除满足第三预设条件的第一边之外的其余边,则可以基于历史事件重新计算该边的权重,若更新后的边权重小于预设的阈值h,则删除该边,否则将新的边权重生效,这样,就可以得到更新后的实时社区构图。
其中,第三预设条件指的是:在当Ei(t+Δτ)=Ei(t)且Ej(t+Δτ)=Ej(t)时,边权重随时间没有发生变化,即wij(t+Δτ)=wij(t)。对于某些构图方案可以退化为,当Eij(t+Δτ)=Eij(t)时,边权重随时间未发生变化。即那些如果没有新事件发生,边权重就不发生变化的边,其边权重是不需重新计算的。而不因实时事件发生,边权重发生变化的边需要重新计算权重,记为已改动边。
进而,对于所有存在已改动边的社区进行一次判断,若满足第四预设条件,则将该社区的所有点标记为活性点。第四预设条件指的是:mcDG<εDc 2,其中,DG表示更新后的实时社区构图的整张图的度数,Dc表示该社区的社区度数,mc为属于社区c的边中边权重最小的边的权重值,ε是一个用户预设的系数,一般情况下ε≥4。另外,若一条边的终点和起点同属于社区c,则这边也属于社区c。
进而,在确定完活性点后,将更新后的实时社区构图中剩下未标记为活性点的都标记为惰性点。每一个活性点都以各自为社区。而每一个惰性点都保持原有的社区标签。最后,在这些活性点上跑一个第三预设社区发现算法,此时只有活性点参与算法流程,而惰性点可以提供算法所需的信息,也可以被动的参与计算。第三预设社区发现算法可以是前述部分的标签传播算法、快速折叠算法或者JME算法,当然,还可以是其它社区发现算法,在此,本申请不做限制。在活性节点上运行第三预设社区发现算法的具体实施过程与增量模式中相同,可参见前述实施例部分的详细内容,在此,本申请不再赘述。
在全量调整模式调整社区执行过程中,不会考虑实时事件对点、边的任何修改。执行过程中对点边的修改,会到全量调整模式进行社区调整执行结束之后才生效。
本实施例中的方法所要解决的是动态图的社区划分问题。构图随着时间发生变化,因此社区划分要跟随着这种构图调整而调整。而真正工业应用当中,往往越到的是超大规模的图,而且图上的一部分边的边权重是时刻发生变化的。对于这种情况,本实施例中的方法能够依据历史事件完成构图初始化,依据实时事件完成构图实时修改,从而实现了动态图。而且每一次构图的修改都可能触发一次社区调整。
进一步,本实施例中的方法中所设计的增量调整模式是为了及时的给新加入的点分配社区标签。而且由于只有新增节点,和新增节点的邻居节点参与计算,因此运行一次的时间复杂度为O(Δm),其中Δm为新增节点涉及到的边数。
进一步,本实施例中的方法中的全量调整模式,重新计算了那些不是因新增事件而是因时间变化而变化的边权重。基于这种变化重新调整社区划分。而且运行一次的时间复杂度也为O(Δm),其中Δm为新增节点涉及到的边数。
本实施例中的方法,即可以及时的新增节点边、及时的修改边的权重、及时的给出新的社区划分,又可以将社区调整的时间复杂度降为O(Δm)。可以用于大规模、时变动态图的社区划分方案。
进一步,本实施例中的方法,将图上的点划分为“活性点”和“惰性点”,只有活性点参与算法流程,而惰性点可以提供算法所需的信息,也可以被动的参与计算。通过这种改造方案,可以把一个原有的社区发现算法改造为一个增量的社区发现算法。且这个增量社区发现算法的时间复杂度为O(Δm),其中Δm为活性点涉及到的边数,实现了时间复杂度低的技术效果。
第二方面,基于同一发明构思,本说明书实施例提供一种社区动态调整装置,请参考图6,包括:
获取单元601,用于在获得实时事件时,获得从上一次采用增量调整模式进行社区调整的第一开始时刻和上一次采用全量调整模式进行社区调整的第二开始时刻;
确定单元602,用于确定从所述第一开始时刻至当前时刻期间累计的第一相关信息以及从所述第二开始时刻至当前时刻期间累计的第二相关信息;
社区调整单元603,用于如果所述第一相关信息满足第一预设条件,采用所述增量调整模式进行社区调整,如果所述第二相关信息满足第二预设条件,采用所述全量调整模式进行社区调整。
在一种可选实现方式中,所述装置还包括构图单元,所述构图单元具体用于:
获取预定时间段内的历史事件,基于所述历史事件,按预设构图装置确定初始社区构图,采用第一预设社区发现算法对所述初始社区构图中的节点进行社区划分,其中,所述初始社区构图中每个节点对应有该节点所属的社区标签;
在每次接收到实时事件时,基于本次接收到的实时事件,对上一次实时社区构图进行调整,得到本次实时社区构图,其中,在第一次接收到实时事件时,基于所述第一次接收到的实时事件,对所述初始社区构图进行实时调整,得到第一次实时社区构图;
所述社区调整单元603具体用于:如果所述第一相关信息满足第一预设条件,基于所述本次实时社区构图,采用增量调整模式进行社区调整;
所述社区调整单元603具体用于:如果所述第二相关信息满足第二预设条件,基于所述本次实时社区构图,采用全量调整模式进行社区调整。
在一种可选实现方式中,所述确定单元602具体用于:确定所述第一相关信息包括从所述第一开始时刻至当前时刻期间累计经过的第一时长或累计的实时事件对应的新增节点的第一数量;以及确定所述第二相关信息包括从所述第二开始时刻至当前时刻期间累计经过的第二时长或累计的实时事件对应的改动边的第一数量。
在一种可选实现方式中,所述社区调整单元603具体用于:
如果所述第一时长达到第一预设时长或所述第一数量达到第一预设数值,确定所述第一相关信息满足第一预设条件,采用所述增量调整模式进行社区调整;
如果所述第二时长达到第二预设时长或所述第二数量达到第二预设数值,确定所述第二相关信息满足第二预设条件,采用所述全量调整模式进行社区调整,其中,所述第一预设时长小于所述第二预设时长,所述第一预设数值小于所述第二预设数值。
在一种可选实现方式中,所述构图单元具体用于:
确定所述本次接收到的实时事件涉及的点边信息;
基于所述点边信息,根据所述预设构图装置对上一次实时社区构图进行点边的增改,得到本次实时社区构图。
在一种可选实现方式中,所述社区调整单元603具体用于:
确定距当前时刻最接近的一次的社区调整的第三开始时刻,获得从所述第三开始时刻至当前时刻期间新增的节点,将所述每个新增的节点标记为第一活性节点,将所述本次实时社区构图中除所述新增的节点之外的其余节点标记为第一惰性节点,其中,所述第三开始时刻为所述第一开始时刻或所述第二开始时刻;
基于所述第一惰性节点的所属的社区标签以及所述本次实时社区构图,采用第二预设社区发现算法对所述第一活性节点进行社区划分,确定每个第一活性节点所属的社区标签。
在一种可选实现方式中,所述社区调整单元603具体用于:
确定距当前时刻最接近的一次的社区调整的第四开始时刻,获得从所述第四开始时刻至当前时刻期间新增的节点,将所述每个新增的节点标记为第二活性节点,其中,所述第四开始时刻为所述第一开始时刻或所述第二开始时刻;
确定从所述第二开始时刻至当前时刻期间满足第三预设条件的第一边,对所述本次实时构图中除所述第一边之外的其余边进行权重更新,确定更新后的实时社区构图,将权重值更新后的边标记为已改动边;
确定所述更新后的实时社区构图中存在所述已改动边的目标社区,在所述目标社区满足第四预设条件时,将所述目标社区包含的节点标记为所述第二活性节点;
将所述更新后的实时社区构图中除所述第二活性节点之外的其余节点标记为第二惰性节点;
确定每个所述第二活性节点以各自为社区,每个所述第二惰性节点保持原有的社区标签,基于所述第二惰性节点的所属的社区标签以及所述更新后的实时社区构图,采用第三预设社区发现算法对所述第二活性节点进行社区划分,重新确定每个第二活性节点所属的社区标签。
在一种可选实现方式中,所述社区调整单元603具体用于:如果从所述第二开始时刻至当前时刻期间,所述本次实时构图中存在两个节点间累计发生的实时事件的数量为0,且所述两个节点间的边的权重值没有发生改变,确定所述两个节点间的边为满足所述第三预设条件的第一边。
在一种可选实现方式中,所述社区调整单元603具体用于:
获取所述更新后的实时社区构图的第一度数;
获取所述目标社区的第二度数;
从所述目标社区中各边的权重值中确定出最小权重值;
如果所述第一度数与所述最小权重值的乘积小于预设系数与所述第二度数平方的乘积,确定所述目标社区满足第四预设条件,将所述目标社区包含的节点标记为所述第二活性节点。
第三方面,基于与前述实施例中社区动态调整方法同样的发明构思,本发明还提供一种服务器,如图7所示,包括存储器704、处理器702及存储在存储器704上并可在处理器702上运行的计算机程序,所述处理器702执行所述程序时实现前文所述社区动态调整方法的任一方法的步骤。
其中,在图7中,总线架构(用总线700来代表),总线700可以包括任意数量的互联的总线和桥,总线700将包括由处理器702代表的一个或多个处理器和存储器704代表的存储器的各种电路链接在一起。总线700还可以将诸如外围设备、稳压器和功率管理电路等之类的各种其他电路链接在一起,这些都是本领域所公知的,因此,本文不再对其进行进一步描述。总线接口706在总线700和接收器701和发送器703之间提供接口。接收器701和发送器703可以是同一个元件,即收发机,提供用于在传输介质上与各种其他装置通信的单元。处理器702负责管理总线700和通常的处理,而存储器704可以被用于存储处理器702在执行操作时所使用的数据。
第四方面,基于与前述实施例中社区动态调整的发明构思,本发明还提供一种计算机可读存储介质,其上存储有计算机程序,该程序被处理器执行时实现前文所述社区动态调整的方法的任一方法的步骤。
本说明书是参照根据本说明书实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的设备。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令设备的制造品,该指令设备实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
尽管已描述了本说明书的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例作出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本说明书范围的所有变更和修改。
显然,本领域的技术人员可以对本说明书进行各种改动和变型而不脱离本说明书的精神和范围。这样,倘若本说明书的这些修改和变型属于本说明书权利要求及其等同技术的范围之内,则本说明书也意图包含这些改动和变型在内。