轨迹聚类算法分为三步骤:
- 轨迹特征点提取,轨迹划分
- 轨迹聚类
- 分段轨迹聚合
1:原始轨迹划分
划分原则:采用MDL原则(最小描述原则),要求选择总描述长度最小的模型。
MDL原则包括两个部分:
- L(H):描述压缩模型(或编码方式)所需要的长度。
- L(D|H):描述利用压缩模型所编码的数据所需要的长度。
如图所示:
不同轨迹距离计算
轨迹划分MDL计算
轨迹划分算法描述
轨迹划分算法:
输入:轨迹TR_i = p_1p_2p_3...p_{len_i}
输出:CP_i集合代表轨迹的特征点
算法:
- 将p_1加入CP_i集合中;(初始点)
- startINdex := 1, length := 1;
- 当 startIndex + length \leq len_i 时
- currIndex := startIndex + length;
- cost_{par} := MDL_{par}(P_{startINdex},p_{currIndex});
- cost_{nopar} := MDL_{nopar}(p_{startIndex},p_{currIndex});
- if(cost_{par} > cost_{nopar}) then
- 将p_{currIndex-1}加入CP_i集合;
- startIndex := currINdex - 1,length := 1;
- else
- length := length + 1;
- 将 p_{len_i}加入CP_i集合;
算法思想:
我们近似划分轨迹的关键思想是将局部最优集合视为全局最优。当假设p_i和p_j仅是特征点时,令MDL_{par}(p_i,p_j)表示p_i和p_j(i < j)之间的轨迹的MDL成本(= L(H) + L(D|H))。当假设在p_i和p_j之间没有特征点时,即当保留原始轨迹时,令MDL_{nopar}(p_i,p_j)表示MDL成本。我们注意到MDL_{nopar}(p_i,p_j)中的L(D|H)为零。然后,局部最优是最长轨迹分区p_ip_j,其满足每k的MDL_{par}(p_i,p_k)≤MDL_{nopar}(p_i,p_k),使得i < k ≤ j。如果前者小于后者,我们知道选择p_k作为特征点会使MDL成本小于不选择它。此外,为了简洁起见,我们尽可能地增加该轨迹分区的长度。我们为轨迹中的每个点计算MDL_{par}和MDL_{nopar}(第5~6行)。如果MDL_{par}大于MDL_{nopar},我们将前一个点p_{currIndex-1}插入到特征点的集合CP_i中(第8行)。然后,我们从那一点开始重复相同的过程(第9行)。否则,我们增加候选轨迹分区的长度(第11行)。
2. 轨迹聚类算法
基于密度的聚类算法,思想同DBSCAN算法:
核心线段等示例
线段聚类算法:
输入:1. 线段集合:D = {L_1,L_2,...,L_{num_{l_n}}}
2. 两个参数\epsilon和MinLns
算法:
- 设置clusterId 为0; /* 初始化ID */
- 将D中所有线段标记为未分类;
- 对每个线段L(L ∈ D):
- 如果线段L为未定义线段,那么:
- 计算L的邻域N_ε (L);
- 如果$(|N_ε (L)| ≥ MinLns) ,那么:
- 分配clusterId给∀X ∈ N_ε (L);
- 将N_ε (L) - {L} 插入队列 Q;
- 扩展,ExpandCluster(Q, clusterId, ε, MinLns);
- clusterId +1; /* 新的id */
- else
- 标记 L 为噪声点;
- 将线段∀L ∈ D 分配到自己的聚类C_{clusterId}中;
/* 检查线段轨迹基数 */ - 对每个C(C ∈ O): /* 当类中的线段基数大于MinLns时该类可用,否则删除掉该类 */
- 如果(|PTR(C)| < MinLns),那么:
- 从O集合中删除集合C;
/* 函数ExpandCluster()计算密度相连集合 */ - ExpandCluster(Q, clusterId, ε, MinLns) {
- 当 (Q \neq \emptyset) 时:
- M := Q中的第一条线段;
- 计算 N_ε (M);
- 如果(|N_ε (M)| ≥ MinLns) ,那么:
- 对于每个X,(X ∈ N_ε (M)) :
- 如果 X 未定义或者为噪声点,那么:
- 分配clusterId给X;
- 如果X未定义,那么:
- 将X插入队列Q;
- 从队列Q中移除M;
- }
3. 轨迹可视化即轨迹聚合
基于密度分为多个簇,然而对于一个簇中所有轨迹的走向及其它特征并没有直观简洁地展示出来,因此有必要提取簇中的整体信息并用可视化的手段展示出来方便进一步分析。
一种可行的方法是计算簇中的平均轨迹,用平均轨迹来代表整个簇中轨迹的整体信息。原文中将这条轨迹形象地称为“代表性轨迹(Representative Trajectory)”。
用一条垂直于簇中线段的平均走向的直线扫描各条线段,每次经过一条线段的起点或终点时都要判断一下此时相交线段的个数是否不小于MinLns。若是,则计算一个所有交点的平均点并存储于列表中,否则不予理会。最终生成的列表即为平均轨迹的结点坐标信息。
这里忽略了一个问题,簇中线段的平均走向如何计算?
原文中是将簇中所有的线段用向量表示,向量的长度为线段的长度,将所有向量相加并单位化即可代表簇中线段的平均走向。
除此之处,由于算法要反复计算扫描直线与簇中线段的交点,如果扫描直线与x轴所成角度不为90度的整数倍,则计算量稍大。因此算法对此进行了预处理,将坐标系旋转使X轴与平均走向平行,这样计算起来就方便许多。
簇轨迹hebing
轨迹可视化算法
输入:1. 一个C_i簇
2. MinLns
3.一个光滑的参数\gamma
输出: C_i簇的代表性轨迹PTR_i
算法:
- 计算线段的平均垂直向量\vec{V};
- 旋转坐标轴,使得X坐标轴平行于\vec{V};
- P为C_i簇中线段开始和结束点的集合;
/* X‘的值代表了X’坐标轴*/ - 依据X'坐标轴的值将P中的点排序;
- 对每个p,(p ∈ P) :
- num_p代表包含点p的线段数量
- 如果num_p \geq MinLns,那么:
- diff := p和之前的点之间的距离;
- 如果diff \geq \gamma,那么:
- 计算平均坐标值avg'_p;
- 撤销坐标轴的旋转并获得点avg_p;
- 将avg_p加入到PTR_i的末尾;
网友评论