forecast

package
v0.0.0-...-11fc026 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2018 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var FunctionAnomalyRollingMultiplicativeHoltWinters = FunctionPeriodicAnomalyMaker("forecast.anomaly_rolling_multiplicative_holt_winters", FunctionRollingMultiplicativeHoltWinters)
View Source
var FunctionAnomalyRollingSeasonal = FunctionPeriodicAnomalyMaker("forecast.anomaly_rolling_seasonal", FunctionRollingSeasonal)
View Source
var FunctionDrop = function.MakeFunction(
	"forecast.drop",
	func(timerange api.Timerange, original api.SeriesList, dropTime time.Duration) api.SeriesList {
		lastValue := float64(timerange.Slots()) - dropTime.Seconds()/timerange.Resolution().Seconds()
		result := make([]api.Timeseries, len(original.Series))
		for i, series := range original.Series {
			values := make([]float64, len(series.Values))
			result[i] = series
			for j := range values {
				if float64(j) < lastValue {
					values[j] = series.Values[j]
				} else {
					values[j] = math.NaN()
				}
			}
			result[i].Values = values
		}

		return api.SeriesList{
			Series: result,
		}
	},
)
View Source
var FunctionLinear = function.MakeFunction(
	"forecast.linear",
	func(context function.EvaluationContext, seriesExpression function.Expression, optionalTrainingTime *time.Duration) (api.SeriesList, error) {
		extraTrainingTime := time.Duration(0)
		if optionalTrainingTime != nil {
			extraTrainingTime = *optionalTrainingTime
		}
		if extraTrainingTime < 0 {
			return api.SeriesList{}, fmt.Errorf("extra training time must be non-negative, but got %s", extraTrainingTime.String())
		}

		newContext := context.WithTimerange(context.Timerange().ExtendBefore(extraTrainingTime))
		extraSlots := newContext.Timerange().Slots() - context.Timerange().Slots()
		seriesList, err := function.EvaluateToSeriesList(seriesExpression, newContext)
		if err != nil {
			return api.SeriesList{}, err
		}

		result := api.SeriesList{
			Series: make([]api.Timeseries, len(seriesList.Series)),
		}

		for seriesIndex, series := range seriesList.Series {
			result.Series[seriesIndex] = api.Timeseries{
				TagSet: series.TagSet,
				Values: Linear(series.Values)[extraSlots:],
			}
		}

		return result, nil
	},
	function.Option{Name: function.WidenBy, Value: function.Argument(1)},
)

FunctionLinear forecasts with a simple linear regression. For data which is mostly just a linear trend up or down, this will provide a good model of current behavior, as well as a good estimate of near-future behavior.

View Source
var FunctionRollingMultiplicativeHoltWinters = function.MakeFunction(
	"forecast.rolling_multiplicative_holt_winters",
	func(context function.EvaluationContext, seriesExpression function.Expression, period time.Duration, levelLearningRate float64, trendLearningRate float64, seasonalLearningRate float64, optionalExtraTrainingTime *time.Duration) (api.SeriesList, error) {
		extraTrainingTime := time.Duration(0)
		if optionalExtraTrainingTime != nil {
			extraTrainingTime = *optionalExtraTrainingTime
		}
		if extraTrainingTime < 0 {
			return api.SeriesList{}, fmt.Errorf("extra training time must be non-negative, but got %s", extraTrainingTime.String())
		}

		samples := int(period / context.Timerange().Resolution())
		if samples <= 0 {
			return api.SeriesList{}, fmt.Errorf("forecast.rolling_multiplicative_holt_winters expects the period parameter to mean at least one slot")
		}

		newContext := context.WithTimerange(context.Timerange().ExtendBefore(extraTrainingTime))
		extraSlots := newContext.Timerange().Slots() - context.Timerange().Slots()
		seriesList, err := function.EvaluateToSeriesList(seriesExpression, newContext)
		if err != nil {
			return api.SeriesList{}, err
		}

		result := api.SeriesList{
			Series: make([]api.Timeseries, len(seriesList.Series)),
		}

		for seriesIndex, series := range seriesList.Series {
			result.Series[seriesIndex] = api.Timeseries{
				TagSet: series.TagSet,
				Values: RollingMultiplicativeHoltWinters(series.Values, samples, levelLearningRate, trendLearningRate, seasonalLearningRate)[extraSlots:],
			}
		}

		return result, nil
	},
	function.Option{Name: function.WidenBy, Value: function.Argument(5)},
)

