数据STUDIO

Scikit-mobility:一个用于分析、生成和风险评估移动数据的Python库

Image

Image

过去十年见证了大规模移动数据集的出现,例如由GPS设备生成的轨迹、通话详单记录和来自社交媒体平台的地理标记帖子。这些数据集促进了各种移动性分析应用的广泛科学产出,从计算流行病学到城市规划和交通工程。

文献主要涉及:与原始时空轨迹相关的数9据清洗问题;侧重于发现支配人类移动的统计“规律”;设计能够逼真地重现人类移动规律的合成轨迹生成算法;致力于解决关键的隐私问题,提出了在数据库中执行个人再识别的技术。但是,目前还没有一款统计软件能够支持科学家和从业者处理移动数据分析中提到的所有方面。

本文,我们将介绍一个实用的Python库——scikit-mobility,它旨在提供一系列API,方便快捷分析移动数据和模拟人类移动习惯。

关键词

数据科学;人类移动性;移动性分析;时空分析;大数据;网络科学;数据挖掘;Python;数学建模;迁移模型;隐私

1 引言

过去十年见证了数字轨迹大规模数据集的出现,以前所未有的规模和细节描绘了人类的移动轨迹。相关研究逐渐展开,涉及到不同的领域。这些领域的研究都表明,人类移动不是随机的,而是具有可预测的模式。因此,研究人类移动,对各行各业都有广泛现实意义。

尽管移动性分析对许多科学和工业领域越来越重要,但目前还没有一款统计软件能够支持科学家和从业者处理所有移动性分析内容。为了填补这一空白,scikit-mobility被开发了出来。

scikit-mobility是一个Python库,旨在为科学家和从业者提供一个环境,以重现现有研究并对移动数据进行分析。具体而言,该库允许用户:

  1. 加载和表示个人和集体级别的移动性数据。
  2. 使用最先进的技术对移动性数据进行清洗和预处理,例如轨迹聚类、压缩、分段和过滤。
  3. 通过使用个人和集体级别上刻画移动模式的主要指标分析移动性数据,例如旅行和特征距离的计算、对象和位置熵、位置频率、等待时间、起始-目的地矩阵等等。
  4. 运行最流行的机制生成模型来模拟个体移动性,例如探索和偏好返回模型(EPR)及其变体,以及通勤和迁移流动,例如引力模型和辐射模型。
  5. 通过模拟与隐私攻击的大量回识别风险相关联,估计与给定移动性数据集分析相关的隐私风险。

scikit-mobility可在GitHub上公开获取,链接为:https://scikit-mobility.github.io/scikit-mobility/。

有关如何使用该库进行移动性分析的教程可在以下链接中找到:https://github.com/scikit-mobility/tutorials。

描述scikit-mobility的所有类和函数的文档可在以下链接中找到:https://scikit-mobility.github.io/scikit-mobility/。

2 数据结构

scikit-mobility提供了两种数据结构,用于处理原始轨迹和地点之间的流动。这两种数据结构都是在DataFrame(Pandas核心对象之一)的基本上扩展。因此,TrajDataFrame和FlowDataFrame都继承了DataFrame提供的所有功能,以及读写表格数据(例如移动性数据集)的高效优化。这个选择使得scikit-mobility具有广泛的兼容性。

需要注意的是,当前版本的库设计用于处理纬度和经度系统(epsg:4326),这是移动性分析实际场景中最常用的系统。因此,当库的函数计算距离时,默认使用Haversine公式。

2.1 轨迹

移动性数据描述了一组对象在观测期间的移动情况。这些对象可以代表个体、动物、私人车辆、船只,甚至是运动场上的运动员。移动性数据通常以自动方式收集,作为人类活动在电子设备上的副产品(如手机、GPS设备、社交网络平台、视频摄像机),并以轨迹的形式存储,轨迹是时间顺序的一系列时空点,表示对象在某一位置停留或穿过。

在移动性分析的文献中,轨迹通常被形式化定义如下:对象u的轨迹是一个时间顺序的元组序列,其中是一个位置, 和是该位置的坐标, 是相应的时间戳,如果 <  ,则有 <   。

在scikit-mobility中,一组轨迹由 TrajDataFrame(图1)描述。

