Pattern recognition in time series
通过处理时间序列图,我想检测类似于以下内容的模式:
以示例时间序列为例,我希望能够检测到此处标记的模式:
为此,我需要使用哪种AI算法(我假设是行销学习技术)? 我可以使用任何库(C / C ++)吗?
这是我对ecg数据进行分区的一个小项目的示例结果。
我的方法是"切换自回归HMM"(如果您尚未听说的话,请点击Google),其中每个数据点都是使用贝叶斯回归模型从上一个数据点预测出来的。我创建了81个隐藏状态:一个用于捕获每个心跳之间数据的垃圾状态,以及80个单独的隐藏状态,分别对应于心跳模式中的不同位置。模式80状态直接从子采样的单拍模式中构建,并具有两个过渡-自过渡和过渡到模式中下一个状态。模式中的最终状态转换为自身或垃圾状态。
我通过维特比(Viterbi)训练对模型进行了训练,仅更新了回归参数。
在大多数情况下结果是足够的。类似的结构条件随机场可能会更好,但是如果您还没有标记数据,则训练CRF将需要在数据集中手动标记模式。
编辑:
这是一些示例python代码-它不是完美的,但是它提供了通用方法。它执行EM而不是Viterbi训练,后者可能会稍微稳定一些。
心电图数据集来自http://www.cs.ucr.edu/~eamonn/discords/ECG_data.zip
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | import numpy as np import numpy.random as rnd import matplotlib.pyplot as plt import scipy.linalg as lin import re data=np.array(map(lambda l: map(float,filter(lambda x: len(x)>0,re.split('\\s+',l))),open('chfdb_chf01_275.txt'))).T dK=230 pattern=data[1,:dK] data=data[1,dK:] def create_mats(dat): ''' create A - an initial transition matrix pA - pseudocounts for A w - emission distribution regression weights K - number of hidden states ''' step=5 #adjust this to change the granularity of the pattern eps=.1 dat=dat[::step] K=len(dat)+1 A=np.zeros( (K,K) ) A[0,1]=1. pA=np.zeros( (K,K) ) pA[0,1]=1. for i in xrange(1,K-1): A[i,i]=(step-1.+eps)/(step+2*eps) A[i,i+1]=(1.+eps)/(step+2*eps) pA[i,i]=1. pA[i,i+1]=1. A[-1,-1]=(step-1.+eps)/(step+2*eps) A[-1,1]=(1.+eps)/(step+2*eps) pA[-1,-1]=1. pA[-1,1]=1. w=np.ones( (K,2) , dtype=np.float) w[0,1]=dat[0] w[1:-1,1]=(dat[:-1]-dat[1:])/step w[-1,1]=(dat[0]-dat[-1])/step return A,pA,w,K #initialize stuff A,pA,w,K=create_mats(pattern) eta=10. #precision parameter for the autoregressive portion of the model lam=.1 #precision parameter for the weights prior N=1 #number of sequences M=2 #number of dimensions - the second variable is for the bias term T=len(data) #length of sequences x=np.ones( (T+1,M) ) # sequence data (just one sequence) x[0,1]=1 x[1:,0]=data #emissions e=np.zeros( (T,K) ) #residuals v=np.zeros( (T,K) ) #store the forward and backward recurrences f=np.zeros( (T+1,K) ) fls=np.zeros( (T+1) ) f[0,0]=1 b=np.zeros( (T+1,K) ) bls=np.zeros( (T+1) ) b[-1,1:]=1./(K-1) #hidden states z=np.zeros( (T+1),dtype=np.int ) #expected hidden states ex_k=np.zeros( (T,K) ) # expected pairs of hidden states ex_kk=np.zeros( (K,K) ) nkk=np.zeros( (K,K) ) def fwd(xn): global f,e for t in xrange(T): f[t+1,:]=np.dot(f[t,:],A)*e[t,:] sm=np.sum(f[t+1,:]) fls[t+1]=fls[t]+np.log(sm) f[t+1,:]/=sm assert f[t+1,0]==0 def bck(xn): global b,e for t in xrange(T-1,-1,-1): b[t,:]=np.dot(A,b[t+1,:]*e[t,:]) sm=np.sum(b[t,:]) bls[t]=bls[t+1]+np.log(sm) b[t,:]/=sm def em_step(xn): global A,w,eta global f,b,e,v global ex_k,ex_kk,nkk x=xn[:-1] #current data vectors y=xn[1:,:1] #next data vectors predicted from current #compute residuals v=np.dot(x,w.T) # (N,K) <- (N,1) (N,K) v-=y e=np.exp(-eta/2*v**2,e) fwd(xn) bck(xn) # compute expected hidden states for t in xrange(len(e)): ex_k[t,:]=f[t+1,:]*b[t+1,:] ex_k[t,:]/=np.sum(ex_k[t,:]) # compute expected pairs of hidden states for t in xrange(len(f)-1): ex_kk=A*f[t,:][:,np.newaxis]*e[t,:]*b[t+1,:] ex_kk/=np.sum(ex_kk) nkk+=ex_kk # max w/ respect to transition probabilities A=pA+nkk A/=np.sum(A,1)[:,np.newaxis] # solve the weighted regression problem for emissions weights # x and y are from above for k in xrange(K): ex=ex_k[:,k][:,np.newaxis] dx=np.dot(x.T,ex*x) dy=np.dot(x.T,ex*y) dy.shape=(2) w[k,:]=lin.solve(dx+lam*np.eye(x.shape[1]), dy) #return the probability of the sequence (computed by the forward algorithm) return fls[-1] if __name__=='__main__': #run the em algorithm for i in xrange(20): print em_step(x) #get rough boundaries by taking the maximum expected hidden state for each position r=np.arange(len(ex_k))[np.argmax(ex_k,1)<3] #plot plt.plot(range(T),x[1:,0]) yr=[np.min(x[:,0]),np.max(x[:,0])] for i in r: plt.plot([i,i],yr,'-r') plt.show() |
为什么不使用简单的匹配过滤器?或其一般的统计对应物称为互相关。给定一个已知的模式x(t)和一个嘈杂的复合时间序列,其中包含您的模式在a,b,...,z中移动,如
我不确定哪个软件包最适合这个。我在大学的某个时候做过类似的事情,我试图为一堆不同的图形自动检测x-y轴上的某些相似形状。您可以执行以下操作。
类标签如下:
- 没课
- 区域开始
- 地区中部
- 区域末端
功能如下:
窗口中的周围点宽11点
Weka是功能强大的机器学习软件集合,并且支持某些时间序列分析工具,但是我对该领域的了解还不足以推荐最佳方法。但是,它基于Java。您可以轻松地从C / C ++调用Java代码。
用于时间序列操纵的程序包主要针对股市。我在评论中建议了克罗诺斯;除了显而易见的之外,我不知道如何使用模式识别:系列中任何长度的良好模型都应能够预测,在距最后一个小凸起一定距离的小凸起之后,还会出现大凸起。也就是说,您的系列表现出自相似性,并且在Cronos中使用的模型旨在对其进行建模。
如果您不介意C#,则应从HCIL的人员那里请求一个TimeSearcher2版本-模式识别对于该系统来说,是绘制模式的样子,然后检查您的模型是否足够通用以捕获大多数实例。假阳性率低。您可能会找到最人性化的方法;所有其他要求在统计或模式识别策略方面具有相当的背景。
如果您愿意,我正在使用深度学习。它是用Java Deeplearning4j完成的。我正在试验LSTM。我尝试了1个隐藏层和2个隐藏层来处理时间序列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | return new NeuralNetConfiguration.Builder() .seed(HyperParameter.seed) .iterations(HyperParameter.nItr) .miniBatch(false) .learningRate(HyperParameter.learningRate) .biasInit(0) .weightInit(WeightInit.XAVIER) .momentum(HyperParameter.momentum) .optimizationAlgo( OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT // RMSE: ???? ) .regularization(true) .updater(Updater.RMSPROP) // NESTEROVS // .l2(0.001) .list() .layer(0, new GravesLSTM.Builder().nIn(HyperParameter.numInputs).nOut(HyperParameter.nHNodes_1).activation("tanh").build()) .layer(1, new GravesLSTM.Builder().nIn(HyperParameter.nHNodes_1).nOut(HyperParameter.nHNodes_2).dropOut(HyperParameter.dropOut).activation("tanh").build()) .layer(2, new GravesLSTM.Builder().nIn(HyperParameter.nHNodes_2).nOut(HyperParameter.nHNodes_2).dropOut(HyperParameter.dropOut).activation("tanh").build()) .layer(3, //"identity" make regression output new RnnOutputLayer.Builder(LossFunctions.LossFunction.MSE).nIn(HyperParameter.nHNodes_2).nOut(HyperParameter.numOutputs).activation("identity").build()) //"identity" .backpropType(BackpropType.TruncatedBPTT) .tBPTTBackwardLength(100) .pretrain(false) .backprop(true) .build(); |
发现了一些东西:
- LSTM或RNN非常擅长选择时间序列中的模式。
- 尝试了一个时间序列,并尝试了一组不同的时间序列。图案很容易挑出来。
- 它还试图挑选出一种节奏而不只是一种节奏的模式。如果有按周和按月的模式,则两者都将通过网络获悉。