动态时间规整算法 Python和matlab实现

动态时间规整/规划(Dynamic Time Warping, DTW),给定两个离散的序列或时间序列,DTW能够衡量这两个序列的相似程度,或者说两个序列的距离,广泛应用于语音识别领域。

关于动态时间规整理论的详细解释:参考https://wenku.baidu.com/view/080ffe1358fafab069dc028b.html 

最后要得到的归整路径是距离最短的一个归整路径:其中Dist(i,j)为初始的欧式距离的平方

动态时间规整算法 Python和matlab实现_第1张图片

# -*- coding: utf-8 -*-
"""
Created on Tue Mar  5 21:33:06 2019
@author: Melo琦
python
"""

import numpy as np
def dtw(seq1,seq2): #动态时间规整:形参为时间序列seq1,seq2 
    m1=len(seq1)
    m2=len(seq2)
    #初始化距离矩阵
    distance=np.zeros(shape=(m1,m2)) #m1行,m2列的距离矩阵
    for i in range(m1):
        for j in range(m2):
            distance[i,j]=(seq1[i]-seq2[j])**2 #一维数组元素之间的欧式距离的平方    
    #构建一个与矩阵d相同大小累积距离矩阵的D
    D=np.zeros(shape=(m1,m2))
    D[0,0]=distance[0,0] #第一个元素和距离矩阵保持一致
    for i in range(1,m1): #累积距离矩阵的左边界
        D[i,0]=distance[i,0]+D[i-1,0]
    for j in range(1,m2):#累积距离矩阵的上边界
        D[0,j]=distance[0,j]+D[0,j-1]
    for i in range(1,m1):
        for j in range(1,m2):
            D[i,j]=distance[i,j]+np.min([D[i-1,j-1],D[i-1,j],D[i,j-1]])
    return D[m1-1,m2-1] #函数返回值为最小动态规划路径


#动态时间规整实例化 
data1=[1,2,3,4,4,5,5,6,7]#这里也可以用实际的Excel数据  注意数据类型为向量或1维数组
data2=[2,3,4,5,6,7,8,9,9]#这里也可以用实际的Excel数据  注意数据类型为向量或1维数组
print(dtw(data1,data2))#调用函数
%matlab实现动态时间规整
function [Dist,D,k,w]=dtw(t,r)
%Dynamic Time Warping Algorithm
%Dist is unnormalized distance between t and r
%D is the accumulated distance matrix
%k is the normalizing factor
%w is the optimal path
%t is the vector you are testing against
%r is the vector you are testing
[N,rows]=size(t);
[M,rows]=size(r);
for n=1:N
   for m=1:M
       d(n,m)=(t(n)-r(m))^2;
   end
end
%d=(repmat(t(:),1,M)-repmat(r(:)',N,1)).^2; %this replaces the nested for loops from above Thanks Georg Schmitz 
D=zeros(size(d));
D(1,1)=d(1,1);
for n=2:N
    D(n,1)=d(n,1)+D(n-1,1);
end
for m=2:M
    D(1,m)=d(1,m)+D(1,m-1);
end
for n=2:N
    for m=2:M
        D(n,m)=d(n,m)+min([D(n-1,m),D(n-1,m-1),D(n,m-1)]);
    end
end
Dist=D(N,M);
n=N;
m=M;
k=1;
w=[];
w(1,:)=[N,M];
while ((n+m)~=2)
    if (n-1)==0
        m=m-1;
    elseif (m-1)==0
        n=n-1;
    else 
      [values,number]=min([D(n-1,m),D(n,m-1),D(n-1,m-1)]);
      switch number
      case 1
        n=n-1;
      case 2
        m=m-1;
      case 3
        n=n-1;
        m=m-1;
      end
  end
    k=k+1;
    w=cat(1,w,[n,m]);
end

 

你可能感兴趣的:(python,机器学习,python,数据挖掘)