图1:TrajDataFrame的表示形式。每行代表一个对象轨迹的一个点,由三个必需的列(纬度、经度、日期时间)描述,最终可能由列uid和tid描述,分别表示与该点相关联的对象和轨迹ID。
图1:TrajDataFrame的表示形式。每行代表一个对象轨迹的一个点,由三个必需的列(纬度、经度、日期时间)描述,最终可能由列uid和tid描述,分别表示与该点相关联的对象和轨迹ID。

TrajDataFrame是pandas DataFrame的扩展,具有特定的列名和数据类型。TrajDataFrame中的一行表示轨迹的一个点,由三个必填字段(也称为列)描述:纬度(类型:浮点数)、经度(类型:浮点数)和日期时间(类型:日期时间)。

此外,还可以指定两个可选列。第一个是uid:它标识与轨迹点相关联的对象,可以是任何类型(字符串、整数或浮点数)。如果uid不存在,scikit-mobility假设TrajDataFrame包含与单个移动对象相关联的轨迹。第二个是tid(任意类型),指定轨迹点所属轨迹的标识符。如果tid不存在,scikit-mobility假设TrajDataFrame中所有与uid相关联的行都属于同一个轨迹。需要注意的是,除了必填列之外,用户可以根据需要向TrajDataFrame添加任意数量的列,因为scikit-mobility中的数据结构继承了所有pandas DataFrame的功能。

每个TrajDataFrame还具有两个必填属性:

  • crs(类型:字典):表示与轨迹相关联的坐标参考系统。默认为epsg:4326(纬度/经度参考系统)。
  • parameters(类型:字典):表示已应用于TrajDataFrame的操作。该属性是一个字典,其中键是已应用的函数的标识(详见第3节)。

scikit-mobility提供了从不同格式(例如字典、列表、pandas DataFrames)的移动性数据创建TrajDataFrame的函数。要从文件加载TrajDataFrame,我们首先导入必要的库。

Image

然后,我们使用TrajDataFrame类的from_file方法从文件路径加载移动性数据。

Image

需要注意的是,与lat、lng和datetime列对应的值必须分别为float、float和datetime类型,否则库会引发异常。

加载的TrajDataFrame的crs属性提供了坐标参考系统,而parameters属性提供了一个包含关于数据的元信息的字典。当我们从文件加载数据时,scikit-mobility将from_file键添加到parameters属性中,该键指示文件的路径。

Image

TrajDataFrame构造函数强制将三个必填列的值转换为预设类型。只有在转换失败时,它才会引发异常。例如,构造函数可以成功将字符串"39.1432"转换为浮点数39.1432,但无法将字符串"39.2ui2"转换为浮点数(因此引发异常)。

加载后,我们可以使用print函数和head函数查看TrajDataFrame的一部分,head函数显示TrajDataFrame的前五行。需要注意的是,由于文件中存在uid列,所创建的TrajDataFrame也包含相应的列。

Image

2.2 流动(Flows)

起始地-目的地矩阵,也称为流动,是移动性数据的另一种常见表示形式。而轨迹是指单个对象的移动,流动则是指一组地点之间对象的聚合移动。流动的一个例子是城市社区之间的日常通勤流动。形式上,我们定义起始地-目的地矩阵如下:

起始地-目的地矩阵T是一个n×m矩阵,其中n是不同的“起始地”位置数,m是不同的“目的地”位置数,Tij是从位置i到位置j的对象数量。

在scikit-mobility中,起始地-目的地矩阵由FlowDataFrame结构描述。FlowDataFrame是pandas DataFrame的扩展,具有特定的列名和数据类型。

FlowDataFrame中的一行表示两个地点之间的对象流动,由三个必填列描述:起始地(任意类型)、目的地(任意类型)和流动量(类型:整数)。同样,用户可以根据需要向FlowDataFrame添加任意数量的列。

在移动性任务中,通常通过将坐标映射到空间分割来将领域离散化,即使用可数数量的几何形状(例如正方形、六边形)覆盖二维空间的空间镶嵌,称为瓦片,不重叠且没有间隙。例如,在对移动流动进行分析或预测时,空间镶嵌用于聚合人们在位置之间移动的流动(镶嵌的瓦片)。因此,每个FlowDataFrame都与一个空间镶嵌关联,该空间镶嵌是一个geopandas GeoDataFrame,包含两个必填列:tile_ID(任意类型)表示位置的标识符;geometry表示描述位置在领域上的几何形状(例如正方形、六边形、邻域的形状)。

