基于缓冲原理计算轨迹相似度

目录

前言

接上文,我们已经知道如何利用夹角余弦来计算两条轨迹的相似度,也知道其中优势和劣势,夹角余弦方法作为一个基础的baseline有其存在的价值,很多学者也提出了各式各样的改进方法来计算轨迹相似度,但是,在上文,我们也提到了 在轨迹相似度计算的时候应该尽量使用与轨迹点直接关系的测度,如轨迹点的数目等,而不应该使用有轨迹点组合而成的几何对象,如线,面,多边形等 。 也就是回归事务数据本源,而不应该为了对比相似性而七拼八凑,这样反而回来带杂质,测度的不准。这一节,我们就来利用缓冲原理计算轨迹相似度。

预备知识

我们在GIS分析的时候,经常会对一个对象做缓冲来看其影响范围,而轨迹具有线性特质,现在,将如下轨迹L

L = [ p 1 , p 2 , ⋯   , p n ] L = [p_1,p_2, \cdots, p_n] L=[p1,p2,⋯,pn]

其中, p i ( 1 ≤ i ≤ n ) p_i(1\leq i\leq n) pi(1≤i≤n)表示第i个轨迹点的位置信息 p i = [ l n g i , l a t i ] p_i=[lng_i, lat_i] pi=[lngi,lati],改成集合形式

L = { p i ∣ 1 ≤ i ≤ n } L = \{p_i|1\leq i \leq n\} L={pi∣1≤i≤n}

如果对 L L L进行一定范围 δ \delta δ 的缓冲的话会形成一条固定宽度的长带

L ^ = { s ∣ d ( s , L ) < δ } \hat{L} = \{ s|d(s,L)<\delta\} L^={s∣d(s,L)<δ}

有另一条轨迹 Q Q Q
Q = [ q 1 , q 2 , ⋯   , q n ] Q = [q_1,q_2, \cdots, q_n] Q=[q1,q2,⋯,qn]

如果 Q Q Q有一些点有落在这个长带 L ^ \hat{L} L^范围里面,我们可以称 Q Q Q的这些点为 L L L这条轨迹可触达的点, Q Q Q与 L L L存在相似性,如果 Q Q Q没有轨迹点落在这个长带范围里面,则称 Q Q Q与 L L L不存在相似性。

思路与核心代码

既然两条轨迹的相似度与其可触达点有密切关系,那么,可以定义两条轨迹的相似度计算公式

S i m ( L , Q ) = λ 1 ∣ L Q ∣ ∣ L ∣ + λ 2 ∣ Q L ∣ ∣ Q ∣ Sim(L,Q) = \lambda_1 \frac{|L_Q|}{|L|} +\lambda_2 \frac{|Q_L|}{|Q|} Sim(L,Q)=λ1∣L∣∣LQ∣+λ2∣Q∣∣QL∣

其中, L Q L_Q LQ表示轨迹 L L L被轨迹 Q Q Q缓冲出的可触达的点做成的集合, Q L Q_L QL表示轨迹 Q Q Q被轨迹 L L L缓冲出的可触达的点做成的集合, ∣ L ∣ |L| ∣L∣表示轨迹 L L L的轨迹点的个数, ∣ Q ∣ |Q| ∣Q∣表示轨迹 Q Q Q的轨迹点的个数, λ i \lambda_i λi表示各自对应可触达点的权重,可以是每条轨迹点的占所有轨迹点的比重;

python 复制代码
def toleranceTest(traj1, traj2): #容差检测,检测两条轨迹的对应轨迹点的距离,并给出缓冲范围的建议值
    max_lng = np.max([traj1['lng'].max(), traj2['lng'].max()])
    min_lng = np.min([traj1['lng'].min(), traj2['lng'].min()])
    max_lat = np.max([traj1['lat'].max(), traj2['lat'].max()])
    min_lat = np.min([traj1['lat'].min(), traj2['lat'].min()])
    dot1 = [min_lng, min_lat]
    dot2 = [max_lng, min_lat]
    dot3 =  [max_lng,  max_lat]
    dot4  = [min_lng, max_lat]
    rectangle = Polygon([dot1, dot2, dot3, dot4])
    area = rectangle.area
    # print("所在区域范围面积", area)
    if  area< 0.00001:
        eps = 0.0001 #10米
    elif area<0.0001:
        eps = 0.0002 #20米
    elif area<0.001:
        eps = 0.0003 #30米
    elif area<0.01:
        eps = 0.0004 #40米
    elif area<0.1:
        eps = 0.0005 #50米
    elif area<1:
        eps = 0.001 #100米
    else:
        eps = 0.0015 #150米
    # print("缓冲宽度", eps)
    return eps

def bufferSimilarity(traj1, traj2, eps): #缓冲相似度
    traj1_points  = list(zip(traj1['lng'], traj1['lat']))
    traj2_points  = list(zip(traj2['lng'], traj2['lat']))
    traj1_line = LineString(traj1_points)
    traj2_line = LineString(traj2_points)
    traj1_buffer = traj1_line.buffer(eps) #缓冲50米
    traj2_buffer = traj2_line.buffer(eps) #缓冲50米
    traj1_buffer_cnt = 0 #轨迹1缓冲的点
    traj2_buffer_cnt = 0 #轨迹2缓冲的点数
    for point in traj2_points:
        if traj1_buffer.contains(Point(point)):  # True or False
            traj1_buffer_cnt +=1
    for point in traj1_points:
        if traj2_buffer.contains(Point(point)):
            traj2_buffer_cnt +=1
    buffer_sim_value = (traj1_buffer_cnt/len(traj2_points)*(len(traj2_points)/(len(traj1_points)+len(traj2_points))))+\
                        (traj2_buffer_cnt/len(traj1_points)*(len(traj1_points)/(len(traj1_points)+len(traj2_points))))
    print("缓冲相似度", buffer_sim_value)
    return buffer_sim_value

优缺点分析

考虑到轨迹跨度范围的不同,有些轨迹可能只有几公里,有些几十公里,有些却有上百公里,不同跨度所需要的缓冲宽度也是不一样的,为此,可以设计一个容差检测,其目的是为不同长度的轨迹对比提供一个缓冲宽度参考,直白一点的就是长的轨迹,缓冲宽一点,短的轨迹缓冲窄一点,这种映射关系可以设计成压缩映射,可以找轨迹范围四至的面积作为标的标的物比,具体见toleranceTest函数,主函数就是把两者相互缓冲对方的轨迹点计算出来,然后利用类似杰卡德公式来计算两条轨迹的相似度。

数值实验

下面是对不同运单利用缓冲原理计算出来的相似度对比,整体还不错,既考虑了相互对称性,有考虑各自轨迹点数的影响,具有很好的均衡性和稳健性。

参考文献

1,轨迹相似性度量方法

https://blog.csdn.net/weixin_39910711/article/details/109333641

2,【ST】轨迹相似性度量

https://zhuanlan.zhihu.com/p/384362352

3,轨迹相似性度量

https://zhuanlan.zhihu.com/p/148797145

4,向量相似度

https://blog.csdn.net/Gentleman_Qin/article/details/110465518

5,shapely官方文档

https://www.osgeo.cn/pygis/shapely.html

6,经纬度保留到不同小数位对应的精度

https://blog.csdn.net/qq_39805362/article/details/117329099

相关推荐
pzx_00112 分钟前
【内积】内积计算公式及物理意义
数据结构·python·opencv·算法·线性回归
一丝晨光13 分钟前
逻辑运算符
java·c++·python·kotlin·c#·c·逻辑运算符
ForRunner12316 分钟前
使用 Python 高分解决 reCAPTCHA v3 的指南
数据库·python·microsoft
躺平的花卷1 小时前
Python爬虫案例六:抓取某个地区某月份天气数据并保存到mysql数据库中
数据库·爬虫·python·mysql
虚拟搬运工1 小时前
Python类及元类的创建流程
开发语言·chrome·python
学步_技术2 小时前
Python编码系列—Python原型模式:深克隆与高效复制的艺术
开发语言·python·原型模式
Desire.9842 小时前
Python 数学建模——灰色关联度分析
python·数学建模·灰色关联度
小鹿( ﹡ˆoˆ﹡ )2 小时前
Python中的树与图:构建复杂数据结构的艺术
开发语言·python
阡之尘埃2 小时前
Python数据分析案例59——基于图神经网络的反欺诈交易检测(GCN,GAT,GIN)
python·神经网络·数据挖掘·数据分析·图神经网络·反欺诈·风控大数据
xiaojiesec2 小时前
第157天: 安全开发-Python 自动化挖掘项目&SRC 目标&FOFA 资产&Web 爬虫解析库
python·安全