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

目录

前言

接上文,我们已经知道如何利用夹角余弦来计算两条轨迹的相似度,也知道其中优势和劣势,夹角余弦方法作为一个基础的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

相关推荐
ocean21034 小时前
2025-2026年Python大厂面试高频问题
python·面试·面试经验
xn71335 小时前
实测 Codex CLI 0.154.0:response.failed 为什么会被 idle timeout waiting for SSE 覆盖
python·openai
李高钢5 小时前
Python Flask 框架入门:从零搭建你的第一个 Web 应用
前端·python·flask
码农学院5 小时前
外贸独立站GEO实战:用 Python 自动生成多语言 llms.txt 和 Schema 站点地图
人工智能·python·chatgpt·geo·geo优化·ai优化aio
jsjzsl25 小时前
独立自由度框架下核聚变的本体论本质与商业化技术新路径
人工智能·python·算法
Thomas.Sir5 小时前
第45课:TensorFlow|异常检测实战【工业设备数据故障识别模型搭建】
人工智能·python·tensorflow
数商云企5 小时前
2026年西安电商智能客服开发选数商云企,技术稳交付快
大数据·python
Patrick在香港5 小时前
Python 分析香港 AQHI 归档 1644 天:同一天的空气,早上 8 点报 3,下午 5 点报 10
开发语言·python·数据分析·api·restful·数据可视化·开放数据
SamChan905 小时前
Python批量处理PDF踩坑实录:中文编码、字体内嵌、多栏排版与内存占用
python·单片机·ai·pdf·机器翻译
3Q工具箱 - BraggTroy5 小时前
Python + PyInstaller 实战:从零打造 10 个 Windows 桌面小工具(附全部踩坑记录与核心代码)
开发语言·windows·python