5

Tôi cần một cách để xác định minima và maxima cục bộ trong dữ liệu chuỗi thời gian với Mathematica. Điều này có vẻ như nó phải là một điều dễ dàng để làm, nhưng nó được khôn lanh. Tôi đã đăng bài này trên MathForum, nhưng nghĩ rằng tôi có thể nhận được một số đôi mắt bổ sung vào nó ở đây.Xác định minima và cực đại quan trọng trong chuỗi thời gian w/Mathematica

Bạn có thể tìm thấy một giấy mà thảo luận về những vấn đề tại địa chỉ: http://www.cs.cmu.edu/~eugene/research/full/compress-series.pdf

Tôi đã thử điều này cho đến nay ...

Nhận và định dạng một số dữ liệu:

data = FinancialData["SPY", {"May 1, 2006", "Jan. 21, 2011"}][[All, 2]]; 
data = data/[email protected]; 
data = Transpose[{Range[[email protected]], data}]; 

Xác định 2 chức năng:

Phương thức đầu tiên:

findMinimaMaxima[data_, window_] := With[{k = window}, 
    data[[k + [email protected][Partition[data[[All, 2]], 2 k + 1, 1], x_List /; x[[k + 1]] < Min[Delete[x, k + 1]] || x[[k + 1]] > Max[Delete[x, k + 1]]]]]] 

Bây giờ cách tiếp cận khác, mặc dù không phải là linh hoạt:

findMinimaMaxima2[data_] := data[[[email protected](Length[#] & /@ Split[Prepend[Sign[[email protected][[All, 2]] - [email protected][[All, 2]]], 0]])]] 

Nhìn vào những gì mỗi chức năng thực hiện. Đầu tiên findMinimaMaxima2 []:

minmax = findMinimaMaxima2[data]; 
{[email protected], [email protected]} 
[email protected] 

này sẽ chọn tất cả cực tiểu và cực đại và kết quả (trong trường hợp này) trong khoảng một nén dữ liệu 49%, nhưng nó không có sự linh hoạt mở rộng cửa sổ. Phương pháp khác này. Một cửa sổ của 2, sản lượng ít hơn và cực trị cho là quan trọng hơn:

minmax2 = findMinimaMaxima[data, 2]; 
{[email protected], [email protected]} 
[email protected] 

Nhưng nhìn vào những gì sẽ xảy ra khi chúng tôi mở rộng cửa sổ để 60:

minmax2 = findMinimaMaxima[data, 60]; 
ListLinePlot[{data, minmax2}] 

Một số cực tiểu và cực đại không còn thay thế. Áp dụng findMinimaMaxima2 [] để đầu ra của findMinimaMaxima [] đưa ra một cách giải quyết ...

minmax3 = findMinimaMaxima2[minmax2]; 
ListLinePlot[{data, minmax2, minmax3}] 

, nhưng điều này có vẻ như một cách vụng về để giải quyết vấn đề.

Vì vậy, ý tưởng sử dụng cửa sổ cố định để nhìn trái và phải không hoàn toàn phù hợp với mọi thứ bạn muốn. Tôi bắt đầu nghĩ về một giải pháp thay thế có thể sử dụng giá trị dải R (ví dụ: phần trăm di chuyển lên hoặc xuống) mà hàm sẽ cần phải đáp ứng hoặc vượt quá để đặt minima hoặc cực đại tiếp theo. Đây là lần thử đầu tiên của tôi:

findMinimaMaxima3[data_, R_] := Module[{d, n, positions}, 
    d = data[[All, 2]]; 
    n = Transpose[{data[[All, 1]], [email protected][If[(#2 <= #1 + #1*R && #2 >= #1) || (#2 >= #1 - #1* R && #2 <= #1), #1, #2] &, d[[1]], d]}]; 
    n = Sign[[email protected][[All, 2]] - [email protected][[All, 2]]]; 
    positions = [email protected][Most[Position[n, Except[0]]]]; 
    data[[positions]] 
    ] 

minmax4 = findMinimaMaxima3[data, 0.1]; 
ListLinePlot[{data, minmax4}] 

này quá lợi ích từ bài xử lý với findMinimaMaxima2 []

ListLinePlot[{data, findMinimaMaxima2[minmax4]}] 

Nhưng nếu bạn nhìn kỹ, bạn sẽ thấy rằng nó nhớ những thái cực nếu họ vượt qua giá trị R trong một số vị trí - bao gồm tối thiểu tuyệt đối của biểu đồ và tối đa cũng như dọc theo các động thái lớn lên xuống. Thay đổi giá trị R cho biết cách giá trị này bỏ qua đầu và cuối nhiều hơn:

minmax4 = findMinimaMaxima3[data, 0.15]; 
ListLinePlot[{data, minmax4}] 

Vì vậy, tôi cần xem xét lại. Bất cứ ai cũng có thể xem xét một lô dữ liệu và dễ dàng xác định minima và cực đại quan trọng. Có vẻ khó khăn hơn để có được một thuật toán để làm điều đó. Một cửa sổ và/hoặc giá trị R có vẻ quan trọng đối với giải pháp, nhưng cả hai đều không đủ (ít nhất không phải trong các phương pháp trên).

Có ai có thể mở rộng bất kỳ phương pháp nào được hiển thị hoặc đề xuất phương án thay thế để xác định minima và cực đại quan trọng không?

Vui lòng chuyển tiếp sổ tay với tất cả mã này và thảo luận trong đó. Hãy cho tôi biết nếu có ai cần nó.

Cảm ơn bạn, Jagra

+0

Tiêu chí tối đa và tối đa xen kẽ không phải lúc nào cũng quan trọng trong các biến thể giá. Giống như ở đây http://i.imgur.com/nsIK7.png –

+0

Cho phép tôi chào mừng bạn đến StackOverflow và nhắc nhở ba điều chúng tôi thường làm ở đây: 1) Khi bạn nhận được sự giúp đỡ, hãy cố gắng cho nó quá ** trả lời câu hỏi ** trong lĩnh vực chuyên môn của bạn 2) ['Đọc câu hỏi thường gặp'] (http://tinyurl.com/2vycnvr) 3) Khi bạn thấy Q & A tốt, hãy bỏ phiếu cho họ ['bằng cách sử dụng tam giác màu xám'] (http: // i .imgur.com/kygEP.png), vì độ tin cậy của hệ thống dựa trên danh tiếng mà người dùng đạt được bằng cách chia sẻ kiến ​​thức của họ. Cũng nên nhớ chấp nhận câu trả lời giải quyết tốt hơn vấn đề của bạn, nếu có, ['bằng cách nhấn dấu kiểm'] (http://i.imgur.com/uqJeW.png) –

Trả lời

8

tôi đề nghị sử dụng một cách tiếp cận lặp đi lặp lại. Các chức năng sau được lấy từ this post, và trong khi họ có thể được viết ngắn gọn hơn mà không Compile, họ sẽ thực hiện công việc:

localMinPositionsC = 
Compile[{{pts, _Real, 1}}, 
    Module[{result = Table[0, {Length[pts]}], i = 1, ctr = 0}, 
    For[i = 2, i < Length[pts], i++, 
    If[pts[[i - 1]] > pts[[i]] && pts[[i + 1]] > pts[[i]], 
     result[[++ctr]] = i]]; 
    Take[result, ctr]]]; 

localMaxPositionsC = 
    Compile[{{pts, _Real, 1}}, 
    Module[{result = Table[0, {Length[pts]}], i = 1, ctr = 0}, 
     For[i = 2, i < Length[pts], i++, 
     If[pts[[i - 1]] < pts[[i]] && pts[[i + 1]] < pts[[i]], 
      result[[++ctr]] = i]]; 
     Take[result, ctr]]]; 

Đây là âm mưu dữ liệu của bạn:

dplot = ListLinePlot[data] 

Ở đây ta vẽ đồ thị phút, mà thu được sau 3 lần lặp:

mins = ListPlot[Nest[#[[localMinPositionsC[#[[All, 2]]]]] &, data, 3], 
    PlotStyle -> Directive[PointSize[0.015], Red]] 

cùng cho maxima:

maxs = ListPlot[Nest[#[[localMaxPositionsC[#[[All, 2]]]]] &, data, 3], 
    PlotStyle -> Directive[PointSize[0.015], Green]] 

Và cốt truyện kết quả:

Show[{dplot, mins, maxs}] 

enter image description here

Bạn có thể thay đổi số lần lặp lại, để có được hạt thô hơn hoặc tốt hơn cực tiểu/maxima.

Edit:

thực sự, tôi chỉ nhận thấy rằng một vài điểm vẫn còn bỏ lỡ bằng phương pháp này, cả hai đều cho cực tiểu và cực đại. Vì vậy, tôi đề nghị nó như là một điểm khởi đầu, không phải là một giải pháp hoàn chỉnh. Có lẽ, bạn có thể phân tích minima/maxima, đến từ các lần lặp lại khác nhau và đôi khi bao gồm các từ nhỏ hơn "trước", chi tiết hơn. Ngoài ra, "lý do vật lý" duy nhất mà loại công trình này, là bản chất của dữ liệu tài chính có vẻ giống như fractal, với một số quy mô khác nhau rõ rệt. Mỗi lần lặp trong Nest-s ở trên nhắm mục tiêu một quy mô cụ thể. Điều này sẽ không hoạt động tốt cho tín hiệu tùy ý.

+0

Leonid - Rất cám ơn vì giải pháp. Hai câu hỏi nhanh: 1. Tôi không quen với việc bạn sử dụng "_Real" trong các hàm được biên dịch. Bạn có thể giải thích nó làm gì không? và 2. Khi tôi giữ bản pdf của cuốn sách "Lập trình Mathematica: Giới thiệu nâng cao" trên máy tính của tôi bất cứ khi nào tôi làm bất cứ điều gì trong Mathematica, tôi tự hỏi bạn có thể bình luận về lý do tại sao bạn cảm thấy các vòng lặp trong localMinPositionsC và localMaxPositionsC làm tốt nhất lựa chọn trong tình huống này so với cách tiếp cận chức năng hơn như bạn thường ủng hộ trong cuốn sách của mình? Một lần nữa cảm ơn rất nhiều. – Jagra

+0

@Jagra - _Real được sử dụng để khai báo loại. Điều này là cần thiết cho các đối số là tensors của một số thứ hạng - vec-tơ, ma trận, vv Trong trường hợp cụ thể đó, chúng ta cần một vectơ của thực (tensor of rank 1). Bạn có thể tìm thấy các ví dụ hay trong tài liệu.Khi sử dụng Compile, bạn đã đúng - tôi không có thời gian để viết và kiểm tra một chức năng nhanh, và đối với vấn đề ban đầu mà tôi đã sử dụng chúng (cái tôi liên kết), tốc độ rất quan trọng. Trong trường hợp của bạn, bạn sẽ có thể viết một cái gì đó với phân vùng đó sẽ là đủ nhanh cho tính toán này. –

+0

OK. Cảm ơn một lần nữa. – Jagra

Các vấn đề liên quan