需要注意的是,FlowDataFrame中起始地和目的地列中的每个位置标识符必须存在于关联的空间镶嵌中。否则,库会引发异常。类似地,如果FlowDataFrame中的起始地和目的地列的类型与关联的空间镶嵌中的tile_ID列的类型不同,scikit-mobility也会引发异常。

以下代码从对应的文件中加载空间镶嵌(spatial tessellation,或空间网格)和FlowDataFrame。

Image

我们使用GeoDataFrame类的from_file方法加载空间镶嵌(tessellation),使用TrajDataFrame类的from_file方法加载FlowDataFrame。需要注意的是,加载FlowDataFrame时需要通过"tessellation"参数指定关联的空间镶嵌。

空间镶嵌和FlowDataFrame的结构如下所示。

Image

由于空间镶嵌是一个geopandas GeoDataFrame,它支持任何类型的几何形状(例如多边形、点)。然而,应避免使用点几何形状,因为它无法正确表示空间镶嵌的瓦片。一般来说,应优先选择多边形和多多边形形状来描述瓦片。

3 轨迹预处理

与任何分析过程一样,移动性数据分析需要进行数据清理和预处理步骤。预处理模块允许用户执行三个主要的预处理步骤:噪声过滤、停留检测和轨迹压缩。需要注意的是,如果TrajDataFrame包含多个用户的多个轨迹,预处理方法会自动应用于单个轨迹,并在必要时应用于单个对象。

3.1 噪声过滤

轨迹数据通常存在噪声,通常是由于记录错误,例如信号接收差。当点的坐标与之前的点相比存在较大误差时,最好的解决方案是过滤掉这些点。在scikit-mobility中,filter方法会过滤掉速度大于max_speed参数(默认设置为500km/h)的点。为了使用filter函数,首先导入预处理模块。

Image

然后,我们在包含GPS轨迹的TrajDataFrame上应用过滤,将最大速度设置为10 km/h:

Image

如上所示,217,653个点中有108,874个点被过滤掉。过滤的强度由max_speed参数控制,值越小,过滤越强。

3.2 停留点检测

轨迹中的一些点可以表示兴趣点(POIs),例如学校、餐厅和酒吧,或者它们可以表示用户特定的位置,如家和工作地点。这些点通常被称为停留点(Stay Points)或停靠点(Stops),可以用不同的方式检测到。常见的方法是应用空间聚类算法,通过观察轨迹点的空间邻近性将它们聚类在一起。在scikit-mobility中,检测模块中的stops函数可以找到对象访问的停留点。例如,要识别停留点,其中对象在给定的点周围至少停留minutes_for_a_stop分钟,在距离spatial_radius_km × stop_radius_factor的范围内,我们可以使用以下代码:

Image

如代码片段所示,为了指示用户离开停留位置的时间,在TrajDataFrame中添加了一个新列leaving_datetime。

3.3 轨迹压缩

轨迹压缩的目标是减少轨迹点的数量,同时保留轨迹的结构。这一步通常在停留点检测步骤之后应用,并且会显著减少轨迹点的数量。在scikit-mobility中,我们可以使用预处理模块下的compression模块中的方法之一。例如,要合并所有彼此距离小于0.2km的点,可以使用以下代码:

Image
表格1:在scikit-mobility中实现的轨迹预处理方法
表格1:在scikit-mobility中实现的轨迹预处理方法

一旦压缩完成,轨迹将呈现较少的点数,可以通过使用scikit-mobility中描述的数据可视化功能轻松绘制这些点。表1列出了scikit-mobility中可用的轨迹预处理方法。

4 绘图

scikit-mobility 的一个使用场景是对移动数据集进行探索性数据分析,其中包括轨迹和流的可视化。

为此,TrajDataFrame 和 FlowDataFrame 都具有方法,允许用户使用 folium 库 生成交互式可视化。选择 folium 的原因是,鉴于移动数据的复杂性,用户可能需要缩放和与轨迹、流和分割进行交互。这种交互在静态绘图库(如 matplotlib)中是不可能的。用户可以将交互式绘图保存在 .html 文件中,或者可以截屏并保存为 .png 文件。

