DTW 是 Dynamic Time Warping,可以动态扭曲时间轴,来计算两个不同长度的序列之间的相似性。详细介绍见百度百科http://baike.baidu.com/view/1647336.htm
百科中关于原理的叙述
如果路径已经通过了格点(n ,m ),那么下一个通过的格点(n ,m )只可能是下列三种情况之一:
(n ,m )=(n +1,m +2)
(n ,m )=(n +1,m +1)
(n ,m )=(n +1,m )
(n ,m )=(n +1,m +2)
(n ,m )=(n +1,m +1)
(n ,m )=(n +1,m )
错误的,其实应该是
如果路径已经通过了格点(n ,m ),那么下一个通过的格点(n ,m )只可能是下列三种情况之一:
(n ,m )=(n ,m +1)
(n ,m )=(n +1,m +1)
(n ,m )=(n +1,m )
(n ,m )=(n ,m +1)
(n ,m )=(n +1,m +1)
(n ,m )=(n +1,m )
算法原理的叙述错误,导致了后面matlab程序的错误,更改后的写法如下:
function dist = dtw(cols,rows) %% 直接距离矩阵 colSize = max(size(cols)); rowSize = max(size(rows)); % 帧匹配距离矩阵 dirtDist = zeros(rowSize,colSize); for i=1:rowSize for j= 1:colSize dirtDist(i,j)=(rows(i)-cols(j))^2; end end %% 累积距离矩阵 accumDist = zeros(rowSize,colSize); % DTW的第一行 accumDist(1,:) = cumsum(dirtDist(1,:)); %% 动态规划 for i = 2:rowSize for j = 1:colSize upper = accumDist(i-1,j); if j>1 left = accumDist(i,j-1); else left = realmax; end if j>1 diag = accumDist(i-1,j-1); else diag = realmax; end accumDist(i,j) = dirtDist(i,j) + min([upper,left,diag]); end end %% 最后的值 dist = sqrt(accumDist(end));
下面给出Java的代码实现:
package cn.edu.xjtu.utils; import java.util.List; /** * DTW(Danymic Time Wrapping,动态时间弯曲)算法的Java实现<br> * * DTW距离包括2部分:A)直接距离 B)累加距离,在本实现中直接距离采用的是Euclidean距离 * * @author lenovo */ public class JavaDTWOpti { private double[][] distanceMatrix; private List<Double> aList; private List<Double> bList; private void spreadCalc(int startColumn, int startRow, int endColumn, int endRow) { distanceMatrix = new double[bList.size()][aList.size()]; if (!(startColumn < endColumn) && !(startRow < endRow)) { throw new IllegalArgumentException("Error Occure!"); } // 将所有的数值转换成java的从0开始 startColumn = startColumn - 1; startRow = startRow - 1; endColumn = endColumn - 1; endRow = endRow - 1; // DTW距离第一部分:直接距离,这里计算采用Euclidean距离 double diredist = 0.0; // DTW距离第二部分:累积距离 double acumdist = 0.0; boolean stopIndex = false; do { // 计算某一顶点开始 横向 的所有DTW距离 for (int i = startColumn; i < endColumn + 1; i++) { diredist = aList.get(i) - bList.get(startRow); acumdist = minAcumDist(startRow, i); distanceMatrix[startRow][i] = diredist * diredist + acumdist; } // 计算某一顶点开始 纵向 的所有DTW距离 for (int i = startRow + 1; i < endRow + 1; i++) { diredist = aList.get(startColumn) - bList.get(i); acumdist = minAcumDist(i, startColumn); distanceMatrix[i][startColumn] = diredist * diredist + acumdist; } // 下一次推进的顶点 startColumn = startColumn + 1; startRow = startRow + 1; // 达到边界后,最多再推进一次; if (stopIndex) { break; } // 因为DTW经常处理的是两不同长度的向量,所以在推进的过程中会遇到长度问题 // 横向达到边界 if (!(startColumn < endColumn)) { stopIndex = true; } // 纵向达到边界 if (!(startRow < endRow)) { stopIndex = true; } } while (true); } private double[][] calcDTWDistance(int rowIndex, int columnIndex) { spreadCalc(1, 1, columnIndex, rowIndex); return distanceMatrix; } /** * 返回距离矩阵,其中的值都是平方后的,方便查看,以备后续处理<br> * aList={1,2,3},b={4,5,6,7},则矩阵是<br> * 9.0000 13.0000 14.0000 <br> * 25.0000 18.0000 17.0000 <br> * 50.0000 34.0000 26.0000 <br> * 86.0000 59.0000 42.0000 <br> * * @note 该方法当且仅当距离矩阵为空的时候,才会调用计算方法;否则,该方法只是返回上一次计算结果 * * @see calcDtwValue,主动计算距离矩阵 * * @return 距离平方的二维矩阵,行号是bList的元素确定,列号由aList的元素确定 */ public double[][] getDistanceMatrix() { if (this.distanceMatrix == null) { calcDTWDistance(bList.size(), aList.size()); } return this.distanceMatrix; } /** * 打印出距离矩阵,横向是aList,纵向是bList<br> * aList={1,2,3},b={4,5,6,7},则打印出来的是<br> * 9.0000 13.0000 14.0000 <br> * 25.0000 18.0000 17.0000 <br> * 50.0000 34.0000 26.0000 <br> * 86.0000 59.0000 42.0000 <br> * * @note 该方法不会调用计算方法;使用前请主动调用calcDtwValue计算距离矩阵 * * @see calcDtwValue */ public void printDistanceMatrix() { for (int i = 0; i < bList.size(); i++) { for (int k = 0; k < aList.size(); k++) { System.out.printf("%10.4f", distanceMatrix[i][k]); System.out.print("\t"); } System.out.println(); } } /** * 计算向量aList和bList的DTW距离 * * @return DTW距离,开平方后的 */ public double calcDtwValue() { this.calcDTWDistance(bList.size(), aList.size()); return Math.sqrt(distanceMatrix[bList.size() - 1][aList.size() - 1]); } private double minAcumDist(int rowIndex, int columnIndex) { double pre = getNumber(rowIndex - 1, columnIndex - 1); double left = getNumber(rowIndex, columnIndex - 1); double up = getNumber(rowIndex - 1, columnIndex); return min(pre, left, up); } private double getNumber(int rowIndex, int columnIndex) { if (rowIndex >= 0 && columnIndex >= 0) { return distanceMatrix[rowIndex][columnIndex]; } else if (rowIndex == -1 && columnIndex == -1) { return 0.0; } else { return Double.MAX_VALUE; } } private double min(double... inputs) { double minValue = inputs[0]; for (double each : inputs) { minValue = Math.min(minValue, each); } return minValue; } public List<Double> getaList() { return aList; } public void setaList(List<Double> aList) { this.aList = aList; } public List<Double> getbList() { return bList; } public void setbList(List<Double> bList) { this.bList = bList; } }
相关推荐
3. **DTW路径**:在距离矩阵基础上,DTW算法通过定义边界条件和成本函数,寻找从左上角到右下角的最低成本路径。这条路径反映了两个序列最佳的匹配关系。 4. **DTW warp窗口**:为了防止两个序列在匹配过程中过于...
### SAP B1 中 DTW 工具操作手册详解 #### 一、DTW 工具简介及作用 DTW(Data Transfer Workbench)是 SAP Business One(简称 SAP B1)中的一项重要工具,用于实现大批量数据高效地导入系统。这对于企业来说非常...
**DTW(动态时间规整)在语音识别中的应用** DTW,全称为Dynamic Time Warping,是一种在序列数据上进行比对的算法,尤其适用于处理时间轴不同但内容相似的序列,比如在语音识别中,它能有效地解决语音信号长度不...
动态时间规整(Dynamic Time Warping,简称DTW)是一种衡量两个序列相似度的算法,尤其在处理时间序列数据时非常有用。它允许两个序列在时间轴上进行非线性对齐,使得它们在对齐后的对应点之间的差异最小。在语音...
DTW(Dynamic Time Warping,动态时间规整)算法是一种在序列数据中寻找最佳匹配路径的方法,常用于语音识别、时间序列分析等领域。本资源包含DTW算法的C语言实现和其基本原理,有助于快速理解并应用DTW于语音识别...
标题中的"DTW.zip_dtw_visual c"表明这是一个与动态时间规整(DTW, Dynamic Time Warping)相关的C语言编程项目,可能包含了DTW算法的实现以及一个可视化界面。DTW是一种在序列数据中寻找最佳匹配路径的算法,常用于...
动态时间规整(Dynamic Time Warping,DTW)是一种在序列数据之间寻找最佳匹配路径的算法,尤其在语音识别和声纹识别领域有着广泛应用。它能够处理不同长度序列之间的匹配问题,不受序列长度差异的限制,使两个序列...
动态时间规整(Dynamic Time Warping, DTW)是一种在时间序列分析中广泛应用的算法,尤其在语音识别、生物信号处理、模式识别等领域具有显著的效果。DTW的主要目的是找到两个时间序列之间的最佳匹配路径,即使它们在...
在本案例中,DTW被应用来计算两个.wav音频文件的相似度。它克服了传统欧氏距离对齐不敏感的问题,使得两个在时间轴上不同步但内容相似的序列能够被正确匹配。 **DTW算法原理** DTW的核心思想是通过找到两个序列的...
动态时间规整(Dynamic Time Warping,简称DTW)是一种在序列数据中寻找最佳匹配路径的算法,尤其在语音识别、时间序列分析等领域有广泛应用。本文将深入探讨DTW算法的原理及其C语言实现。 一、DTW算法原理 DTW...
动态时间规整(Dynamic Time Warping,简称DTW)是一种在时间序列分析中广泛使用的算法,尤其适用于比较不同长度的时间序列。在Matlab环境中实现DTW,可以方便地对各种数据进行非线性、非同步的时间序列匹配,例如...
3. **生物信息学**:在DNA序列比对或蛋白质结构分析中,DTW可以用来比较不同长度的序列,找出它们的相似部分。 4. **金融分析**:在股票市场预测或经济指标研究中,DTW可用于识别模式或趋势的相似性,从而辅助决策...
3. 生物医学信号处理:在心电图(ECG)或脑电图(EEG)分析中,DTW可以帮助识别模式相似的信号段。 4. 运动分析:例如,比较运动员的不同动作,寻找最接近的动作模板。 总结,DTW算法在MATLAB中的实现涉及序列距离...
DTW算法-dtw.m DTW算法入门
3. **应用领域**:DTW在语音识别中用于比较不同人的发音,找出最相似的模板;在金融领域中可以用来分析股票价格趋势的相似性;在生物信息学中,DTW可用于基因序列的比对。 **二、MATLAB实现DTW** 1. **预处理**:...
这个压缩包中的“语音识别DTW算法的测试程序”显然是一个基于VC++开发的实验性项目,旨在实现DTW算法并进行初步的语音识别功能验证。虽然程序可能尚未完全完成,但仍然可以从中学习到DTW的基本原理和应用。 动态...
在MATLAB中,实现DTW通常涉及以下步骤: - 导入或生成时间序列数据。 - 编写函数计算两个序列的欧氏距离或其他合适的距离度量。 - 实现DTW算法,包括初始化矩阵、填充代价矩阵和寻找最优路径。 - 执行DTW算法,...
动态时间规整(Dynamic Time Warping,简称DTW)是一种在序列数据中寻找最佳匹配对的方法,常用于处理不同速度的信号对齐问题,尤其在语音识别、生物信息学(如指纹、DNA序列比对)以及金融数据分析等领域有着广泛...