任务5:单车畅行友好度方案


## 学习目标

  • 骑行路线匹配
  • 密集骑行路线识别
  • 骑行友好度定义

## 骑行路径匹配

对于赛题给定的单车订单数据和单车轨迹而言,其并没有给定具体的街道信息,只在单车停车点给定了街道信息。因此我们可以选择使用停车点数据做街道信息匹配,也可以用外部数据做匹配,操作都是一致的。

我们可以使用DCIC2020年给的厦门市道路矢量数据来完成:

import shapely, geopandas, fiona
import seaborn as sns
%pylab inline

shp_df = geopandas.GeoDataFrame.from_file("xiamen_road/xm_road_edit20200826.shp")
shp_df.plot(figsize=(8, 8))

还可以提取具体道路经纬度:

shp_df['START_LONGITUDE'] = shp_df['geometry'].apply(lambda x: x.coords[0][0])
shp_df['START_LATITUDE'] = shp_df['geometry'].apply(lambda x: x.coords[0][1])

shp_df['END_LONGITUDE'] = shp_df['geometry'].apply(lambda x: x.coords[1][0])
shp_df['END_LATITUDE'] = shp_df['geometry'].apply(lambda x: x.coords[1][1])
shp_df = shp_df.drop(['UserID', 'geometry'], axis=1)
road_name START_LONGITUDE START_LATITUDE END_LONGITUDE END_LATITUDE
安仁大道(西向东) 117.986519 24.612696 117.989647 24.610982
安仁大道(西向东) 117.996934 24.605661 117.997052 24.605552
安仁大道(西向东) 117.997052 24.605552 117.997149 24.605466
安仁大道(西向东) 117.999725 24.602609 118.002706 24.598994
安仁大道(西向东) 118.002706 24.598994 118.002770 24.598916
... ... ... ... ...
圆一路 118.186581 24.504305 118.186646 24.505749
安东路 118.000649 24.614283 118.000729 24.614362
长岸路辅路(北向南) 118.088231 24.511117 118.088089 24.510614
长岸路辅路(北向南) 118.087805 24.509671 118.087780 24.509593
殿前一路(西向东) 118.096068 24.532458 118.095621 24.532743

对于骑行轨迹与道路匹配,我们仍然可以使用KNN/或HNSW的方法:

from sklearn.neighbors import NearestNeighbors

knn = NearestNeighbors(metric = "haversine", n_jobs=-1, algorithm='brute')
knn.fit(np.vstack([shp_df[['START_LATITUDE', 'START_LONGITUDE']].values,
                 shp_df[['END_LATITUDE', 'END_LONGITUDE']].values]
                ))


import hnswlib
import numpy as np
p = hnswlib.Index(space='l2', dim=2)
p.init_index(max_elements=300000, ef_construction=1000, M=32)
p.set_ef(1024)
p.set_num_threads(14)

p.add_items(np.vstack([shp_df[['START_LATITUDE', 'START_LONGITUDE']].values,
                 shp_df[['END_LATITUDE', 'END_LONGITUDE']].values]
                ))

当然也可以使用KNN + 停车点的数据完成上述步骤,也可以使用百度梯度的API完成。

index, dist = p.knn_query(bike_track[['LATITUDE','LONGITUDE']].values[:], k=1)
index = index.reshape(-1)
bike_track['road_name'] =  shp_df.iloc[index % len(shp_df)]['road_name'].values

## 密集骑行路线识别

在做完具体的道路匹配后,可以直接完成频率计算:

bike_track[bike_track['day'] == 21]['road_name'].value_counts().head(10)
路名称 频率
厦禾路(东向西) 53924
吕岭路(西向东) 50296
金尚路(南向北) 36511
云顶北路(南向北) 34136
仙岳路辅路(西向东) 32861
湖滨南路(东向西) 32219
仙岳路辅路(东向西) 28889
湖滨南路(西向东) 28785
金尚路(北向南) 28378
嘉禾路(北向南) 26169

## 骑行友好度定义

骑行友好度可以从两个角度来考虑,一是密集骑行路线,二是街道单位骑行花费时间,前者已经计算完成,这里我们关注后者。

$$街道单位骑行花费时间 = \frac{街道距离}{单位骑行时间}$$

  • 单位骑行时间
bike_use_ratio = bike_track.groupby(['road_name','BICYCLE_ID'])['date'].count()*15.0/3615/4
bike_use_ratio = bike_use_ratio.reset_index()
bike_use_ratio = bike_use_ratio.groupby(['road_name'])['date'].mean()
  • 街道距离
from geopy.distance import geodesic
# 根据停车点 范围 计算具体的面积
shp_df['Length'] = shp_df.apply(lambda x: geodesic(
    (x['START_LATITUDE'], x['START_LONGITUDE']), (x['END_LATITUDE'], x['END_LONGITUDE'])
).meters, axis=1)
shp_legth = shp_df.groupby(['road_name'])[['Length']].sum()
  • 友好度计算
bike_use_ratio = pd.merge(bike_use_ratio, shp_legth, on='road_name', how='left')
bike_use_ratio['friendliness'] = bike_use_ratio['Length'] / bike_use_ratio['date']
bike_use_ratio.sort_values(by='friendliness', ascending=False)
bike_use_ratio = bike_use_ratio[['road_name', 'friendliness']]

## 外部数据


## 改进思路

  1. 友好度还可以根据轨迹数据来进行匹配,挖掘出路线中的回头路等信息;
  2. 友好度还可以结合停车点来进行分析,比如停车点是否在街道分布均匀,是否街道两侧都有停车点;
  3. 友好度还可以结合其他交通设施一起分析,如道路是否存在公交车站;

## 报告撰写建议

  1. 建议查阅下现有友好度和拥堵定义,并进行对比分析;
  2. 可以选择一个位置,进行具体分析并给出具体建议,并对比优化前后对比;
  3. 数据使用+技术架构,可以先设计demo,撰写好文档;

赛题FAQ:https://shimo.im/docs/dpgWPXRcygjKg9GH/



© 2019-2021 coggle.club 版权所有     京ICP备20022947    京公网安备 11030102010643号