4.1 轨迹可视化

TrajDataFrame 具有三种主要的绘图方法:plot_trajectory 在地图上绘制连接轨迹点的线条;plot_stops 在地图上绘制停留点的位置;plot_diary 绘制随时间变化的访问位置序列。

4.1.1 绘制轨迹

TrajDataFrame 的 plot_trajectory 方法在地图上绘制按时间排序的轨迹点,通过直线将它们连接起来。如果列 uid 存在且包含多个对象,则轨迹点首先按 uid 进行分组,然后按 datetime 进行排序。具有许多点的大型 TrajDataFrame 在可视化时可能会计算量很大。可以使用两个参数来减少要绘制的数据量:max_users(类型:int,默认值:10)限制要绘制轨迹的对象数量,而 max_points(类型:int,默认值:1000)限制每个对象要绘制的轨迹点数量,即如果需要,将对对象的轨迹进行下采样,并绘制最多 max_points 个点。可以通过参数自定义绘图样式,以指定轨迹线的颜色、线宽、透明度,以及要使用的地图瓦片类型。用户还可以绘制标记,表示轨迹的起点和终点。

plot_trajectory 方法以及所有其他绘图方法都返回一个 folium.Map 对象,可以通过其他 folium 和 scikit-mobility 函数将额外的数据可视化在同一地图上。folium.Map 对象可以通过 map_f 参数传递给绘图方法(默认值为 None,表示将移动数据绘制在新地图上)。

下面是 plot_trajectory 方法生成的绘图示例:

Image

注意,如果轨迹代表抽象的移动性,例如从社交媒体帖子或手机通话中提取的移动性,可能会出现不考虑道路网络上的墙壁、建筑物和类似结构的直线。

默认情况下,TrajDataFrame 表示一组个体的完整移动性,即覆盖整个观测期(例如一个月)。用户可以使用预处理函数(如 detection.stops 函数)将个体的轨迹分割,并将整个轨迹分割成子轨迹,添加适当的列来标识它们(例如 tid 列)。此时,用户可以通过选择创建的列的值来可视化 TrajDataFrame 的部分内容。

4.1.2 绘制停留点

TrajDataFrame 的 plot_stops 方法在地图上将停留点的位置绘制为标记。此方法需要具有 constants.LEAVING_DATETIME 列的 TrajDataFrame,该列由 scikit-mobility 函数用于检测停留点创建。参数 max_users(类型:int,默认值:10)限制要绘制停留点的对象数量。可以通过参数自定义绘图样式,以指定标记的颜色、半径和透明度,以及要使用的地图瓦片类型。popup 参数(默认值:False)允许增强绘图的交互性,当用户点击标记时,弹出窗口会显示在停留点的信息,如坐标、对象的 uid、到达时间和离开时间。

该方法返回一个 folium.Map 对象,可以通过其他 folium 和 scikit-mobility 函数使用该对象在同一地图上可视化其他数据。folium.Map 对象可以通过 map_f 参数传递给 plot_stops 方法(默认值为 None,表示停留点绘制在新地图上)。

下面是由 plot_stops 方法生成的绘图示例。请注意,如果 TrajDataFrame 中存在 cluster 列(例如在应用 cluster 方法时),则停留点会根据该列的值自动上色(以区分不同的停留点簇)。

Image

4.1.3 绘制日记

TrajDataFrame 的 plot_diary 方法绘制对象访问的位置的时间序列。如果存在 uid 列,则必须通过 user 参数指定一个对象 ID。该方法需要具有 constants.CLUSTER 列的 TrajDataFrame,该列由 scikit-mobility 函数用于聚类停留点创建。

绘图在 x 轴上显示时间,并显示一系列不同颜色的矩形,表示对象对各个停留点的访问。矩形的长度表示访问的持续时间:左边缘表示到达时间,右边缘表示离开时间。矩形的颜色表示停留点的聚类:属于同一聚类的停留点具有相同的颜色(颜色代码与 plot_stops 方法使用的代码一致)。白色矩形表示对象正在移动。

