基于轨迹的游客行为特征分析

---------------------------------------------------------------------------------------------
[版权申明:本文系作者原创,转载请注明出处] 
文章出处:https://blog.csdn.net/sdksdk0/article/details/83068473

作者:朱培      ID:sdksdk0     
--------------------------------------------------------------------------------------------

大数据时代,深度“数据挖掘”高级分析技术成为大势所趋,对于旅游景区来说,谁先掌握互联网平台、善用大数据,谁就最有可能先人一步破除体制壁垒与管理围墙,实现转型升级和跨越式发展。通过在旅游景区部署移动信号监测设备,就可以发现该群体游客的相关属性,例如在一个区县,在不同景点之间部署,可以发现游客移动的轨迹是怎么样,本文主要就是用于分析游客在不同景点之间的浏览情况,这样可以更加合理的设计景区与景区之间的交通路线,销售相关旅游产品和应急预案等方面的东西。本文所涉及的内容使用mysql+springboot来实现。

首先来看一下清洗完成后的数据:浏览线路的格式为:  景区A=>景区C=>景区B=>景区D。

现在有数据格式如下(完整的数据集在文末提供下载链接):

第一列为id,第二列为景区编号,第三列为用户编号,第四列为时间,第五列为景区名称。

1    18C8E750176E    3478D7E2C139    20180503000000     嵩溪村
2    18C8E750182A    C46699E01080    20180503000000     江南第一家花海
3    18C8E750180E    084ACF3E591F    20180503000000     水晶城
4    18C8E75017DA    386EA2788110    20180503000000     高速路
5    18C8E7501806    205D479A3020    20180503000001     翠湖
6    18C8E750181E    442C05543BED    20180503000001     水晶城
7    18C8E750182E    F06D781D8FAF    20180503000002     通济桥水库大坝
8    18C8E75017EE    B4EFFAC7D0C7    20180503000002     汽车客运站
9    18C8E75017EE    6C5C14743F6F    20180503000002     汽车客运站
10    18C8E75017A6    F4B7B356B876    20180503000003     檀溪镇
11    18C8E750181A    4C0FC7DF8C8E    20180503000003     金狮湖
12    18C8E750180A    B436A9063032    20180503000003     翠湖

下载需要统计的就是同一个用户去了哪些景区,按时间维度进行排列,即可得出单个游客的移动轨迹。然后将所有游客的轨迹在一个List中进行合并处理,相同游客轨迹的数量加1,最终即可全部游客的移动轨迹。因为全部数据量在非常大,所以数据从数据仓库中选取了某一天的部分数据量来这里做演示。

1、在mysql数据库中创建表orbit_data,将数据集导入进去(文末提供数据集下载链接)

2、创建bean,OrbitData.java,里面包含和数据库表结构相对应的字段

    private Integer id;
    private String probMac;
    private String devcMac;
    private String inTime;
    private String name;

3、mybatiss中查询

<select id="selectByMapAllList" resultType="OrbitData">
        select *  from orbit_data  where 1=1
        and devcMac in
        (select devcMac from  orbit_data  where 1=1
        and length(devcMac)>=10
        <if test="beginTime != null and beginTime != '' ">
            and inTime <![CDATA[ >= ]]> #{beginTime}
        </if>
        <if test="endTime != null and endTime != '' ">
            and inTime <![CDATA[ <=]]> #{endTime}
        </if>
        group by devcMac
        having count(*)>1
        )
        <if test="beginTime != null and beginTime != '' ">
            and inTime <![CDATA[ >= ]]> #{beginTime}
        </if>
        <if test="endTime != null and endTime != '' ">
            and inTime <![CDATA[ <=]]> #{endTime}
        </if>
        order by devcMac,inTime asc
    </select>

4、因为这个轨迹分析计算是离线处理的,每天只需要运行一次即可,所以处理逻辑如下:

log.info("游客轨迹分析定时任务,开始...");
        //获取总人数
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        String dayId = DateUtil.format(cal.getTime(), "yyyyMMdd");
        String beginTime = dayId + "000000";
        String endTime = dayId+"235959";
        
        List<OrbitData> orbitList = orbitMapper.selectByMapAllList(beginTime,endTime);
        
        List<Map<String, Object>> lineList = new ArrayList<Map<String, Object>>();
 
        String tempLine="";
        for(int i=0;i<orbitList.size();i++){
            Map<String, Object> lineMap=new HashMap<String,Object>();
            OrbitData orbit = orbitList.get(i);
            if(i==0){
                tempLine = orbitList.get(i).getName()+"=>";
                location += "("+orbitList.get(i).getLongitude()+","+orbitList.get(i).getLatitude()+"),";
            }else if(i>0 && i<orbitList.size()){
                //如果相等,说明是同一个人
                if(orbit.getDevcMac().equals(orbitList.get(i-1).getDevcMac())){
                    if(!orbitList.get(i-1).getName().equals(orbit.getName())){
                        BigDecimal a= new BigDecimal(orbitList.get(i-1).getInTime().toString().trim());
                        BigDecimal b= new BigDecimal(orbitList.get(i).getInTime().toString().trim());
                        BigDecimal cc=b.subtract(a);

                         //不同景点之间需要间隔10分钟以上的才属于有效数据
                        if( cc.compareTo(new BigDecimal(1000))>-1){
                            tempLine += orbitList.get(i).getName()+"=>";    
                        }else if(i+1<orbitList.size()){
                           
                            if(!orbit.getDevcMac().equals(orbitList.get(i+1).getDevcMac())){
                                tempLine += orbitList.get(i).getName()+"=>";    
                            }
                        }
                    }
                }else{
                    String[] split = tempLine.split("=>");
                    if(split.length>1){
                        tempLine=tempLine.substring(0,tempLine.length()-2);
                        lineMap.put("track", tempLine);
                        lineMap.put("day_id", DateUtil.format(cal.getTime(), "yyyy-MM-dd"));
                        lineMap.put("num", 1);
                        lineList.add(lineMap);
                    }
                    tempLine="";
                    location="";
                    tempLine += orbitList.get(i).getName()+"=>";    
                }
            }
        }
        
        //lineList合并处理
        List<Map<String, Object>> countList = new ArrayList<Map<String, Object>>();// 用于存放最后的结果
        for (int i = 0; i < lineList.size(); i++) {
            String track = lineList.get(i).get("track").toString();
            String day_id = lineList.get(i).get("day_id").toString();
            int flag = 0;// 0为新增数据,1为增加count
            for (int j = 0; j < countList.size(); j++) {
                String track_ = countList.get(j).get("track").toString();
                String day_id_ = countList.get(j).get("day_id").toString();
                if (track.equals(track_) && day_id.equals(day_id_)) {
                    int sum = Integer.parseInt(lineList.get(i).get("num").toString())
                            + Integer.parseInt(countList.get(j).get("num").toString());
                    countList.get(j).put("num", sum + "");
                    flag = 1;
                    continue;
                }
            }
            if (flag == 0) {
                countList.add(lineList.get(i));
            }
        }
        if(countList.size()>0){

          //将查询出来的结果存放到数据库中
            personStayLineMapper.insertBatch(countList);
        }
        log.info("游客轨迹分析定时任务,结束...");

5、处理完成的结果如下

处理完成之后有的有轨迹至少要有2个景区,同时会存在有多个景点情况

 

数据集下载地址为:https://download.csdn.net/download/sdksdk0/10723169

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值