计算两个时间序列之间一致性的清晰步骤

机器算法验证 r 时间序列 光谱分析
2022-04-10 04:45:10

我最初将其发布在 stackoverflow.com 上,然后将其删除并移至此处

我的问题类似于 两个离散傅立叶变换的相似性(特别是选定的答案)。我还从这个 R 帮助线程中收集了一些有用的信息。

然而,我坚持这个过程的实际实施。

我有两个傅立叶级数;我的最终目标是计算加权相干性的总和。(实际上我有数百万个与像素对应的系列,但是,我们现在只称它为两个)。

    TS1 <- c(5051.29, 5355.31, 5602.18, 5784.4, 5896.45, 5934.9, 5898.6, 
5788.64, 5608.37, 5363.27, 5060.78, 4710.09, 4321.86, 3907.89, 
3480.75, 3053.42, 2638.89, 2249.75, 1897.82, 1593.81, 1346.93, 
1164.71, 1052.67, 1014.21, 1050.52, 1160.47, 1340.74, 1585.84, 
1888.33, 2239.02, 2627.25, 3041.22, 3468.36, 3895.69, 4310.22, 
4699.36, 5051.29)
    TS2 <- c(4192.83, 4532.62, 4836.41, 5094.96, 5300.41, 5446.53, 5528.88, 
5544.95, 5494.25, 5378.33, 5200.71, 4966.78, 4683.65, 4359.93, 
4005.45, 3630.98, 3247.9, 2867.85, 2502.38, 2162.59, 1858.8, 
1600.25, 1394.8, 1248.67, 1166.33, 1150.26, 1200.95, 1316.87, 
1494.5, 1728.43, 2011.55, 2335.28, 2689.76, 3064.23, 3447.31, 
3827.36, 4192.83)

从上面的链接我看到我需要计算每个频率的交叉谱的相干性,并对具有更高功率谱密度的频率进行加权。

我知道我可以从

spectrum(data.frame(TS1, TS2))$spec

我知道我可以使用以下方法提取连贯性:

spectrum(data.frame(TS1, TS2))$coh

我可以看到提取的相干性值始终等于 1。似乎对此的“解决方案”是以某种方式滞后时间序列。

我不确定如何 1)计算最佳滞后,特别是因为我希望它在所有相干性计算中具有可比性,以及 2)如何在频谱()中指定滞后。spec.pgram 采用“跨度”,但这些似乎更多地与平滑而不是偏移有关。

我尝试了此处定义的最大 ccf 函数,但在许多情况下(不在我提供的示例集中,您必须相信我)返回的“最佳滞后”为 0,这是有道理的,因为 ccf 为 1,但实际上并不是我想要的。

我应该使用acf()还是ccf()手动计算相干性?我需要执行哪些步骤(R 函数会非常有用)才能从我所在的位置获得单个加权相干值?

3个回答

以下是我按顺序简要总结的问题,因为每个问题本身都是一个有趣的问题,然后用我的解决方案跟进:

i) 如何使两个时间序列不滞后,从而使由于滞后而丢失的数据最少,同时最大化互相关或光谱相干性。

ii)当您处理多变量时间序列时如何做到这一点。因为它大于两者,所以它就像在滞后数据集中的各种时间序列的同时优化求解一个魔方,以保持 (i) 的总和度量。

iii) 如何计算加权相干性?

我将跳过 ii) 并回答 i) 和 iii) 由于利益冲突的原因以及关于我在 ii) 上的工作的研究合作/保密协议。我知道 iii) 恰好是从 i) 开始的中心问题。

我对 iii) 的解决方案

预处理步骤:假设您有两个时间序列 t1 和 t2。确定一个 CCF 最大化滞后,比如 optLag 和 unlag t1 和 t2 asunlaggedTS = lag(t2,optLag)并执行数据集的时间序列联合 as unionTS = ts.union(t1,unlaggedTS)之后,由于时间序列不滞后会在您因滞后而丢失条目时产生一些 NA,因此您需要根据需要在 unionTS 中将这些值设置为零——这意味着在 NA 点处没有观察到任何内容。

第 2 步: 现在,获取一个绑定时间序列,并根据需要使用跨度参数。

bindTSPair= abind(((spectrum(unionTS,span=c(16,16),plot=F)$spec)[,1]),((spectrum(unionTS,span=c(16,16),plot=F)$spec)[,2])) 

在它之后,只需将 bindTSPair 中的数据标准化,如下所示:

normalizedTS=round(data.Normalization(c(bindTSPair),type="n4"),6)

然后得到以下两半:

TSHalf1=normalizedTS[1:(length(bindTSPair)/2)]

TSHalf2=normalizedTS[((length(bindTSPair)/2)+1):(length(bindTSPair))]

然后最终获得光谱相干性的“加权”版本,如下所示:

 weightedCoherence=sum((10*(TSHalf1 + TSHalf2)) * (spectrum(unionTS,span=c(10,10),plot=F)$coh))

您可以根据需要更改权重或使用“先前”信息。

我对 i) 的解决方案以获得 CCF 最大化滞后:

 for(i in 2:ncol(myTS))
{
    for(j in 2:ncol(myTS))
    {
r=ccf(myTS[,i],myTS[,j],lag.max=1000,plot=TRUE)
tp=sort((r$acf),index.return=TRUE)$ix
tn=sort((r$acf),index.return=TRUE,decreasing=T)$ix
cn=r$acf[tn[length(tn)]]
    cp=r$acf[tp[length(tp)]]
    if(abs(cp) > abs(cn))
    {
    temp=r$lag[tp[length(tp)]]
    	 tcc=cp
    	}
    		if(abs(cn) > abs(cp))
    		{
    		temp=r$lag[tn[length(tn)]]
    		tp=tn
    		 tcc=cn
    		}
    if(abs(cn) > abs(cp))
    {
    temp=r$lag[tp[length(tp)]]
}
show(i)
if(length(tp) != 0)
{

mlag[i,j]=temp
mcc[i,j]=tcc
}
    }

}

mlag=mlag[2:ncol(myTS),2:ncol(myTS)]
mlag=data.frame(mlag)

除非您的任务是实际实现相干性计算,否则我不会这样做,因为必须有一个包。例如,我看到了coh包,我自己没有使用过。这个函数似乎可以完成特定频率 f 所需的一切,因此您可以在频率范围内循环调​​用它。

在 matlab 中有一个叫做mscohere的函数,它产生一个像这样的整个图,它是相干度的平方 在此处输入图像描述

我为使用 Matlab 示例道歉,但我自己还没有在 R 中进行任何光谱分析。虽然概念是一样的。

用于seewave::coh()提取最大相干点的相干值和滞后值:

coherence <- coh(ts1, ts2, f=100, plot=TRUE)
lags      <- coherence[,1]
vals      <- coherence[,2]
val.max   <- vals[which.max(vals)]
lag.max   <- lags[which.max(vals)]

coh()函数旨在与 ts 对象一起使用。这是进行 Praneeth在此处描述的计算的一种简单方法。