下面是由 plot_diary 方法生成的绘图示例:

Image

用户可以将多个移动对象的日记绘制在一起以进行比较:

Image

4.2 可视化流动性

FlowDataFrame 有两种主要的绘图方法:plot_tessellation 在地理地图上绘制空间镶嵌的瓦片,plot_flows 在地理地图上绘制连接空间镶嵌瓦片之间存在流动性的质心的线条。

4.2.1 绘制空间镶嵌

FlowDataFrame 的 plot_tessellation 方法在地理地图上绘制与 FlowDataFrame 相关联的 GeoDataFrame。对于具有许多瓦片的大型空间镶嵌,可视化可能会计算密集。maxitems 参数可用于限制要绘制的瓦片数量(默认值为 -1,表示显示所有瓦片)。

绘图样式可以通过参数进行自定义,以指定瓦片的颜色、透明度和地图瓦片类型。popup_features 参数(类型:列表,默认值:[constants.TILE_ID])可以增强绘图的交互性,当用户点击瓦片时会显示弹出窗口,其中包含在参数列表中指定的空间镶嵌的 GeoDataFrame 中的列中的信息。

该方法返回一个 folium.Map 对象,可以通过其他 folium 和 scikit-mobility 函数使用该对象在同一地图上可视化其他数据。folium.Map 对象可以通过 map_osm 参数传递给 plot_flows 方法(默认值为 None,表示在新地图上绘制空间镶嵌)。

下面是由 plot_tessellation 方法生成的绘图示例:

Image

4.2.2 绘制流动性

FlowDataFrame 的 plot_flows 方法将流动性绘制在地理地图上,以连接 FlowDataFrame 的空间镶嵌瓦片的质心。对于具有许多起点-终点对的大型 FlowDataFrame,可视化可能会计算密集。min_flow 参数(类型:整数,默认值:0)可用于指定仅显示大于 min_flow 的流动性。每条线的粗细取决于流量,并可以通过 flow_weight、flow_exp 和 style_function 参数进行指定。绘图样式可以通过其他参数进一步自定义,以指定流动线的颜色、透明度和地图瓦片类型。flow_popup 和 tile_popup 参数可增强绘图的交互性,当用户点击流动线或起点位置的圆圈时,弹出窗口显示流动性或来自某个位置的流动性的信息。该方法返回一个 folium.Map 对象,可以通过其他 folium 和 scikit-mobility 函数使用该对象在同一地图上可视化其他数据。folium.Map 对象可以通过 map_f 参数传递给 plot_flows 方法(默认值为 None,表示在新地图上绘制流动性)。

下面是由 plot_flows 方法生成的绘图示例:

Image
表 2:scikit-mobility 中实现的绘图方法。
表 2:scikit-mobility 中实现的绘图方法。

用户还可以在同一绘图中可视化空间镶嵌和流动性

Image

5 移动性度量

在过去的十年中,已经提出了几种度量方法来捕捉个体和集体级别的人类移动模式。个体度量方法总结了单个移动对象的移动模式,而集体度量方法总结了整个人群的移动模式。例如,所谓的回旋半径及其变体量化了个体行进的特征距离,而多种受香农熵启发的度量方法被提出来量化个体移动的可预测性。

scikit-mobility 提供了一系列广泛的移动性度量方法,每个方法都作为一个函数实现,输入为 TrajDataFrame,并输出为 pandas DataFrame。个体度量和集体度量分别在 skmob.measure.individual 和 skmob.measure.collective 模块中实现。

下面的代码计算了两个度量:对象的行进距离和它们的回旋半径。首先,我们从库中导入这两个函数。

Image

然后,我们分别调用TrajDataFrame上的两个函数。

Image

这些函数的输出是一个带有两列的 pandas DataFrame:uid 列包含对象的标识符;第二列的名称与调用的函数名称相对应,其中包含了该对象的计算度量值。例如,在 DataFrame jl_df 中,DataFrame 的 jump_lengths 列包含该对象的所有行进距离列表。

类似地,在 DataFrame rg_df 中,radius_of_gyration 列包含该对象的回旋半径。

