基于机器学习聚类算法的门禁数据异常检测方法转让专利

申请号 : CN201611061709.8

文献号 : CN106528850B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 王爱华高峰利程涛

申请人 : 中通服公众信息产业股份有限公司

摘要 :

本发明涉及门禁技术领域,特别涉及一种基于机器学习聚类算法的门禁数据异常检测方法,步骤一,清洗社区门禁系统的刷卡记录数据;步骤二,对清洗后的数据进行特征提取;步骤三,基于机器学习的聚类算法,分析所提取的门禁记录特征,将所有数据点划分到具有不同异常度的类中。本发明的有益效果是:可以有效检测社区进出人员的行为特征,大幅增强社区门禁系统数据的综合分析和应用能力,有利于提高社区安全管理水平。

权利要求 :

1.基于机器学习聚类算法的门禁数据异常检测方法,包括用于存储门禁记录的数据库,其特征在于:步骤一,清洗社区门禁系统的刷卡记录数据;删除门禁记录中的重复数据和高频数据;

步骤二,对清洗后的数据进行特征提取;提取每个门卡号单日内的分时段刷卡次数和进出门禁的比例作为特征;

步骤三,基于机器学习的聚类算法,分析所提取的门禁记录特征,将所有数据点划分到具有不同异常度的类中;

步骤四,定义异常度、抽取异常刷卡行为;

所述步骤二对清洗后的数据进行特征提取的方法包括:

首先,对于所述步骤一清洗过的数据,确定刷卡数据的基础格式为(Index,ID,time,gateflag),其中Index为刷卡记录的序号,ID为门卡号,time为刷卡时间,gateflag为进出门禁的标识;gateflag=1表示进入小区,gateflag=0表示离开小区;

然后,确定进行特征提取的特征格式为(ID,n1,n2,n3,n4,gateflag),其中n1、n2、n3、n4分别为四个不同时段的刷卡次数;

最后,将每个门卡对应的刷卡数据由基础格式转换为特征格式。

2.根据权利要求1所述的基于机器学习聚类算法的门禁数据异常检测方法,其特征在于,所述步骤一中删除门禁记录中的重复数据和高频数据的方法包括:步骤S1,设定每日刷卡次数阈值与刷卡时间间隔阈值;

步骤S2,从数据库中读取并统计门禁记录中每个门卡号的刷卡次数和刷卡时间序列;步骤S3,对每个门卡号记录中大于刷卡次数阈值,小于刷卡时间间隔阈值的刷卡记录进行清除。

3.根据权利要求1所述的基于机器学习聚类算法的门禁数据异常检测方法,其特征在于,所述特征格式(ID,n1,n2,n3,n4,gateflag)中,n1对应的时段为0-5时,n2对应的时段为

6-11时,n3对应的时段为12-17时,n4对应的时段为18-23时。

4.根据权利要求1所述的基于机器学习聚类算法的门禁数据异常检测方法,其特征在于,所述步骤三中的机器学习聚类分析为机器学习的K均值聚类算法。

5.根据权利要求4所述的基于机器学习聚类算法的门禁数据异常检测方法,其特征在于,将所述步骤二得到的特征记录投射到特征空间中,每条记录对应为空间中的一点,将空间中的所有数据点按照距离远近进行分类,最终所有的数据点都被划分到与其最近的类中。

6.根据权利要求4所述的基于机器学习聚类算法的门禁数据异常检测方法,其特征在于,所述K均值聚类算法中,建立的聚类模型中,其类数量的确定方法为根据数据点与所对应类的中心的距离,将所有数据点划分到n个类,计算所有数据点与其类心距离的总和,该值随着分类数量增加而逐渐减少,在n达到阈值时,再增加分类数量不会明显减小总距离,这个阈值即设为最终的分类数量。

7.根据权利要求4所述的基于机器学习聚类算法的门禁数据异常检测方法,其特征在于,所述步骤四中异常度的定义方法为,通过K均值方法将记录数据划分到n个类中,计算每个数据点距离所有数据中心的距离,值越大表示该点异常度越高。

8.根据权利要求4所述的基于机器学习聚类算法的门禁数据异常检测方法,其特征在于,所述步骤四中异常度的定义方法为,通过K均值方法将记录数据划分到n个类中,按照每一类的数据量定义异常度,类内数据点越少表示该类越异常。

