時系列の変化の検出(Rの例)


18

通常は同じ形状の時系列データの変化を検出したいと思います。これまでのところ私が働いてきたchangepointR用のパッケージとcpt.mean(), cpt.var()してcpt.meanvar()機能します。cpt.mean()データが通常1つのレベルにとどまっている場合、PELTメソッドを使用するとうまく機能します。しかし、降下中の変化も検出したいと思います。変化の例として、検出したいのは、実際に例の赤い点線に従うはずの黒い曲線が突然落ちる部分です。私はcpt.var()関数を試しましたが、良い結果を得ることができませんでした。推奨事項はありますか(必ずしもRを使用する必要はありません)?

曲線を変更

変更されたデータ(Rオブジェクトとして)は次のとおりです。

dat.change <- c(12.013995263488, 11.8460207231808, 11.2845153487846, 11.7884417180764, 
11.6865425802022, 11.4703118125303, 11.4677576899063, 11.0227199625084, 
11.274775836817, 11.03073498338, 10.7771805591742, 10.7383206158923, 
10.5847230134625, 10.2479315651441, 10.4196381241735, 10.467607842288, 
10.3682422713283, 9.7834431752935, 9.76649842404295, 9.78257968297228, 
9.87817694914062, 9.3449034905713, 9.56400153361727, 9.78120084558148, 
9.3445162813738, 9.36767436354887, 9.12070987223648, 9.21909859069157, 
8.85136359917466, 8.8814423003979, 8.61830163359642, 8.44796977628488, 
8.06957847272046, 8.37999165387824, 7.98213210294954, 8.21977468333673, 
7.683960439316, 7.73213584532496, 7.98956476021092, 7.83036046746187, 
7.64496198988985, 4.49693528397253, 6.3459274845112, 5.86993447552116, 
4.58301192892403, 5.63419551523625, 6.67847511602895, 7.2005344054883, 
5.54970477623895, 6.00011922569104, 6.882667104467, 4.74057284230894, 
6.2140437333397, 6.18511450451019, 5.83973575417525, 6.57271194428385, 
5.36261938326723, 5.48948831338016, 4.93968645996861, 4.52598133247377, 
4.56372558828803, 5.74515428123725, 5.45931581984165, 5.58701112949141, 
6.00585679276365, 5.41639695946931, 4.55361875158434, 6.23720558202826, 
6.19433060301002, 5.82989415940829, 5.69321394985076, 5.53585871082265, 
5.42684812413063, 5.80887522466946, 5.56660158483312, 5.7284521523444, 
5.25425775891636, 5.4227645808924, 5.34778016248718, 5.07084809927736, 
5.324066161355, 5.03526881241705, 5.17387528516352, 5.29864121433813, 
5.36894461582415, 5.07436929444317, 4.80619983525015, 4.42858947882894, 
4.33623051506001, 4.33481791951228, 4.38041031792294, 3.90012900415342, 
4.04262777674943, 4.34383842876647, 4.36984816425014, 4.11641092254315, 
3.83985887104645, 3.81813419810962, 3.85174630901311, 3.66434598962311, 
3.4281724860426, 2.99726515704766, 2.96694634792395, 2.94003031547181, 
3.20892607367132, 3.03980832743458, 2.85952185077593, 2.70595278908964, 
2.50931109659839, 2.1912274016859)

Rコードのみを要求している場合は、ここではトピックから外れていることに注意してください。一般的な方法論的なアドバイスを求めている場合は、それで問題ありません。Rコードが含まれている場合もありますが、そうでない場合もあります。
GUNG -復活モニカ

1
良い発言、私は一般的な解決策に興味があります。Rを使用すると便利です。
-mlee

回答:


17

時系列異常値検出を使用して、時系列の変化を検出できます。 Tsayの手順またはChen and Liuの手順は、一般的な時系列外れ値検出方法です。このサイトに関する以前の質問を参照してください。

Rのtsoutlierパッケージは、異常値の検出にChenとLiuの方法を使用します。SAS / SPSS / Autoboxもこれを行うことができます。時系列の変化を検出するRコードについては、以下を参照してください。

library("tsoutliers")
dat.ts<- ts(dat.change,frequency=1)
data.ts.outliers <- tso(dat.ts)
data.ts.outliers
plot(data.ts.outliers)

tsoultlierパッケージのtso関数は、次の外れ値を識別します。ドキュメントを読んで、外れ値のタイプを調べることができます。

Outliers:
  type ind time coefhat   tstat
1   TC  42   42 -2.9462 -10.068
2   AO  43   43  1.0733   4.322
3   AO  45   45 -1.2113  -4.849
4   TC  47   47  1.0143   3.387
5   AO  51   51  0.9002   3.433
6   AO  52   52 -1.3455  -5.165
7   AO  56   56  0.9074   3.710
8   LS  62   62  1.1284   3.717
9   AO  67   67 -1.3503  -5.502

