`
xiaolongfeixiang
  • 浏览: 236417 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

百度百科中关于DTW的3处错误及改正

阅读更多

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 ,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;
	}

}
 
 

 

0
0
分享到:
评论

相关推荐

    DTW操作手册

    ### SAP B1 中 DTW 工具操作手册详解 #### 一、DTW 工具简介及作用 DTW(Data Transfer Workbench)是 SAP Business One(简称 SAP B1)中的一项重要工具,用于实现大批量数据高效地导入系统。这对于企业来说非常...

    DTW的Java实现

    动态时间规整(Dynamic Time Warping,简称DTW)是一种衡量两个序列相似度的算法,尤其在处理时间序列数据时非常有用。它允许两个序列在时间轴上进行非线性对齐,使得它们在对齐后的对应点之间的差异最小。在语音...

    DTW_dtw_语音识别matlab_

    **DTW(动态时间规整)在语音识别中的应用** DTW,全称为Dynamic Time Warping,是一种在序列数据上进行比对的算法,尤其适用于处理时间轴不同但内容相似的序列,比如在语音识别中,它能有效地解决语音信号长度不...

    DTW算法 c实现及原理

    DTW(Dynamic Time Warping,动态时间规整)算法是一种在序列数据中寻找最佳匹配路径的方法,常用于语音识别、时间序列分析等领域。本资源包含DTW算法的C语言实现和其基本原理,有助于快速理解并应用DTW于语音识别...

    DTW.zip_dtw_visual c

    标题中的"DTW.zip_dtw_visual c"表明这是一个与动态时间规整(DTW, Dynamic Time Warping)相关的C语言编程项目,可能包含了DTW算法的实现以及一个可视化界面。DTW是一种在序列数据中寻找最佳匹配路径的算法,常用于...

    语音识别中dtw算法详解,用于声纹识别时非常有用

    动态时间规整(Dynamic Time Warping,DTW)是一种在序列数据之间寻找最佳匹配路径的算法,尤其在语音识别和声纹识别领域有着广泛应用。它能够处理不同长度序列之间的匹配问题,不受序列长度差异的限制,使两个序列...

    语音识别中DTW算法的改进

    动态时间规整(Dynamic Time Warping, DTW)是一种在时间序列分析中广泛应用的算法,尤其在语音识别、生物信号处理、模式识别等领域具有显著的效果。DTW的主要目的是找到两个时间序列之间的最佳匹配路径,即使它们在...

    DTW.zip_DTW 相似度_DTW 计算相似度_dtw wav_wav相似度_“SLN-DTW”

    在本案例中,DTW被应用来计算两个.wav音频文件的相似度。它克服了传统欧氏距离对齐不敏感的问题,使得两个在时间轴上不同步但内容相似的序列能够被正确匹配。 **DTW算法原理** DTW的核心思想是通过找到两个序列的...

    DTW算法实现代码_C++_dtw_dtw算法c++_

    3. **DTW路径**:在距离矩阵基础上,DTW算法通过定义边界条件和成本函数,寻找从左上角到右下角的最低成本路径。这条路径反映了两个序列最佳的匹配关系。 4. **DTW warp窗口**:为了防止两个序列在匹配过程中过于...

    DTW算法 C语言代码

    动态时间规整(Dynamic Time Warping,简称DTW)是一种在序列数据中寻找最佳匹配路径的算法,尤其在语音识别、时间序列分析等领域有广泛应用。本文将深入探讨DTW算法的原理及其C语言实现。 一、DTW算法原理 DTW...

    Matlab实现DTW算法(完整源码).zip

    动态时间规整(Dynamic Time Warping,简称DTW)是一种在时间序列分析中广泛使用的算法,尤其适用于比较不同长度的时间序列。在Matlab环境中实现DTW,可以方便地对各种数据进行非线性、非同步的时间序列匹配,例如...

    DTW_dtw_时间序列_dtw算法_时间序列分类_

    3. **生物信息学**:在DNA序列比对或蛋白质结构分析中,DTW可以用来比较不同长度的序列,找出它们的相似部分。 4. **金融分析**:在股票市场预测或经济指标研究中,DTW可用于识别模式或趋势的相似性,从而辅助决策...

    使用matlab 实现DTW算法(源代码)

    3. 生物医学信号处理:在心电图(ECG)或脑电图(EEG)分析中,DTW可以帮助识别模式相似的信号段。 4. 运动分析:例如,比较运动员的不同动作,寻找最接近的动作模板。 总结,DTW算法在MATLAB中的实现涉及序列距离...

    DTW算法-dtw.m

    DTW算法-dtw.m DTW算法入门

    matlab实现DTW算法

    3. **应用领域**:DTW在语音识别中用于比较不同人的发音,找出最相似的模板;在金融领域中可以用来分析股票价格趋势的相似性;在生物信息学中,DTW可用于基因序列的比对。 **二、MATLAB实现DTW** 1. **预处理**:...

    语音识别中DTW算法的测试程序

    这个压缩包中的“语音识别DTW算法的测试程序”显然是一个基于VC++开发的实验性项目,旨在实现DTW算法并进行初步的语音识别功能验证。虽然程序可能尚未完全完成,但仍然可以从中学习到DTW的基本原理和应用。 动态...

    dtw算法用matlab代码实现,有图

    在MATLAB中,实现DTW通常涉及以下步骤: - 导入或生成时间序列数据。 - 编写函数计算两个序列的欧氏距离或其他合适的距离度量。 - 实现DTW算法,包括初始化矩阵、填充代价矩阵和寻找最优路径。 - 执行DTW算法,...

    Matlab的DTW算法的工具包

    动态时间规整(Dynamic Time Warping,简称DTW)是一种在序列数据中寻找最佳匹配对的方法,常用于处理不同速度的信号对齐问题,尤其在语音识别、生物信息学(如指纹、DNA序列比对)以及金融数据分析等领域有着广泛...

Global site tag (gtag.js) - Google Analytics