说明书 :

基于机器学习聚类算法的门禁数据异常检测方法

技术领域

[0001] 本发明涉及门禁技术领域,特别涉及一种基于机器学习聚类算法的门禁数据异常检测方法。

背景技术

[0002] 大数据分析技术与社会化行为数据的结合在近年来得到了飞速发展,这一方面得益于大数据平台的持续发展,比如开源的Hadoop、Spark、Hbase等分布式计算、存储框架的成熟。这些新技术伴随着互联网行业的爆发,已经被广泛应用于服务器的恶意请求分析、垃圾邮件过滤、购物推荐、图像识别等领域。基于机器学习的聚类、分类、回归等算法借助分布式大数据平台和工具的威力使得人们有能力对不断增长的数据规模进行深度分析。
[0003] 另一方面,得益于多种类型的传感器被大量应用于检测和收集社会化行为数据,可供分析的数据资源空前丰富。怎样从所获得的数据中挖掘出社会化行为的规律、特征及其他深度信息,成为一个具有相当高研究价值的问题。已有的应用比较成熟的领域有医疗疾病治疗、人类基因编码分析、交通导航等。而在非商业领域,新技术推进的步伐并不是很快,比如对出入社区门禁人员的异常刷卡行为的监测方面,门禁记录数据的分析利用仍处于初级阶段,仅限于记录社区人员和来访人员的进出门禁情况,用以统计常住人口和来访人员。而且门禁系统自身的运行效率和状态往往受到人为管理水平不稳定和门禁设备不够完善等缺陷的约束,对记录的进一步挖掘和利用极其匮乏。

发明内容

[0004] 为了解决上述发明问题,本发明提供了一种基于机器学习聚类算法的门禁数据异常检测方法,实现对门禁记录数据的自动分类,根据每类中记录的数量值可以合理给出异常度的定义,其中记录数量最少的类即为最异常类。
[0005] 具体地,为达到上述目的,本发明提出了基于机器学习聚类算法的门禁记录异常度分析方法,内容包括:
[0006] 步骤1、数据清洗:清除原始门禁记录中的无效数据。原始门禁记录中因违规管理(多人同时使用一张门卡进出门禁等情况)、设备功能不完善(设备采样率设置不合理或异常)等问题,出现个别门卡刷卡次数远高于多数门卡、短时内重复刷卡等情况,进而表现为门禁记录中的无效数据。数据清洗的方法为:统计门禁记录中每个门卡号的刷卡次数和刷卡时间序列,删除刷卡次数超过某个阈值(例如每日刷卡次数排名前十)的门卡号记录,再删除相邻刷卡时间间隔小于某个阈值(例如30秒)的记录。经此处理,得到可进一步分析的有效门禁记录数据。
[0007] 步骤2、提取门禁记录的刷卡行为特征。特征提取是整个方法中最关键的一步,所提取的特征需能够合理反映门禁刷卡行为是否存在异常。经步骤1清洗之后的单条门禁记录的存储格式为(Index,ID,time,gateflag),其中Index为刷卡记录的序号,ID为门卡号,time为刷卡时间,gateflag为进出门禁的标识,gateflag=1表示进入小区,gateflag=0表示离开小区。可以预见,与一个门卡是否存在异常相关联的因素至少包含:一天内的刷卡次数、刷卡时间分布、进出门禁的比例。基于此,统计在一天内单个门卡在0-5时、6-11时、12-17时、18-23时四个时间段内的刷卡次数,记为n1、n2、n3、n4,将原门禁记录格式转化为(ID,n1,n2,n3,n4,gateflag),新格式能表征前述与门卡异常度相关联的三个因素,即为所提取的门禁记录刷卡行为特征。
[0008] 步骤3、基于机器学习的聚类分析。一个中等规模社区的门禁系统经过三个月到半年时间将累积产生几十万到上百万条记录,此数据规模适合采用机器学习方法。所采用的K均值聚类算法的核心思想:将步骤2得到的特征记录投射到特征空间中,每条记录对应为空间中的一点,将空间中的所有数据点按照距离远近进行分类,最终所有的数据点都被划分到与其最近的类中。
[0009] 聚类计算需要人为设定合理的类数量,一个简单的办法是考虑数据点与所对应类的中心的距离,当将所有数据点划分到n个类时,计算所有数据点与其类心距离的总和,该值随着分类数量增加而逐渐减少,在n达到某一个阈值时,再增加分类数量不会明显减小总距离,这个阈值即可设为最终的分类数量。
[0010] 步骤4、定义异常度、抽取异常刷卡行为。通过K均值方法可以将记录数据划分到n个类中,有两种方法定义数据的异常度,一是计算每个数据点距离所有数据中心的距离,值越大表示该点异常度越高,二是按照每一类的数据量定义异常度,类内数据点越少表示该类越异常。因为第一种方法计算量较大,所以本发明采用第二种方法,数据点最少的类中的记录即为异常刷卡行为。
[0011] 本发明实施例的有益效果是:深度挖掘出社区门禁信息,能够得到异常记录,是加强社区安全管理的有力工具。开创性地运用机器学习技术,与常规的人工搜索相比,能够更精准地得到数据中的异常信息,尤其适用于动态递增的海量数据情况。根据由计算得到的异常度,能有效判断任一记录的安全等级。由历史纪录提炼出的数据模型,可实时处理新出现的记录,实时判断该记录的异常度。

