我试图了解如何对一组时间序列数据(每日股票价格,温度等)进行细分,并且遇到了一本书,解释了如何进行SWAB(滑动窗口和底部 - 分段算法,但我不太了解它。该分割是超声处理算法的一部分。以下文字来自"多媒体数据挖掘和分析:颠覆性创新"。
SWAB细分 算法得到四个参数 - 输入文件(时间序列数据),输出 文件(分段数据),最大错误和标称属性的指示。 经过一系列不同大小的时间序列实验 对于段数的值,我们选择了相应的默认数量 细分如下。时间序列的时间序列大小的25-50%小于100 观察结果,20-35%的时间序列,100-200观察,15-25% 时间序列超过200个观测值。如果用户不想使用 出于任何原因的默认值,他可以输入自己的段数作为参数 算法。 从最小和最大错误的默认值开始,我们 第一次运行分割算法并获得最小数量 给定时间序列的段(最大误差越大,段越少) 将被发现)。然后我们减少最大误差(因此增加数量 找到的段)试图缩小误差的上限和下限 将基数除以2的幂(如二进制搜索)。每次跑完之后 当前最大误差的分割算法,我们测试是否这样 value给出了最佳段数的更好近似,因此是a 最佳最大误差的上限或下限。如果是这样,我们推进 适当绑定到此值。一开始,只有上限受到影响。 但是,一旦我们发现下限提供的分段多于 最佳,我们继续通过较小的步骤寻找最佳段数: 下一个最大误差是当前上限和下限之间的平均值。 以下是我们对许多不同时间序列数据库的经验 最佳最大误差通常在3-4次迭代中找到。收敛速度 取决于输入时间序列数据库本身。如果算法没有收敛 在20次迭代中,我们停止搜索并继续下一个声处理步骤 使用在第20次迭代中找到的片段。
因此,例如,如果我有150个观测值的时间序列数据(相当于20-35%的默认段数),我需要采取哪些确切的步骤来分割数据?
感谢任何帮助,谢谢。
答案 0 :(得分:3)
确切步骤
以下是该方法的简明描述:
滑动窗口算法通过锚定a的左点来工作 时间序列的第一个数据点的潜在部分, 然后尝试用右边的数据近似 增加更长的部分。在某些时候我,错误的 潜在的段大于用户指定的阈值,所以 从锚到i -1的子序列被转换成 细分。将锚移动到位置i,并重复该过程 直到整个时间序列变成了分段 线性逼近。
基于此,算法的伪代码如下。请参阅我在代码中的注释,以了解具体情况。
//function takes a set of points T and a max error
function Sliding_Window(T, max_error)
anchor = 1;
while (not finished segmenting time series) {
i=2;
//keep making subsets of progressively larger size
//until the error of the subset is greater than the max error
//t[anchor: anchor + i] represents the elements of the set
//from index (anchor) to index (anchor + i)
//this could be an implemented as an array
while (calculate_error(T[anchor: anchor+i]) < max_error) {
i=i+1;
}
//add the newly found segment to the set of all segments
Seg_TS = concat(Seg_TS, create_segment(T[anchor: anchor + (i-1)]);
//and increment the anchor in preparation for creating a new segment
anchor = anchor + i;
}
}
“错误”的定义
您似乎不清楚的一件事是在这种情况下“错误”的含义。以下段落很好地解释了它:
所有分割算法也需要一些方法来评估 适合潜在细分的品质。常用的措施 与线性回归结合是平方和,或者 残差。这是通过采用所有垂直计算的 最佳拟合线与实际数据点之间的差异, 将它们平方然后将它们相加在一起。另一个常见的 使用的拟合度度量是最佳拟合度之间的距离 线和垂直方向上最远的数据点。
换句话说,这里可以使用多种方法来表示“错误”。统计中使用的两种常见方法是平方和和最大垂直距离。从理论上讲,你甚至可以为此编写自己的函数,只要它返回的数字在某种程度上表明该段代表给定点集的程度。
有关平方和方法的更多信息,请访问:https://en.wikipedia.org/wiki/Residual_sum_of_squares
如果你想自己实现它,一些伪代码可能如下所示:
function calculateSegmentErrorUsingSumOfSquares() {
int sum = 0;
for each (point in set_approximated_by_segment) {
int difference = point.y_coordinate - approximation_segment.y_at_x(point.x_coordinate)
sum = sum + (difference * difference)
}
return sum
}
请注意,您使用的任何方法都可能具有某些优点和缺点。有关更多信息和参考资料,请参阅下面的Jason的评论,但关键是:确保您选择的任何错误函数都能很好地响应您期望的数据类型。
<强>来源强>