時系列のノイズの多いパッチを強調表示するにはどうすればよいですか?


9

時系列データがたくさんあります-水位と速度vs時間。これは、水理モデルシミュレーションからの出力です。モデルが期待どおりに動作していることを確認するための確認プロセスの一環として、各時系列をプロットして、データに「ウォブル」がないことを確認する必要があります(以下のマイナーウォブルの例を参照)。モデリングソフトウェアのUIを使用すると、このデータを確認するのにかなり時間がかかり、面倒です。したがって、結果を含むモデルのさまざまなデータをExcelにインポートし、それらをすべて一度にプロットする短いVBAマクロを作成しました。時系列データを分析して疑わしいセクションを強調表示する別の短いVBAマクロを記述したいと思っています。

これまでの私の唯一の考えは、データの勾配について分析を行うことができるということです。特定の検索ウィンドウ内で勾配が正から負に複数回急速に変化する場所は、不安定であると分類できます。もっと簡単なトリックはありませんか?基本的に、「安定した」シミュレーションは非常に滑らかな曲線を提供するはずです。突然の変化は、計算の不安定性の結果である可能性があります。

小さな不安定性の例


1
シンプルなメソッドのスイートについては、Tukeyの本EDAを読んでください。たとえば、本の早い段階で、彼は単純な平滑化器とその残差を取得するための使用法について説明しています。絶対残差の後続の平滑化は、曲線の局所変動をグラフ化し、急激な、突然の、または異常な変化がある場合に高くなり、それ以外の場合は低くとどまります。はるかに洗練された多くの方法が可能ですが、おそらくこれで十分でしょう。テューキーのスムーザーは、VBAのコードには比較的簡単です:私はそれを行っています
whuber

@whuberこれは基本的にスライディングハイパスフィルターの能力ですか?
amoeba

@amoebaたぶん。そのようなフィルターについての私の理解は、それらが完全にローカルではなく、確実に堅牢ではないのに対し、Tukeyのスムーザーはこれらの重要な特性の両方を持っているということです。(最近の人々は平滑化にLoessまたはGAMを使用していますが、これは問題ありませんが、実装するのははるかに簡単ではありません。)
whuber

回答:


10

簡単にするために、データのロバストな平滑化と比較した残差のサイズ(絶対値)を分析することをお勧めします。自動検出の場合、それらのサイズをインジケーターで置き換えることを検討してください。1が高い分位数を超えた場合は1、たとえばレベルでそれ以外の場合は0。このインジケーターを平滑化し、を超える平滑化された値を強調表示します。1αα

図

左の図は、データポイントを青色でプロットし、ロバストで局所的な滑らかさを黒色でプロットしています。右の図は、そのスムーズの残差のサイズを示しています。黒い点線は80パーセンタイルです(対応)。赤い曲線は上記のように作成されていますが、(と値から)プロットするために絶対残差の中域にスケーリングされています。1201α=0.201

変精度を制御できます。この例では、未満に設定すると、22時間あたりのノイズの短いギャップが識別されます。一方、超えるを設定すると、0時間近くの急激な変化も拾います。αα0.20α0.20

スムーズの詳細はあまり問題ではありません。この例では黄土スムーズ(に実装Rようloessspan=0.05、それをローカライズする)を使用したが、それでもウィンドウの平均は罰金をやっているだろう。絶対残差を平滑化するために、幅17のウィンドウ平均(約24分)を実行した後、ウィンドウ中央値を実行しました。これらのウィンドウ処理されたスムージングは​​、Excelでの実装が比較的簡単です。効率的なVBA実装(古いバージョンのExcelの場合、ソースコードは新しいバージョンでも機能するはずです)は、http://www.quantdec.com/Excel/smoothing.htmで入手できます


R コード

#
# Emulate the data in the plot.
#
xy <- matrix(c(0, 96.35,  0.3, 96.6, 0.7, 96.7, 1, 96.73, 1.5, 96.74, 2.5, 96.75, 
               4, 96.9, 5, 97.05, 7, 97.5, 10, 98.5, 12, 99.3, 12.5, 99.35, 
               13, 99.355, 13.5, 99.36, 14.5, 99.365, 15, 99.37, 15.5, 99.375, 
               15.6, 99.4, 15.7, 99.41, 20, 99.5, 25, 99.4, 27, 99.37),
             ncol=2, byrow=TRUE)
n <- 401
set.seed(17)
noise.x <- cumsum(rexp(n, n/max(xy[,1])))
noise.y <- rep(c(-1,1), ceiling(n/2))[1:n]
noise.amp <- runif(n, 0.8, 1.2) * 0.04
noise.amp <- noise.amp * ifelse(noise.x < 16 | noise.x > 24.5, 0.05, 1)
noise.y <- noise.y * noise.amp

g <- approxfun(noise.x, noise.y)
f <- splinefun(xy[,1], xy[,2])
x <- seq(0, max(xy[,1]), length.out=1201)
y <- f(x) + g(x)
#
# Plot the data and a smooth.
#
par(mfrow=c(1,2))
plot(range(xy[,1]), range(xy[,2]), type="n", main="Data", sub="With Smooth",
     xlab="Time (hours)", ylab="Water Level")
abline(h=seq(96, 100, by=0.5), col="#e0e0e0")
abline(v=seq(0, 30, by=5), col="#e0e0e0")
#curve(f(x) + g(x), xlim=range(xy[,1]), col="#2070c0", lwd=2, add=TRUE, n=1201)
lines(x,y, type="l", col="#2070c0", lwd=2)

span <- 0.05
fit <- loess(y ~ x, span=span)
y.hat <- predict(fit)
lines(fit$x, y.hat)
#
# Plot the absolute residuals to the smooth.
#
r <-  abs(resid(fit))
plot(fit$x, r, type="l", col="#808080",
     main="Absolute Residuals", sub="With Smooth and a Threshold",
     xlab="Time hours", ylab="Residual Water Level")
#
# Smooth plot an indicator of the smoothed residuals.
#
library(zoo)
smooth <- function(x, window=17) {
  x.1 <- rollapply(ts(x), window, mean)
  x.2 <- rollapply(x.1, window, median)
  return(as.vector(x.2))
}
alpha <- 0.2
threshold <- quantile(r, 1-alpha)
abline(h=threshold, lwd=2, lty=3)
r.hat <- smooth(r >threshold)
x.hat <- smooth(fit$x)
z <- max(r)/2 * (r.hat > alpha)
lines(x.hat, z, lwd=2, col="#c02020")
par(mfrow=c(1,1))

1
+1。どういうわけか、OPのプロットからデータを削りましたか?
アメーバ2017

2
@Amoebaそれは、特に15時間後の波状のビットについては、あまりにも面倒です。曲線上の1ダースの点に注目し、スプラインをプロットし、中間点をいくつか挿入して、スプラインが生成する可能性のある奇妙なスパイクを取り除き、強く負の異分散相関エラーを追加しました。プロセス全体には数分しかかかりませんでしたが、質問に示されているようなデータセットが質的に得られました。
whuber

あなたは私のプロットからどのようにデータを得るのだろうと思いました!乾杯!やってみます。
davehughes87 2017

FWIW、私はイラストの作成に使用したコードを投稿しました。VBAではありませんが、詳細が明らかになるかもしれません。(cc @amoeba)
whuber
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.