การตรวจจับการเปลี่ยนแปลงในอนุกรมเวลา (ตัวอย่าง R)


18

ฉันต้องการตรวจจับการเปลี่ยนแปลงในข้อมูลอนุกรมเวลาซึ่งมักจะมีรูปร่างเหมือนกัน จนถึงตอนนี้ฉันได้ทำงานกับchangepointแพ็คเกจสำหรับ R และcpt.mean(), cpt.var()และcpt.meanvar()ฟังก์ชั่น cpt.mean()ด้วยวิธี 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 - Reinstate Monica

1
คำพูดที่ดีฉันสนใจในโซลูชันทั่วไปการใช้ R จะสะดวก
mlee

คำตอบ:


17

คุณสามารถใช้การตรวจหาค่าล่วงเวลาของอนุกรมเวลาเพื่อตรวจจับการเปลี่ยนแปลงในอนุกรมเวลา กระบวนการของ TsayหรือChen และ Liu เป็นวิธีการตรวจหาค่าช่วงเวลาที่เป็นที่นิยม ดูคำถามก่อนหน้าของฉันในเว็บไซต์นี้

แพ็คเกจtsoutlierของ R ใช้วิธีของ 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)

ฟังก์ชัน tso ในแพ็คเกจ tsoultlier ระบุค่าผิดปกติดังต่อไปนี้ คุณสามารถอ่านเอกสารเพื่อค้นหาประเภทของค่าผิดปกติ

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

แพคเกจยังให้แปลงที่ดี ดูด้านล่าง เนื้อเรื่องแสดงว่าตัวผิดอยู่ที่ไหนและเกิดอะไรขึ้นถ้าไม่มีตัวผิด

ป้อนคำอธิบายรูปภาพที่นี่

ฉันยังใช้แพคเกจ R ที่เรียกว่าStrucchangeเพื่อตรวจจับการเลื่อนระดับ เป็นตัวอย่างในข้อมูลของคุณ

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 ดูเหมือนจะเป็นเรื่องเล็กน้อย (ยกเว้นตำแหน่ง 41)
mlee

7

ฉันจะเข้าถึงปัญหานี้จากต่อไปนี้มุมมอง นี่เป็นเพียงไอเดียบางอย่างที่อยู่ด้านบนของหัวฉัน - เอาเกลือไปด้วย อย่างไรก็ตามฉันหวังว่าสิ่งนี้จะเป็นประโยชน์

  • ชุดการจัดกลุ่มเวลา ตัวอย่างเช่นโดยใช้การแปรปรวนเวลาไดนามิกยอดนิยม(DTW)หรือวิธีการอื่น โปรดดูคำตอบของฉันที่เกี่ยวข้องกันใน DTW สำหรับการจำแนกประเภท / การจัดกลุ่มและใน DTW หรือทางเลือกสำหรับชุดเวลาที่ไม่สม่ำเสมอ ความคิดคือการอนุกรมเวลาคลัสเตอร์เป็นประเภท "ปกติ" และ "ผิดปกติ" (หรือคล้ายกัน)

  • มาตรการเอนโทรปี ดูคำตอบที่เกี่ยวข้องของฉันในเวลามาตรการชุดเอนโทรปี ความคิดคือการกำหนดเอนโทรปีของ "ปกติ" อนุกรมเวลาแล้วเปรียบเทียบกับช่วงเวลาอื่น ๆ (ความคิดนี้มีสมมติฐานของการเบี่ยงเบนเอนโทรปีในกรณีของการเบี่ยงเบนจาก "ปกติ")

  • การตรวจสอบความผิดปกติ ดูคำตอบที่เกี่ยวข้องของฉันในการตรวจจับความผิดปกติ (รวมถึงทรัพยากร R) ความคิดคือการโดยตรงตรวจสอบความผิดปกติผ่านทางวิธีการต่าง ๆ (โปรดดูอ้างอิง) สัญญาณเตือนภัยล่วงหน้า (EWS) กล่องเครื่องมือและRแพคเกจearlywarningsดูเหมือนโดยเฉพาะอย่างยิ่งที่มีแนวโน้ม


6

คำตอบของฉันที่ใช้ AUTOBOX นั้นค่อนข้างคล้ายกับ @forecaster แต่มีรูปแบบที่ง่ายกว่ามาก Box และ Einstein และคนอื่น ๆ สะท้อนให้เห็นถึงวิธีการแก้ปัญหาที่ง่าย แต่ไม่ง่ายเกินไป ป้อนคำอธิบายรูปภาพที่นี่รูปแบบที่ได้รับการพัฒนาโดยอัตโนมัติเป็น ป้อนคำอธิบายรูปภาพที่นี่พล็อตที่เกิดขึ้นจริงและทำความสะอาดแล้วจะคล้ายกันมาก พล็อตของเศษ (ซึ่งควรได้รับการแสดง) อยู่ที่นี่ป้อนคำอธิบายรูปภาพที่นี่พร้อมกับ acf ป้อนคำอธิบายรูปภาพที่นี่บังคับของคลาดเคลื่อน สถิติของเหลืออยู่เสมอประโยชน์ในการเปรียบเทียบระหว่าง ป้อนคำอธิบายรูปภาพที่นี่"ดวลรุ่น" กราฟจริง / พอดี / พยากรณ์อยู่ที่นี่ป้อนคำอธิบายรูปภาพที่นี่


1

ดูเหมือนว่าปัญหาของคุณจะง่ายขึ้นอย่างมากหากคุณลบข้อมูลของคุณ ดูเหมือนว่าจะลดลงเป็นเส้นตรง เมื่อคุณ detrend ข้อมูลคุณสามารถใช้การทดสอบที่หลากหลายสำหรับแบบไม่คงที่


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 เป็นวิธีการเดียวที่จะทำงานได้ดีเสมอ (อย่างน้อยสำหรับซีรีส์ zillions ของเวลาที่เราได้เห็น) และมีรุ่น R หากคุณต้องการแชทแบบออฟไลน์เนื่องจากฉันไม่ต้องการไปที่ "salesy" ที่นี่ฉันสามารถอธิบายกระบวนการที่เข้าใจง่าย / โปร่งใส แต่ไม่ซ้ำกันได้อย่างง่ายดาย
IrishStat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.