zoukankan      html  css  js  c++  java
  • 滴滴算法大赛算法解决过程

    题目分析

    赛题详情
    构建一个模型,根据天气,交通,区域里面的各种设施,以往历史数据,预测未来的某个时间点,某个区域里,打车需求的缺口。整个算法其实就是一个有监督的机器学习的过程。

    数据整理

    下载后的整个压缩数据包575M,其中包括的订单数据大约900万条。(其他Master表数据量很小,这里忽略不计)
    使用MongoDB存储的话,大概使用2GB的空间,全部导入之后,工作用计算机十分卡顿。MongoCola管理软件失去响应。所以,这里的订单按照日期导入。(训练的时候,按照天来训练)注意:官方的订单数据的 订单号 OrderID是主键重复的。这里以第一次出现的订单号的数据为准。

    由于数据量非常庞大,所以这里建议将中间的计算结果也放入数据库中备用。
    博客园不支持图片放大功能,如果您想更好的查看图片,也可以使用以下网址获得更好的阅读体验:
    http://codesnippet.info/Article/Index?ArticleId=00000038

    订单数据整理

    订单数据整理,主要是整理出各个时段,各个地域的订单数据。

    • 时间段
    • 地域编号
    • 需求数
    • 缺口
    • 缺口比例

    数据整理尽量使用LINQ进行处理,MONGODB查询是消耗时间的!!!,这里数据库只是用作数据的存储不做计算

            private void btnImportDB_Click(object sender, EventArgs e)
            {
                string rootFolder = txtRootDir.Text;
                //Order: Root + "order_data"
                foreach (var filename in Directory.GetFiles(rootFolder + "\order_data"))
                {
                    if (!filename.Contains("._"))
                    {
                        string strDate = filename.Substring(filename.LastIndexOf("_") + 1);
                        var colname = "Order_" + strDate;
                        Database.Clear(colname);
                        var orderlist = new List<Order>();
                        var read = new StreamReader(filename);
                        while (!read.EndOfStream)
                        {
                            var o = Order.Gernerate(read.ReadLine());
                            orderlist.Add(o);
                        }
                        orderlist = orderlist.Distinct(x => x.order_id).ToList();
                        Database.InsertRecBatch(orderlist, colname);
    
    
                        var orderGaplist = new List<OrderGap>();
                        Database.Clear("OrderGap_" + strDate);
                        for (int time = 1; time < 144 + 1; time++)
                        {
                            for (int area = 1; area < 66 + 1; area++)
                            {
                                var m = new OrderGap() {  DistrictId = area,TimeSlient = time};
                                m.Total = orderlist.Count((x) => { return x.DistrictID == area && x.TimeSlient == time; });  
                                m.Gap = orderlist.Count((x) => { return x.DistrictID == area && x.TimeSlient == time && x.driver_id == "NULL" ; });
                                m.GapPercent = m.Total == 0 ? 0 : Math.Round(((double)m.Gap / m.Total) * 100, 2);
                                orderGaplist.Add(m);
                            }
                        }
                        Database.InsertRecBatch(orderGaplist, "OrderGap_" + strDate);
                        //暂时只分析一天数据
                        break;
                    }
                }
            }
    

    利用Excel,可视化数据

    以下是2016-01-01的数据分析。蓝色的是GAP缺口数,红色的是Total数。
    一天24个小时整体需求分布可以看个大概了。
    PS 区域1 :占整体的5.1%订单量,有一定的参考价值

    PS 区域5 :占整体的22.5%订单量,有一定的参考价值
    这里看到,整个24小时分布极不均衡。考虑到 01-01 是一个特殊的日子,大家为了跨年而在零点之后选择打车也是可以理解的。

    同样的51区域,2016-01-02的情况则比较正常,整体的高峰出现在夜间16:50 - 17:20(评价订单850) 左右。21:10,22:00也是两个小高峰(平均订单720)。

    拟合

    Gap的预测,是建立在一个拟合函数上的。也有一些机器学习的味道。

    总的Gap函数 = 函数(时间,地区)

    • TimeID : 时间片编号
    • DistricID:地区编号
    • Traffic:交通流量
    • Weather:天气
    • POI:设施数

    百度地图POI说明
    注意:每家公司的POI分类都是不同的,这里只是将百度POI做个例子,滴滴打车的POI和百度的POI定义好像是不同的。

    交通流量和时间有关,一个地方的拥堵程度和时间有关系
    不同的地区,各种设施配置不同。
    天气和时间有关。

    Gap函数 = 函数(交通拥挤度函数(时间,地区编号),POI函数(地区编号),天气函数(时间))

    这里可以认为,一个地方的打车人数,交通越堵,则打车的GAP越大。天气不好,打车的人则越多,GAP也越大。设施越多的地方,打车的需求也越多,GAP可能也越大。但是这一切都只是可能性。
    (题外话,其实真实的情况也要考虑节假日的问题,在节假日的时候,GAP可能会变大。当然这是一个人文的考量了)

    算法

    交通拥堵函数:
    这里的交通拥堵函数是使用4个等级表示的。

    • LV1 20条路 权重8
    • LV2 10条路 权重4
    • LV3 15条路 权重2
    • LV4 05条路 权重1
      那么拥堵指数怎么计算呢?这里应该是对每个拥堵哟一个权重,等级越高,权重越大。
      拥挤度 = SUM(权重 * 数量)
      当然权重也是一个需要训练和拟合的。
      (设施数和天气差不多,也是同样考虑的。)
      这里有三个指标,每种指标对于整体的影响程度也是需要训练的。

    各项指标分析

    起始区域差距

    以下数据为2016-01-01的数据统计

    整体有效订单数:498789(订单ID去重复)
    66个区域的订单分布是极其不均衡的.

    MAX MIN AVG
    112023 71 7557.4

    排名后33位的,总共只有整体的4.37%的订单
    排名前5位的,总共只有整体的50.87%的订单

    起始区域POI整体数目和订单数关系

    我们将POI总数/30 和订单数一起放到柱状图中发现,POI总数和订单数应该有一些联系。
    一个区域POI数越多说明这个地区越是繁华,从这里打车的需求就越多。

    任务

    • 研究同一时间片,同一地区,按照日期变化,数据的变化。观察天气对数据变化的影响
    • 研究同一时间片,不同地区,POI的数量对数据变化的影响
    • 研究每个区域的需求量,可能每个区域的需求量基准数值都是差不多的。
  • 相关阅读:
    面试题:Spring的理解
    静态块与静态变量
    构造方法与构造块的执行顺序(区别于static)
    子类调用父类的构造函数几种情况
    使用json遇到的问题
    页面加载,使用ajax查询某个类别,并且给它们添加(拼接)连接
    对某个商品的上下架状态进行改变
    SSH后台管理系统,实现查询+分页
    跟上Java8
    java中值传递和引用传递
  • 原文地址:https://www.cnblogs.com/TextEditor/p/5519894.html
Copyright © 2011-2022 走看看