Documentation ¶
Overview ¶
Package matrixprofile computes the matrix profile and matrix profile index of a time series
Example ¶
sig := []float64{0, 0.99, 1, 0, 0, 0.98, 1, 0, 0, 0.96, 1, 0} mp, err := New(sig, nil, 4) if err != nil { panic(err) } if err = mp.Compute(NewComputeOpts()); err != nil { panic(err) } fmt.Printf("Signal: %.3f\n", sig) fmt.Printf("Matrix Profile: %.3f\n", mp.MP) fmt.Printf("Profile Index: %5d\n", mp.Idx)
Output: Signal: [0.000 0.990 1.000 0.000 0.000 0.980 1.000 0.000 0.000 0.960 1.000 0.000] Matrix Profile: [0.014 0.014 0.029 0.029 0.014 0.014 0.029 0.029 0.029] Profile Index: [ 4 5 6 7 0 1 2 3 4]
Example (CaseStudy) ¶
sin := siggen.Sin(1, 5, 0, 0, 100, 2) sin2 := siggen.Sin(0.25, 10, 0, 0.75, 100, 0.25) saw := siggen.Sawtooth(0.5, 7, 0, 0, 100, 1) line := siggen.Line(0, 0, len(sin2)*4) sig := siggen.Append(sin, sin2, sin, line, sin2, line, sin2, line, saw) noise := siggen.Noise(0.1, len(sig)) sig = siggen.Add(sig, noise) var m, k int var r float64 m = 32 k = 6 r = 3 mp, err := New(sig, nil, m) if err != nil { panic(err) } co := NewComputeOpts() ao := NewAnalyzeOpts() ao.KMotifs = k ao.RMotifs = r ao.OutputFilename = "mp_sine.png" if err = mp.Analyze(co, ao); err != nil { panic(err) } fmt.Printf("Saved png file result to %s\n", ao.OutputFilename)
Output: Saved png file result to mp_sine.png
Example (KDimensionalCaseStudy) ¶
sin := siggen.Sin(1, 4, 0, 0, 100, 0.25) saw := siggen.Sawtooth(1, 4, 0, 0, 100, 0.25) square := siggen.Square(1, 4, 0, 0, 100, 0.25) line := siggen.Line(0, 0, len(sin)*4) line2 := siggen.Line(0, 0, len(sin)*3) sig := make([][]float64, 3) sig[0] = siggen.Append(line, line, line, saw, line2, saw, line2) sig[1] = siggen.Append(line, sin, line2, sin, line2, sin, line2, sin, line2) sig[2] = siggen.Append(line, square, line2, square, line2, square, line2, square, line2) noise := siggen.Noise(0.1, len(sig[0])) sig[0] = siggen.Add(sig[0], noise) noise = siggen.Noise(0.1, len(sig[0])) sig[1] = siggen.Add(sig[1], noise) noise = siggen.Noise(0.1, len(sig[0])) sig[2] = siggen.Add(sig[2], noise) var m int m = 25 mp, err := NewK(sig, m) if err != nil { panic(err) } if err = mp.MStomp(); err != nil { panic(err) } sigPts := make([]plotter.XYs, 3) sigPts[0] = Points(sig[0], len(sig[0])) sigPts[1] = Points(sig[1], len(sig[0])) sigPts[2] = Points(sig[2], len(sig[0])) mpPts := make([]plotter.XYs, 3) mpPts[0] = Points(mp.MP[0], len(sig[0])) mpPts[1] = Points(mp.MP[1], len(sig[0])) mpPts[2] = Points(mp.MP[2], len(sig[0])) if err = PlotKMP(sigPts, mpPts, "mp_kdim.png"); err != nil { panic(err) } fmt.Println("Saved png file result to mp_kdim.png")
Output: Saved png file result to mp_kdim.png
Index ¶
- type Algo
- type AnalyzeOptions
- type ComputeOptions
- type KMatrixProfile
- type MatrixProfile
- func (mp MatrixProfile) Analyze(co ComputeOptions, ao AnalyzeOptions) error
- func (mp *MatrixProfile) Compute(o ComputeOptions) error
- func (mp MatrixProfile) DiscoverDiscords(k int, exclusionZone int) ([]int, error)
- func (mp MatrixProfile) DiscoverMotifs(k int, r float64) ([]MotifGroup, error)
- func (mp MatrixProfile) DiscoverSegments() (int, float64, []float64)
- func (mp *MatrixProfile) Update(newValues []float64) error
- func (mp MatrixProfile) Visualize(fn string, motifs []MotifGroup, discords []int, cac []float64) error
- type MotifGroup
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AnalyzeOptions ¶
type AnalyzeOptions struct { KMotifs int // the top k motifs to find RMotifs float64 // the max radius to find motifs KDiscords int // the top k discords to find OutputFilename string // relative or absolute filepath for the visualization output }
AnalyzeOptions contains all the parameters needed for basic features to discover from a matrix profile. This is currently limited to motif, discord, and segmentation discovery.
func NewAnalyzeOpts ¶
func NewAnalyzeOpts() AnalyzeOptions
NewAnalyzeOpts creates a default set of parameters to analyze the matrix profile.
type ComputeOptions ¶
type ComputeOptions struct { Algorithm Algo // choose which algorithm to compute the matrix profile Sample float64 // only applicable to algorithm STAMP Parallelism int }
ComputeOptions are parameters to vary the algorithm to compute the matrix profile.
func NewComputeOpts ¶
func NewComputeOpts() ComputeOptions
NewComputeOpts returns a default ComputeOptions defaulting to the STOMP algorithm with a parallelism of 4.
type KMatrixProfile ¶
type KMatrixProfile struct { MP [][]float64 // matrix profile Idx [][]int // matrix profile index // contains filtered or unexported fields }
KMatrixProfile is a struct that tracks the current k-dimensional matrix profile computation for a given slice of timeseries of length N and subsequence length of M. The profile and the profile index are stored here.
func NewK ¶
func NewK(t [][]float64, m int) (*KMatrixProfile, error)
NewK creates a matrix profile struct specifically to be used with the k dimensional matrix profile computation. The number of rows represents the number of dimensions, and each row holds a series of points of equal length as each other.
func (*KMatrixProfile) MStomp ¶
func (mp *KMatrixProfile) MStomp() error
MStomp computes the k dimensional matrix profile
type MatrixProfile ¶
type MatrixProfile struct { A []float64 // query time series B []float64 // timeseries to perform full join with AMean []float64 // sliding mean of a with a window of m each AStd []float64 // sliding standard deviation of a with a window of m each BMean []float64 // sliding mean of b with a window of m each BStd []float64 // sliding standard deviation of b with a window of m each BF []complex128 // holds an existing calculation of the FFT of b timeseries N int // length of the timeseries M int // length of a subsequence SelfJoin bool // indicates whether a self join is performed with an exclusion zone MP []float64 // matrix profile Idx []int // matrix profile index AV av.AV // type of annotation vector which defaults to all ones }
MatrixProfile is a struct that tracks the current matrix profile computation for a given timeseries of length N and subsequence length of M. The profile and the profile index are stored here.
func New ¶
func New(a, b []float64, m int) (*MatrixProfile, error)
New creates a matrix profile struct with a given timeseries length n and subsequence length of m. The first slice, a, is used as the initial timeseries to join with the second, b. If b is nil, then the matrix profile assumes a self join on the first timeseries.
func (MatrixProfile) Analyze ¶
func (mp MatrixProfile) Analyze(co ComputeOptions, ao AnalyzeOptions) error
Analyze performs the matrix profile computation and discovers various features from the profile such as motifs, discords, and segmentation. The results are visualized and saved into an output file.
func (*MatrixProfile) Compute ¶
func (mp *MatrixProfile) Compute(o ComputeOptions) error
Compute calculate the matrixprofile given a set of input options. This defaults to using STOMP unless specified differently
func (MatrixProfile) DiscoverDiscords ¶
func (mp MatrixProfile) DiscoverDiscords(k int, exclusionZone int) ([]int, error)
DiscoverDiscords finds the top k time series discords starting indexes from a computed matrix profile. Each discovery of a discord will apply an exclusion zone around the found index so that new discords can be discovered.
func (MatrixProfile) DiscoverMotifs ¶
func (mp MatrixProfile) DiscoverMotifs(k int, r float64) ([]MotifGroup, error)
DiscoverMotifs will iteratively go through the matrix profile to find the top k motifs with a given radius. Only applies to self joins.
Example ¶
// generate a signal mainly composed of sine waves and switches // frequencies, amplitude, and offset midway through // amplitude of 1, frequency of 5Hz, sampling frequency of 100 Hz, // time of 2 seconds sin := siggen.Sin(1, 5, 0, 0, 100, 2) // amplitude of 0.25, frequency of 10Hz, offset of 0.75, sampling // frequency of 100 Hz, time of 1 second sin2 := siggen.Sin(0.25, 10, 0, 0.75, 100, 1) sig := siggen.Append(sin, sin2) // create a new MatrixProfile struct using the signal and a // subsequence length of 32. The second subsequence is set to nil // so we perform a self join. mp, err := New(sig, nil, 32) if err != nil { panic(err) } // run the STMP algorithm with self join. The matrix profile // will be stored in mp.MP and the matrix profile index will // be stored in mp.Idx o := NewComputeOpts() o.Algorithm = AlgoSTMP if err = mp.Compute(o); err != nil { panic(err) } // finds the top 3 motifs in the signal. Motif groups include // all subsequences that are within 2 times the distance of the // original motif pair motifs, err := mp.DiscoverMotifs(2, 2) if err != nil { panic(err) } for i, mg := range motifs { fmt.Printf("Motif Group %d\n", i) fmt.Printf(" %d motifs\n", len(mg.Idx)) }
Output: Motif Group 0 2 motifs Motif Group 1 2 motifs
func (MatrixProfile) DiscoverSegments ¶
func (mp MatrixProfile) DiscoverSegments() (int, float64, []float64)
DiscoverSegments finds the the index where there may be a potential timeseries change. Returns the index of the potential change, value of the corrected arc curve score and the histogram of all the crossings for each index in the matrix profile index. This approach is based on the UCR paper on segmentation of timeseries using matrix profiles which can be found https://www.cs.ucr.edu/%7Eeamonn/Segmentation_ICDM.pdf
Example ¶
// generate a signal mainly composed of sine waves and switches // frequencies, amplitude, and offset midway through // amplitude of 1, frequency of 5Hz, sampling frequency of 100 Hz, // time of 2 seconds sin := siggen.Sin(1, 5, 0, 0, 100, 2) // amplitude of 0.25, frequency of 10Hz, offset of 0.75, sampling // frequency of 100 Hz, time of 1 second sin2 := siggen.Sin(0.25, 10, 0, 0.75, 100, 1) sig := siggen.Append(sin, sin2) // noise with an amplitude of 0.1 noise := siggen.Noise(0.01, len(sig)) sig = siggen.Add(sig, noise) // create a new MatrixProfile struct using the signal and a // subsequence length of 32. The second subsequence is set to nil // so we perform a self join. mp, err := New(sig, nil, 32) if err != nil { panic(err) } // run the STMP algorithm with self join. The matrix profile // will be stored in mp.MP and the matrix profile index will // be stored in mp.Idx o := NewComputeOpts() o.Algorithm = AlgoSTMP if err = mp.Compute(o); err != nil { panic(err) } // segment the timeseries using the number of arc crossings over // each index in the matrix profile index idx, cac, _ := mp.DiscoverSegments() fmt.Printf("Signal change foud at index: %d\n", idx) fmt.Printf("Corrected Arc Curve (CAC) value: %.3f\n", cac)
Output: Signal change foud at index: 194 Corrected Arc Curve (CAC) value: 0.000
func (*MatrixProfile) Update ¶
func (mp *MatrixProfile) Update(newValues []float64) error
Update updates a matrix profile and matrix profile index in place providing streaming like behavior.
func (MatrixProfile) Visualize ¶
func (mp MatrixProfile) Visualize(fn string, motifs []MotifGroup, discords []int, cac []float64) error
Visualize creates a png of the matrix profile given a matrix profile.
type MotifGroup ¶
MotifGroup stores a list of indices representing a similar motif along with the minimum distance that this set of motif composes of.