请注意,如果输入的 TrajDataFrame 中没有可选的 uid 列,则输出的是简单的 Python 结构,而不是 pandas DataFrame(例如,jump_lengths 函数输出一个列表,radius_of_gyration 函数输出一个浮点数)。

集体度量的使用方式类似。下面的代码计算了一个集体度量 - 每个位置的访问次数(由任何对象)。首先,我们导入函数。

Image

然后,我们在 TrajDataFrame 上调用该函数。

Image

与个体度量一样,这些函数的输出是一个 pandas DataFrame。这个 DataFrame 的格式取决于度量方法。例如,在 DataFrame vpl_df 中有三列:lat 和 lng 表示一个位置的坐标,n_visits 表示 TrajDataFrame 中访问该位置的次数。

表格3和表格4分别列出了可用的个体和集体度量。

表格3:个体度量
表格3:个体度量
表格4:集体度量
表格4:集体度量

6 个体生成算法

人类移动性生成算法的目标是创建一个人口模型,其移动模式在统计上与真实个体的移动模式无法区分。

生成算法通常生成与单个移动对象相对应的合成轨迹,假设一个对象独立于其他对象。scikit-mobility实现了最常见的个体生成算法,如探索和偏好回归模型及其变种和DITRAS。

每个生成算法都是一个Python类。首先,我们实例化算法。然后,我们调用generate方法开始生成合成轨迹。

下面的代码展示了生成描述1000个代理在一个Tessellation的位置之间移动并在输入中指定的一段时间内的合成轨迹的TrajDataFrame的代码。首先,我们从库中导入生成算法的类(DensityEPR)。

Image

然后,我们从文件加载空间网格化,这是代理必须移动的空间网格化对象,并且我们指定模拟的开始时间和结束时间为pandas的datetime对象。

Image

最后,我们实例化DensityEPR模型,并通过generate方法开始模拟,该方法接受开始时间、结束时间、网格化对象、代理数量和其他模型特定参数作为输入。模拟的输出是一个包含1000个代理商轨迹的TrajDataFrame。

Image

7. 集体生成算法

集体生成算法估计一组离散位置之间的空间流动。使用集体生成算法估计的空间流动的示例包括邻域之间的通勤出行、市之间的迁移流动、州之间的货运以及地区之间的电话通话。在scikit-mobility中,集体生成算法接受一个镶嵌对象作为输入。

要成为集体算法的有效输入,网格化应包含两列:几何和相关性,这两列用于计算集体算法使用的两个变量:网格之间的距离和每个网格的重要性(也称为“吸引力”)。集体算法生成一个包含生成流动和指定为算法输入的镶嵌的FlowDataFrame。

scikit-mobility实现了最常见的集体生成算法:重力模型和辐射模型。我们用基于重力模型的示例说明如何在scikit-mobility中使用生成算法。

实现重力模型的Gravity类有两个主要方法:fit方法使用训练的FlowDataFrame校准模型的参数;generate方法在给定的镶嵌上生成流动。以下代码展示了如何使用这两个方法估计纽约州各县之间的通勤流动。

首先,我们从文件中加载镶嵌:

Image

镶嵌包含人口列,用作每个网格(县)的相关性变量。接下来,我们从文件中加载县之间的观察到的通勤流动:

Image

让我们使用观察到的流动来拟合带有幂律避让函数的单约束重力模型的参数(有关重力模型的更多细节,请参见[Barbosa et al., 2018])。

首先,我们实例化模型:

Image

然后,我们调用fit方法从之前加载的FlowDataFrame拟合参数:

Image

最后,我们使用拟合的模型在相同的网格化上生成流动。通过设置out_format="probabilities"参数,我们指定在返回的FlowDataFrame的flow列中希望观察到单位流动(出行)的概率。

Image
表5列出了库中可用的生成模型。
表5列出了库中可用的生成模型。

8 隐私风险评估

移动数据是敏感的,因为个体的移动可以揭示机密个人信息或允许在数据库中重新识别个体,从而产生严重的隐私风险。

实际上,《通用数据保护条例》(GDPR)明确要求数据控制者对最高风险的数据分析进行数据保护影响评估。因此,scikit-mobility为移动分析领域的科学家提供了用于评估与给定数据集分析相关的隐私风险的工具。

在文献中,隐私风险评估依赖于通过恶意对手的攻击来通过数据库中的移动对象的重新识别。隐私风险评估的常见框架。

假设在攻击期间,恶意对手以某种方式获得了对匿名化移动数据集的访问权限,即一个移动数据集,在该数据集中,与轨迹相关联的移动对象是未知的。此外,假设恶意对手以某种方式获取了关于在已获取的数据集中表示的个体的轨迹(或其中一部分轨迹)的信息。基于这些信息,通过估计该个体的移动数据在已获取的数据集中相对于其他个体的移动数据的唯一性来计算重新识别该个体的风险。

scikit-mobility提供了几种攻击模型,每个模型都是作为一个Python类实现的。例如,在位置攻击模型中,实现了LocationAttack类,恶意对手知道个体访问的一定数量的位置,但是他们不知道访问的时间顺序。要实例化一个LocationAttack对象,我们可以运行以下代码:

Image

参数knowledge_length指定恶意对手知道每个对象移动的位置的数量。根据knowledge_length位置的所有可能组合中的最坏情况组合,计算重新识别风险。

为了评估与作为TrajDataFrame表示的移动数据集相关联的重新识别风险,我们将其指定为assess_risk方法的输入,该方法返回一个包含TrajDataFrame中每个对象的uid和相关的重新识别风险的pandas DataFrame,其中风险以risk列(类型:float,范围:[0,1],其中0表示最低风险,1表示最高风险)的形式表示。

Image

由于对更大规模的数据集进行风险评估可能耗时较长,scikit-mobility提供了仅针对一部分对象进行评估的选项,通过参数targets。例如,在以下代码中,我们仅计算uid为1和2的对象的重新识别风险:

Image

在计算过程中,不一定对所有位置组合进行评估以评估移动对象的重新识别风险:当找到具有最大重新识别风险(例如,风险为1)的组合时,所有其他组合都不会被计算,以使计算更快。然而,如果用户希望无论如何计算所有组合,可以将参数force_instances(类型:布尔值,默认值:False)设置为True:

Image

结果是一个包含每个组合的参考编号的pandas DataFrame,并且对于每个组合,风险和组成该组合的每个位置由属性instance_elem指示。在表6中,我们列出了库中提供的隐私攻击方法。

9 结论与未来发展

在本文中,我们介绍了scikit-mobility,这是一个用于分析、生成和隐私风险评估的移动数据的Python库。scikit-mobility允许用户管理两种基本类型的移动数据——轨迹和流量,并提供了几个模块,每个模块专门用于移动数据分析的特定方面。

scikit-mobility的优势在于它提供了一个单一的环境,可以处理移动分析的不同方面,例如数据预处理和清理,计算移动度指标,生成合成轨迹和流量,以及评估隐私风险。该库的当前版本也有一些局限性。例如,由于pandas DataFrame必须完全加载到内存中,可以分析的移动数据集的大小受限于用户计算机内存的容量。此外,该库目前仅设计用于使用纬度和经度参考系统,但可以轻松适应任何参考系统。

我们对scikit-mobility的未来发展设想有两个方向。一方面,我们计划添加更多的模块,以涵盖更广泛的移动数据分析方面。例如,我们计划包括用于预测个体下一个访问位置的算法。我们还将考虑包括一个执行地图匹配的模块,即将轨迹的点分配给街道网络,并计算轨迹之间的相似性的模块。

另一方面,我们计划从计算角度改进该库。尽管在当前版本中,scikit-mobility易于使用,并且在几GB级别的移动数据集上效率相当高,但在TB级别的大规模移动数据集上不具备可扩展性。由于每年都有类似于pandas但计算效率更高的新Python库(例如dask)正在开发,我们计划重新实现scikit-mobility中的关键函数,以便利用这些库的计算效率。这个方面在目前并不是关键的,但当该库被科学界广泛采用时,它将变得至关重要。

原文:Scikit-mobility: a Python library for the analysis, generation and risk assessment of mobility data(https://doi.org/10.48550/arXiv.1907.07062)

代码请在https://github.com/scikit-mobility/scikit-mobility/tree/master/examples下载。

翻译整理:我得学城

🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉Python|MySQL|数据分析|数据可视化|机器学习与数据挖掘|爬虫等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递ImageImage