このパッケージは、素晴らしいプロットも提供します。下記参照。このプロットは、外れ値の場所と、外れ値がなかった場合に何が起こるかを示しています。

ここに画像の説明を入力してください

また、strucchangeと呼ばれるRパッケージを使用して、レベルシフトを検出しました。データの例として

library("strucchange")
breakpoints(dat.ts~1)

プログラムは、ブレークポイントまたは構造の変更を正しく識別します。

Optimal 4-segment partition: 

Call:
breakpoints.formula(formula = dat.ts ~ 1)

Breakpoints at observation number:
17 41 87 

Corresponding to breakdates:
17 41 87 

お役に立てれば


1
おかげでtsoうまくいきましたが、大きなデータセットの場合は少し遅くなります。struccchangeのブレークポイントの位置は、少しarbitrary意的です(41の位置を除く)。
-mlee

7

私は次の観点からこの問題に取り組みます。これらは私の頭の上のいくつかのアイデアにすぎません-塩の粒でそれらをしてください。それでも、これが役立つことを願っています。

  • 時系列クラスタリング。たとえば、一般的な動的タイムワーピング(DTW)または代替アプローチを使用します。私の関連の回答を参照してください:DTW上の分類/クラスタリング用DTWまたは不均一な時系列の代替にアイデアは、「正常」および「異常」(または類似の)カテゴリにクラスタの時系列です。

  • エントロピー測定時系列エントロピー測定に関する関連する回答参照してください。この考え方は、「正常な」時系列のエントロピーを決定し、それを他の時系列と比較することです(この考え方には、「正常」からの偏差の場合のエントロピー偏差の仮定があります)。

  • 異常検出異常検出に関する関連する回答参照してください(Rリソースを含む)。アイデアがすることです直接(参考文献を参照してください)、様々な方法を介して異常を検出します。早期警告信号(EWS)ツールボックスRパッケージearlywarningsは特に有望です。


6

AUTOBOXを使用した私の応答は@forecasterに非常に似ていますが、はるかに単純なモデルです。BoxとEinsteinなどは、ソリューションをシンプルに保つことを考えていますが、シンプルすぎないようにしています。自動的に開発されたモデルはでしたここに画像の説明を入力してください。実際のプロットとクレンジングされたプロットは非常に似ていここに画像の説明を入力してくださいます。残差のプロット(常に表示する必要があります)はここに画像の説明を入力してください、残差の必須acfとともにここにありますここに画像の説明を入力してください。残差の統計は、「デュエルモデル」間の比較に常に役立ちここに画像の説明を入力してくださいます。Actual / Fit / Forecastグラフはこちらここに画像の説明を入力してください


1

データのトレンド除去を行うと、問題が大幅に簡素化されるように思われます。直線的に減少しているようです。データのトレンド除去を行うと、非定常性に対してさまざまなテストを適用できます。


3
歴史には明らかに異なる傾斜があるため、このアプローチは失敗します。複数の「トレンド/スロープ」を組み込む場合を除き、このアプローチでは意味のある結果は得られません。多くの場合、単純で単純なソリューションは単純すぎます。
IrishStat

1

すべて良い答えですが、@ MrMeritologyによって示唆されているように、ここに簡単なものがあります。これは、問題の時系列、および他の多くの「類似」データセットでうまく機能するようです。

これは、以下の自明のグラフを生成するRスニペットです。

outl = rep( NA, length(dat.change))
detr = c( 0, diff( dat.change))

ix = abs(detr) > 2*IQR( detr)
outl[ix] = dat.change[ix]

plot( dat.change, t='l', lwd=2, main="dat.change TS")
points( outl, col=2, pch=18)

plot( detr, col=4, main="detrended TS", t='l', lwd=2 )
acf( detr, main="ACF of detrended TS")

ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください


複数のトレンドの変更と複数のインターセプトの変更(レベルシフト)が発生する可能性があるため、実際にデータを診断してこれらを決定するソリューションを見つける必要があります...
IrishStat

はい、確かに、上記の前のコメントを読みました。ただし、時系列を診断して複数のトレンド/レベルを検出すること自体が問題です。ここでの私のポイントは、上記の単純なアプローチが、特定のデータに対して特に機能することを示すことです。逆に、単一のアプローチが常にうまくいくとは限りません。R.Hyndman(R-function tsoutliers)によるアプローチは、そうでなければお勧めします。
dnqxt

AUTOBOXは(少なくとも私たちが見た無数の時系列で)常にうまく機能する単一のアプローチであり、Rバージョンがあります。ここで「難解」にしたくないので、オフラインでチャットしたい場合は、完全に理解できる/透明であるが簡単に複製できないプロセスを説明できます。
IrishStat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.