附图说明

[0012] 图1为本发明实施例的基于机器学习聚类算法的门禁数据异常检测方法流程图。
[0013] 图2为本发明实施例的异常类计算结果。

具体实施方式

[0014] 实施例1
[0015] 参见图1与图2,本发明提供一种基于机器学习聚类算法的门禁数据异常检测方法。
[0016] 以某社区的真实门禁数据为例,详细描述本发明的操作步骤。
[0017] 步骤1、数据清洗。原始数据记录的时间跨度为三个月,典型的刷卡记录如下:
[0018] 表1 社区门禁刷卡原始记录示例记录序号 卡号 刷卡时间 进出标识
8079 00234521 2016-03-18 21:45:32 1
8100 00237453 2016-03-19 13:18:26 1
8314 00235419 2016-03-19 13:33:47 1
8682 00230173 2016-03-19 14:11:27 0
8802 00232517 2016-03-19 14:19:13 1
[0019] 表中第一列为每条记录对应的序号;第二列为门卡号;第三列为刷卡时间;第四列为进出门禁的方向标识,“1”表示出,“0”表示进。
[0020] 门禁系统因为存在管理疏漏,经常出现管理人员使用同一张卡打开门禁的情况,所以原始数据中存在个别门卡号刷卡次数过多;同时门禁系统的刷卡设备存在采样率设置不当或采样不稳定等问题,间断性地出现在短时内(比如10秒)多次记录同一刷卡行为,导致原始记录中存在一定量的冗余。由这些因素导致的无效记录信息,需要通过统计分析进行排除,采用开源的Apache Spark进行数据清洗操作,代码如下。
[0021] //导入时间处理相关的三个库,对原始记录中的时间格式进行调整
[0022] import java.sql.Timestamp
[0023] import java.text.SimpleDateFormat
[0024] import java.util.Date
[0025] //导入原始数据,并对数据进行初步解析
[0026] val input=sc.textFile("dir/to/data.csv")
[0027] .map{x=>x.split(",")}
[0028] .map{x=>(x(2),(x(3),x(1),x(4),x(0)))}
[0029] //转换数据中的时间格式
[0030] val residents=input
[0031] .map{case(x,(y,z,g,h))=>(x,List(Timestamp.valueOf(y).getTime.toString,z,g,h))}
[0032] .cache
[0033] //检索刷卡次数最多的门卡号
[0034] val residentCount=residents.countByKey.toList
[0035] .sortBy{case(id,count)=>count}
[0036] .reverse
[0037] //删除出现次数过多、时间间隔过小的记录
[0038] val perIdInfor=residents.groupByKey.map{case(id,other)=>{var temp1=other.toList.sortBy{x=>x(0).toLong};(id,temp1)}}
[0039] val reducedRecords=perIdInfor
[0040]   .map{
[0041]      case(id,other)=>{
[0042]         var temp2=List(other(0));
[0043]         for(i<-0 to other.length-2){
[0044]           if(other(i)(2).toInt!=other(i+1)(2).toInt){
[0045]              var temp3=temp2:::List(other(i+1));
[0046]              temp2=temp3;
[0047]           }else{
[0048]           if(other(i+1)(0).toLong-other(i)(0).toLong>300000){[0049]                 var temp3=temp2:::List(other(i+1));
[0050]                 temp2=temp3;
[0051]              }
[0052]           }
[0053]         };
[0054]         (id,(temp2.length,temp2))
[0055]      }
[0056]   }
[0057] 步骤2、特征提取。原始数据以每一次刷卡记录为一条数据,而我们关心的是同一门卡号在一天内的总体刷卡行为,所以需要对清洗后的数据按天进行划分,并统计一天内同一门卡号的刷卡行为,代码如下:
[0058] val reducedData=reducedRecords
[0059] .flatMapValues{case(n,records)=>records}
[0060] //以天为单位统计单个门卡号的记录,并提取其在0-5时、6-11时、12-17时、18-23时四个时间段上刷卡次数作为特征。
[0061] val refDate=Timestamp
[0062] .valueOf("1970-01-01 00:00:00")
[0063] .getTime
[0064] val perDayData=reducedData
[0065] .map{case(id,other)=>{
[0066] var dayGap=(other(0).toLong-refDate)/86400000;
[0067] var quartDayNum=(other(0).toLong-refDate)/21600000%4;
[0068] (id++"#"++dayGap.toString,List(dayGap.toString,quartDayNum.toString,other(1),other(2),other(3)))}}
[0069] val perIdDayData=perDayData.groupByKey
[0070] val perDayFeature=perIdDayData
[0071] .map{case(id,other)=>{
[0072] var tempOther=other
[0073] .toList;
[0074] var flagOne=other
[0075] .toList.map(x=>x(3).toInt).sum;
[0076] var q0=other.toList.filter(x=>x(1).toInt==0).length;
[0077] var q1=other.toList.filter(x=>x(1).toInt==1).length;
[0078] var q2=other.toList.filter(x=>x(1).toInt==2).length;
[0079] var q3=tempOther.length-q0-q1-q2;
[0080] (id,List(q0,q1,q2,q3,flagOne*1.0/tempOther.length))}}
[0081] 在上述代码中,将以(ID,time,gateflag)格式存储的记录转变为(ID,特征)的格式。将全天时间根据当地时区分为0-5时、6-11时、12-17时、18-23时四个时间段,分别统计单个ID在一天内在前述四个时间段内的刷卡次数,相应记为n1、n2、n3、n4。经此处理,原记录转变为(ID,n1,n2,n3,n4,gateflag)的格式,其中特征项n1、n2、n3、n4能同时体现某个ID在某一天内的刷卡时间分布特征和刷卡次数特征,特征项gateflag能体现该ID进出门禁的方向特征。
[0082] 步骤3、聚类分析。聚类算法分析中需要人工设定分类数目K,所选定的K值需使得分类结果趋于稳定。判断分类结果质量的一种方法是计算所有数据点与相应类心的距离平均值。为此,在下面所示的代码中定义了distToCentroid函数用以计算该距离,并在K值范围5-40内分别计算平均距离,通过比对不同K值的平均距离,以选定合理的K值,在本实例中,最终选定的K=30。
[0083] def distance(a:Vector,b:Vector)={
[0084] math.sqrt(a.toArray.zip(b.toArray)
[0085] .map(p=>p._1-p._2)
[0086] .map(d=>d*d)
[0087] .sum)}
[0088] def distToCentroid(datum:Vector,model:KMeansModel)={
[0089] val cluster=model.predict(datum);
[0090] val centroid=model.clusterCenters(cluster);
[0091] distance(centroid,datum)}
[0092] import org.apache.spark.rdd._
[0093] def clusteringScore(data:RDD[Vector],k:Int)={
[0094] val kmeans=new KMeans();
[0095] kmeans.setK(k);
[0096] val model=kmeans.run(data);
[0097] data.map(datum=>distToCentroid(datum,model)).mean()}
[0098] (5 to 40 by 5)
[0099] .map(k=>(k,clusteringScore(K_data,k)))
[0100] .foreach(println)
[0101] 需要注意的是,上述代码仅用于选取K值,一旦该值给定,这些代码将不再使用,不包含在生产代码中。
[0102] 选定K值后,下一步工作是对数据进行机器学习,代码如下。
[0103] val kmeans=new KMeans()
[0104] kmeans.setK(30)
[0105] val model=kmeans.run(K_data)
[0106] 步骤4、结果提取。使用上述机器学习获得的聚类模型,应用于所有数据记录,可得到每一记录的归属类,并统计每一类的记录数量。代码如下。
[0107] //计算每个数据点所属的类,并统计类内的数据点数量。
[0108] val cluster_feature=
[0109] feature.map{case(label,datum)
[0110] =>val cluster=model.predict(datum);
[0111] (cluster,label,datum)}
[0112] val clusterCounts=
[0113] cluster_feature.map{case(x,y,z)=>x}
[0114] .countByValue.map{case(x,y)=>(y,x)}
[0115] .toList.sortBy{case(x,y)=>x}
[0116] 然后统计记录数量最小的类,这些类即是需要查找的异常类,代码如下。
[0117] val abnormalCluster=clusterCounts.take(selected_K/5)
[0118] val abnormalRecords=
[0119] abnormalCluster.map{case(count,cluster)
[0120] =>cluster_feature.filter{case(c,label,datum)
[0121] =>c==cluster}.collect}
[0122] val abnormalData=abnormalRecords.flatMap(x=>x.toList)
[0123] //抽取异常类中的记录
[0124] val abnormalID=
[0125] abnormalData.map{case(cluster,id,vector)
[0126] =>(id.slice(0,18),cluster)}
[0127] val abnormalID_2=
[0128] sc.makeRDD(abnormalID).repartition(1)
[0129] .countByKey.toList.sortBy{case(id,count)
[0130] =>count}.reverse
[0131] 步骤5、结果验证。K均值分析得到的聚类结果如图2所示。
[0132] 类内记录数量直接与异常度关联,类22的异常度最高,类11的异常度最低。本实例中选取所有类的1/5作为异常类输出,即为类22、27、2、26、15和19,由上面可见,这6个类的记录总数并不是很多,较合理地定义了异常类。随机选取类22和11中个5条记录,以验证分类质量。结果如下表所示。
[0133] 表2 类22中的记录示例ID 0-5时(次) 6-11时(次) 12-17时(次) 18-23时(次) “出”占比
1 0 0 7 8 0.53
2 0 1 5 9 0.4
3 0 0 7 6 0.46
4 3 0 10 6 0.42
5 0 0 5 7 0.5
[0134] 表3 类11中的记录示例ID 0-5时(次) 6-11时(次) 12-17时(次) 18-23时(次) “出”占比
1 0 0 0 1 1
2 0 0 0 1 0
3 0 0 0 1 0
4 0 0 0 1 0
5 0 0 0 1 0
[0135] 表2表示异常的刷卡行为包括下午和晚上的多次刷卡,表3表示最正常的刷卡行为是晚上出现的单次刷卡。这里需要进一步解释为什么最正常的刷卡行为出现在下班之后,而不是早上上班时,原因是早上上班人流较集中,一次刷卡,多人可以一起出门禁,多数人都不用刷卡,而晚上下班时,分散的陆陆续续的刷卡较多。通过简单的对比,能够说明此聚类分析结果的质量较好。
[0136] 在本说明书的描述中,参考术语“一个实施例”、“一些实施例”、“示例”、“具体示例”、或“一些示例”等的描述意指结合该实施例或示例描述的具体特征、结构、材料或者特点包含于本发明的至少一个实施例或示例中。在本说明书中,对上述术语的示意性表述不必须针对的是相同的实施例或示例。而且,描述的具体特征、结构、材料或者特点可以在任一个或多个实施例或示例中以合适的方式结合。此外,在不相互矛盾的情况下,本领域的技术人员可以将本说明书中描述的不同实施例或示例以及不同实施例或示例的特征进行结合和组合。
[0137] 以上所述仅为本发明的较佳实施例,并不用以限制本发明,凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。