Mendeteksi perubahan dalam deret waktu (contoh R)


18

Saya ingin mendeteksi perubahan dalam data deret waktu, yang biasanya memiliki bentuk yang sama. Sejauh ini saya telah bekerja dengan changepointpaket untuk R cpt.mean(), cpt.var()dan cpt.meanvar()fungsi. cpt.mean()dengan metode PELT berfungsi dengan baik ketika data biasanya tetap pada satu tingkat. Namun saya juga ingin mendeteksi perubahan saat turun. Contoh untuk perubahan, saya ingin mendeteksi, adalah bagian di mana kurva hitam tiba-tiba turun sementara itu sebenarnya harus mengikuti garis putus-putus merah yang patut dicontoh. Saya telah bereksperimen dengan fungsi cpt.var (), namun saya tidak bisa mendapatkan hasil yang baik. Sudahkah Anda mendapat rekomendasi (yang tidak harus menggunakan R)?

Ubah kurva

Berikut adalah data dengan perubahan (sebagai objek 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)

Perhatikan bahwa jika Anda hanya meminta kode R, itu akan menjadi off-topic di sini. Jika Anda meminta saran metodologis umum, itu tidak masalah. Mungkin datang dengan beberapa kode R, tapi sekali lagi, mungkin tidak.
gung - Reinstate Monica

1
Ucapan yang baik, saya tertarik pada solusi umum, menggunakan R hanya akan nyaman.
pindah

Jawaban:


17

Anda bisa menggunakan deteksi outlier seri waktu untuk mendeteksi perubahan dalam seri waktu. Prosedur Tsay atau Chen dan Liu adalah metode deteksi outlier time series yang populer. Lihat pertanyaan saya sebelumnya di situs ini.

Paket tsoutlier R menggunakan metode Chen dan Liu untuk mendeteksi outlier. SAS / SPSS / Autobox juga dapat melakukan ini. Lihat di bawah untuk kode R untuk mendeteksi perubahan dalam deret waktu.

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

Fungsi tso dalam paket tsoultlier mengidentifikasi outlier berikut. Anda dapat membaca dokumentasi untuk mengetahui tipe outlier.

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

paket ini juga menyediakan plot yang bagus. Lihat di bawah. Plot menunjukkan di mana outlier berada dan juga apa yang akan terjadi jika tidak ada outlier.

masukkan deskripsi gambar di sini

Saya juga menggunakan paket R yang disebut strucchange untuk mendeteksi pergeseran level. Sebagai contoh pada data Anda

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

Program dengan benar mengidentifikasi breakpoints atau perubahan struktural.

Optimal 4-segment partition: 

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

Breakpoints at observation number:
17 41 87 

Corresponding to breakdates:
17 41 87 

Semoga ini membantu


1
Terima kasih, tsoberfungsi dengan baik, namun agak lambat untuk kumpulan data yang lebih besar. Posisi breakpoint dari struccchange tampak sedikit berubah-ubah (kecuali posisi 41).
mlee

7

Saya akan mendekati masalah ini dari perspektif berikut . Ini hanya beberapa ide dari atas kepala saya - tolong bawa mereka dengan sebutir garam. Meskipun demikian, saya berharap ini akan bermanfaat.

  • Pengelompokan seri waktu . Misalnya dengan menggunakan populer dynamic time warping (DTW) atau pendekatan alternatif. Silakan lihat jawaban terkait saya: pada DTW untuk klasifikasi / pengelompokan dan pada DTW atau alternatif untuk rangkaian waktu yang tidak rata . The ide adalah untuk klaster time series dalam kategori "normal" dan "abnormal" (atau serupa).

  • Tindakan entropi . Lihat jawaban saya yang relevan tentang tindakan entropi seri waktu . The ide adalah untuk menentukan entropi dari "normal" time series dan kemudian membandingkannya dengan time series lainnya (ide ini memiliki asumsi dari penyimpangan entropi dalam kasus penyimpangan dari "normalitas").

  • Deteksi anomali . Lihat jawaban saya yang relevan pada deteksi anomali (termasuk sumber daya R). The ide adalah untuk langsung mendeteksi anomali melalui berbagai metode (lihat referensi). Kotak Alat Peringatan Dini (EWS) danR paket earlywarningstampaknya terutama menjanjikan.


6

Respons saya menggunakan AUTOBOX sangat mirip dengan @forecaster tetapi dengan model yang jauh lebih sederhana. Box dan Einstein dan lainnya telah merefleksikan menjaga solusi sederhana tetapi tidak terlalu sederhana. Model yang dikembangkan secara otomatis adalah masukkan deskripsi gambar di sini. Plot aktual dan dibersihkan sangat mirip masukkan deskripsi gambar di sini. Plot residu (yang harus selalu ditampilkan) ada di sini masukkan deskripsi gambar di sinibersama dengan acf wajib residu masukkan deskripsi gambar di sini. Statistik residu selalu berguna dalam membuat perbandingan antara "model duel" masukkan deskripsi gambar di sini. Grafik Aktual / Fit / Prakiraan ada di sinimasukkan deskripsi gambar di sini


1

Tampaknya masalah Anda akan sangat disederhanakan jika Anda mengubah data Anda. Tampaknya menurun secara linear. Setelah Anda menentukan data, Anda dapat menerapkan berbagai tes untuk ketidakstabilan.


3
Pendekatan ini akan gagal karena ada kemiringan yang jelas berbeda dalam sejarah. Kecuali jika Anda menggabungkan beberapa "tren / lereng" pendekatan ini tidak akan menghasilkan hasil yang bermakna. Solusi lurus ke depan seringkali terlalu sederhana.
IrishStat

1

Semua jawaban baik-baik saja, tetapi di sini adalah yang sederhana, seperti yang disarankan oleh @MrMeritology, yang tampaknya bekerja dengan baik untuk deret waktu yang dimaksud, dan kemungkinan untuk banyak set data "serupa" lainnya.

Berikut adalah cuplikan-R yang menghasilkan grafik penjelasan sendiri di bawah ini.

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")

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini


mungkin ada beberapa perubahan tren dan beberapa perubahan intersep (pergeseran level) ... sehingga orang perlu menemukan solusi yang benar-benar mendiagnosis data untuk menentukan ini ...
IrishStat

Ya, memang, saya sudah membaca komentar Anda sebelumnya di atas. Namun, mendiagnosis deret waktu untuk mendeteksi beberapa tren / level adalah masalah tersendiri. Maksud saya di sini adalah untuk menunjukkan bahwa pendekatan sederhana di atas kadang-kadang berfungsi, khususnya untuk data yang diberikan. Sebaliknya, tidak ada pendekatan tunggal yang akan berhasil dengan baik. Pendekatan oleh R.Hyndman (R-function tsoutliers) adalah sesuatu yang saya sarankan.
dnqxt

AUTOBOX adalah pendekatan tunggal yang akan bekerja dengan baik selalu (setidaknya untuk zillions seri waktu yang telah kita lihat) dan ada versi R. Jika Anda ingin mengobrol secara offline karena saya tidak ingin menjadi "salesy" di sini saya dapat menjelaskan proses yang sepenuhnya dimengerti / transparan tetapi tidak mudah diduplikasi.
IrishStat
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.