FunctionRollingMultiplicativeHoltWinters computes a rolling multiplicative Holt-Winters model for the data. It takes in several learning rates, as well as the period that describes the periodicity of the seasonal term. The learning rates are interpreted as being "per period." For example, a value of 0.5 means that values in this period are effectively weighted twice as much as those in the previous. A value of 0.9 means that values in this period are weighted 1.0/(1.0 - 0.9) = 10 times as much as the previous.

View Source
var FunctionRollingSeasonal = function.MakeFunction(
	"forecast.rolling_seasonal",
	func(context function.EvaluationContext, seriesExpression function.Expression, period time.Duration, seasonalLearningRate float64, optionalExtraTrainingTime *time.Duration) (api.SeriesList, error) {
		extraTrainingTime := time.Duration(0)
		if optionalExtraTrainingTime != nil {
			extraTrainingTime = *optionalExtraTrainingTime
		}
		if extraTrainingTime < 0 {
			return api.SeriesList{}, fmt.Errorf("extra training time must be non-negative, but got %s", extraTrainingTime.String())
		}

		samples := int(period / context.Timerange().Resolution())
		if samples <= 0 {
			return api.SeriesList{}, fmt.Errorf("forecast.rolling_seasonal expects the period parameter to mean at least one slot")
		}

		newContext := context.WithTimerange(context.Timerange().ExtendBefore(extraTrainingTime))
		extraSlots := newContext.Timerange().Slots() - context.Timerange().Slots()
		seriesList, err := function.EvaluateToSeriesList(seriesExpression, newContext)
		if err != nil {
			return api.SeriesList{}, err
		}

		result := api.SeriesList{
			Series: make([]api.Timeseries, len(seriesList.Series)),
		}

		for seriesIndex, series := range seriesList.Series {
			result.Series[seriesIndex] = api.Timeseries{
				TagSet: series.TagSet,
				Values: RollingSeasonal(series.Values, samples, seasonalLearningRate)[extraSlots:],
			}
		}

		return result, nil
	},
	function.Option{Name: function.WidenBy, Value: function.Argument(3)},
)

FunctionRollingSeasonal is a forecasting MetricFunction that performs the rolling seasonal estimation. It is designed for data which shows seasonality without trends, although which a high learning rate it can perform tolerably well on data with trends as well.

Functions

func FunctionPeriodicAnomalyMaker

func FunctionPeriodicAnomalyMaker(name string, model function.MetricFunction) function.MetricFunction

FunctionPeriodicAnomalyMaker makes anomaly-measurement functions that return simple p-values for deviations from the predicted model. In order to make this procedure mostly automatic, it performs a join on the original tagsets to match them up with their predictions.

func Linear

func Linear(ys []float64) []float64

Linear estimates a purely linear trend from the data.

func LinearRegression

func LinearRegression(ys []float64) (float64, float64)

LinearRegression estimates ys as (a + b*t) and returns (a, b). It performs linear regression using the explicit form for minimization of least-squares error. When ys[i] is NaN, it is treated as a missing point. (This makes things only slightly more complicated).

func RollingMultiplicativeHoltWinters

func RollingMultiplicativeHoltWinters(ys []float64, period int, levelLearningRate float64, trendLearningRate float64, seasonalLearningRate float64) []float64

RollingMultiplicativeHoltWinters approximate the given input using the Holt-Winters model by performing exponential averaging on the HW parameters. It scales 'levelLearningRate' and 'trendLearningRate' by the 'period'. That is, if you double the period, it will take twice as long as before for the level and trend parameters to update. This makes it easier to use with varying period values.

func RollingSeasonal

func RollingSeasonal(ys []float64, period int, seasonalLearningRate float64) []float64

RollingSeasonal estimates purely seasonal data without a trend or level component. For data which shows no long- or short-term trends, this model is more likely to recognize deviant behavior. However, it will perform worse than Holt-Winters on data which does have any significant trends.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL