当我们想利用手机信令数据做一些研究探索的时候怎么办?
没有钱,没有渠道。难道就没得办法了吗?
那就自己动手,造,可劲造。
1 准备
首先准备一个区界,比如天津市河西区,坐标系就用EPSG:32650,底图用osm就可以了。
然后根据对河西区的大致了解,点几个人流聚集的vip点位。
读取这两个shp文件。
gdf = gpd.read_file("./GIS/天津市河西区_boundary.shp")
p_shp = gpd.read_file("./GIS/vip_point.shp")
这里使用sklearn的make_blobs生成满足高斯blobs分布的随机点位,为了不卡机,生成2000个。
当然,记得要把vip_point.shp中的点位弄出来,作为中心点参数。
centers = list(zip(p_shp.geometry.x, p_shp.geometry.y))
data = make_blobs(n_samples=2000, n_features=2, centers=centers, cluster_std=1000, center_box=None, random_state=0, shuffle=True)
X, y = data
sns.scatterplot(X[:,0], X[:,1],hue=y, ax=ax)
2 定义一些常量
接下来定义一些常量,包括边界,数据属性,代理人种类及交通方式等等。
#
# \\\\\\定义常量\\\\\\
#
minx, miny, maxx, maxy = gdf.bounds.loc[0] # 这个是边界
STRUCTURE = ['id_', 'grid', 'timestamp', 'pos_x', 'pos_y', 'bearing', 'category', 'speed_rank', 'speed'] # 属性
CATEGORYRANGE = ['STAY', 'WALKING', 'BICYCLE', 'CAR'] # 交通方式,对应speedrank
CATEGORYPROB = [0.1, 0.4, 0.2, 0.3] # 各种交通方式随机比例
GRIDSIZE = 200 # 格网尺寸
N = 1000 # agent数量
XLIM = (minx, maxx) # x范围
YLIM = (miny, maxy) # y范围
SPEEDRANK = [0, 1, 2, 3] # 静止, 步行, 自行车, 机动车
SPEEDVALUE = [0, 1.4, 2.8, 14] # 单位为米/秒, 对应:0, 5km/h, 10km/h, 50km/h
TIMEORI = pd.Timestamp('2021-4-26 00:00:00') # 初始时间 Timestamp('2021-01-01 00:00:00')
TIMEDT = pd.Timedelta(60, unit='second') # 秒,时间偏移
PERIOD = 180
ANGRANGE = (0, 2 * np.pi) # 角度范围,2*pi
ANGSWING = (-0.25 * np.pi, 0.25 * np.pi) # 移动方向摆动幅度
CATEGORYPROB:这个解释一下,是随机分配的时候,代理人选择交通方式的概率,也就是10%静止不动,40%步行,20%骑自行车,30%开车,对应的移动速度也是不一样的。
其他参数看注释都很好理解。
3 初始化原始的点位
之前生成的2000个点,每个点都需要附加相应的属性,这其中最重要的是随机产生每个点的初始方向与交通选择,当然,也要给每个点赋予名字(ID)和时间戳。
#
# \\\\\\根据shp文件的边界以及vippoint的位置随机生成N个agent,并存储相应的属性
#
df_ori = pd.DataFrame(columns=STRUCTURE) # 初始化初始点位列表
for i in range(len(X)):
id_ = ''.join(['AGENT', f'{i:08d}'])
timestamp = TIMEORI
pos_x = X[i][0]
pos_y = X[i][1]
# pos_x = np.random.uniform(XLIM[0], XLIM[1])
# pos_y = np.random.uniform(XLIM[0], XLIM[1]) # 平均分布的随机数,randn是正态分布的
grid = int((pos_x-minx) // GRIDSIZE + (max(XLIM) - min(XLIM))//GRIDSIZE * ((pos_y-miny) //GRIDSIZE))
bearing = np.random.uniform(min(ANGRANGE), max(ANGRANGE))
speed_rank = np.random.choice(SPEEDRANK, p=CATEGORYPROB)
category = CATEGORYRANGE[speed_rank]
speed = SPEEDVALUE[speed_rank]
df_ori.loc[i] = [id_, grid, timestamp, pos_x, pos_y, bearing, category, speed_rank, speed]
df_ori.to_csv("原始点位.csv", encoding="gb18030")
记得存盘。
4 动起来
这里定义了一个Agent类,包括一些基本的功能。思路就是每一个点都是一个Agent实例,通过随机产生的角度抖动,按照相应的移动速度计算单位时间下x、y轴方向的增量,计算新的位置信息与对应的格网,形成新的记录。
传入period参数,计算相应时间段agent的移动轨迹。
最后汇总,把这2000个点移动需要的时长段,就得到了伪造的移动点数据。
移动轨迹随机,选个点如下:(id=AGENT00000000, CATEGORY=WALKING, SPEED=1.4M/S, TS=2021-04-26 00:00-00:03)