go语言学习时间序列和异常检测

本文深入探讨了时间序列分析的基本概念,包括时序数据的表示、关键术语的理解、与时间序列相关的统计方法,如自相关和偏自相关,以及自回归模型的应用。通过Go语言示例,展示了如何读取时间序列数据、绘制时序图、计算自相关和偏自相关,以及使用自回归模型进行预测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间序列和异常检测
时间序列建模有助于我们根据过去的属性预测未来

7.1go语言中表示时序数据
gonum、gota包中都有时序数据表示方式

读数据并将数据制作成时序图
import (
	"image/color"
	"log"
	"os"

	"gonum.org/v1/plot/vg"

	"gonum.org/v1/plot"

	"gonum.org/v1/plot/plotter"

	"github.com/kniren/gota/dataframe"
)

func main() {

	airFlie, err := os.Open("D:/gocode/AirPassengers.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer airFlie.Close()

	// 创建数据帧
	airData := dataframe.ReadCSV(airFlie)

	// fmt.Println(airData)

	// 将时间序列绘图
	yVals := airData.Col("value").Float()

	pts := make(plotter.XYs, airData.Nrow())

	// 填充数据点
	for i, floatVal := range airData.Col("time").Float() {
		pts[i].X = floatVal
		pts[i].Y = yVals[i]
	}
	p, err := plot.New()
	if err != nil {
		log.Fatal(err)
	}
	p.X.Label.Text = "time"
	p.Y.Label.Text = "passengers"
	p.Add(plotter.NewGrid())

	// 将时间序列填入
	l, err := plotter.NewLine(pts)
	if err != nil {
		log.Fatal(err)
	}
	l.LineStyle.Width = vg.Points(1)
	l.LineStyle.Color = color.RGBA{B: 255, A: 255}

	p.Add(l)
	// Save()的第一个参数是长,第二参数是高
	if err := p.Save(10*vg.Inch, 4*vg.Inch, "passengers.png"); err != nil {
		log.Fatal(err)
	}
}

7.2理解时间序列的术语
时间、日期、时间戳
观察、测量、信号、随机变量
季节性:随着季节的变化而变化
趋势:随着时间的变化而呈现的一种形态
平稳的:随着时间的变化,不变或者没有较大的变化
时间段:时间学列中连续观测点之间的时间量
自归模型:试图通过同一过程的一个或多个延迟或滞后版本对时间序列过程建模。
移动平均模型:试图根据不完全预测项的当前或过去的值对时间序列进行建模

7.3与时间序列有关的相关统计
7.3.1自相关
自相关是衡量信号与其本身的延迟版本之间相关型的变量 使用自相关函数定量

import (
	"fmt"
	"log"
	"math"
	"os"

	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/plotutil"

	"gonum.org/v1/plot/vg"

	"gonum.org/v1/plot"

	"github.com/kniren/gota/dataframe"
	"gonum.org/v1/gonum/stat"
)

//计算延迟自相关的函数
func acf(x []float64, lag int) float64 {

	xAdj := x[lag:len(x)]
	xLag := x[0 : len(x)-lag]

	var numrator float64
	var denomiator float64

	xBar := stat.Mean(x, nil)
	for idx, xval := range xAdj {
		numrator += ((xval - xBar) * (xLag[idx] - xBar))
	}
	for _, xval := range x {
		denomiator += math.Pow(xval-xBar, 2)

	}
	return numrator / denomiator
}

func main() {

	airFlie, err := os.Open("D:/gocode/AirPassengers.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer airFlie.Close()

	// 创建数据帧
	airData := dataframe.ReadCSV(airFlie)
	passengers := airData.Col("value").Float()

	fmt.Println("自相关是:")
	for i := 1; i < 11; i++ {

		adjusted := passengers[i:len(passengers)]
		lag := passengers[0 : len(passengers)-i]

		ac := stat.Correlation(adjusted, lag, nil)
		fmt.Printf("Lag %d period :%0.2f\n", i, ac)
	}

	// 成图显示
	p, err := plot.New()
	if err != nil {
		log.Fatal(err)
	}
	p.Title.Text = "passengers "
	p.X.Label.Text = "Lag"
	p.Y.Label.Text = "ACF"

	p.Y.Max = 0
	p.Y.Max = 1

	w := vg.Points(3)

	numLags := 20

	pts := make(plotter.Values, numLags)
	for i := 1; i < numLags; i++ {

		pts[i-1] = acf(passengers, i)
	}

	bars, err := plotter.NewBarChart(pts, w)
	if err != nil {
		log.Fatal(err)
	}
	bars.LineStyle.Width = vg.Length(0)
	bars.Color = plotutil.Color(1)
	p.Add(bars)
	if err := p.Save(8*vg.Inch, 4*vg.Inch, "acf.png"); err != nil {
		log.Fatal(err)
	}
}
7.3.2偏自相关
	测量一个	序列在减去任何中间延迟的自相关后,在特定的延迟步长的相关性。可以将其视为移除中间关联后的剩余自相关。
	如果偏自相关在第一次延迟后消失,就使用基于自身的单延迟,若没有消失就要使用时间序列的多个延时版本。
	偏自相关就是为了消除了其他延迟产生的影响 
	import (
	"fmt"
	"log"
	"os"
	"strconv"

	"github.com/kniren/gota/dataframe"
	"github.com/sajari/regression"
	"gonum.org/v1/plot"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/plotutil"
	"gonum.org/v1/plot/vg"
)

// 偏相关函数
func pacf(x []float64, lag int) float64 {
	var r regression.Regression
	r.SetObserved("x")

	for i := 0; i < lag; i++ {
		r.SetVar(i, "x"+strconv.Itoa(i))
	}

	xAdj := x[lag:len(x)]

	for i, xVal := range xAdj {
		lagVariables := make([]float64, lag)
		for idx := 1; idx <= lag; idx++ {
			lagVariables[idx-1] = x[lag+i-idx]
		}
		r.Train(regression.DataPoint(xVal, lagVariables))
	}
	r.Run()
	return r.Coeff(lag)
}

func main() {
	airFlie, err := os.Open("D:/gocode/AirPassengers.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer airFlie.Close()

	// 创建数据帧
	airData := dataframe.ReadCSV(airFlie)
	passengers := airData.Col("value").Float()

	fmt.Println("偏自相关:")
	for i := 1; i < 11; i++ {
		pac := pacf(passengers, i)
		fmt.Printf("Lag %d period :%0.2f\n", i, pac)
	}

	// 成图显示
	p, err := plot.New()
	if err != nil {
		log.Fatal(err)
	}
	p.Title.Text = "passengers "
	p.X.Label.Text = "Lag"
	p.Y.Label.Text = "PACF"

	p.Y.Max = 0
	p.Y.Max = 1

	w := vg.Points(3)

	numLags := 20

	pts := make(plotter.Values, numLags)
	for i := 1; i < numLags; i++ {

		pts[i-1] = pacf(passengers, i)
	}

	bars, err := plotter.NewBarChart(pts, w)
	if err != nil {
		log.Fatal(err)
	}
	bars.LineStyle.Width = vg.Length(0)
	bars.Color = plotutil.Color(1)
	p.Add(bars)
	if err := p.Save(8*vg.Inch, 4*vg.Inch, "pacf.png"); err != nil {
		log.Fatal(err)
	}
}

7.4预测的自回归模型
用来预测时间序列的第一类模型称为自回归模型
7.4.2自回归模型假设和陷阱
平稳性:自回归模型假定时间序列是平稳的
遍历性:时间序列的统计特征不应随着时间变化或漂移

7.4.3自回归模型实例
	利用差分(后一项减前一项)保持时间序列的平稳
import (
	"encoding/csv"
	"image/color"
	"log"
	"math"
	"os"
	"strconv"

	"gonum.org/v1/plot/vg"

	"gonum.org/v1/plot"

	"github.com/kniren/gota/dataframe"
	"gonum.org/v1/plot/plotter"
)

func main() {
	airFlie, err := os.Open("D:/gocode/AirPassengers.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer airFlie.Close()

	// 创建数据帧
	airData := dataframe.ReadCSV(airFlie)
	passengers := airData.Col("value").Float()
	timeVals := airData.Col("time").Float()

	pts := make(plotter.XYs, airData.Nrow()-1)

	var difference [][]string
	difference = append(difference, []string{"time", "differenceVal"})

	for i := 1; i < len(passengers); i++ {
		pts[i-1].X = timeVals[i]
		pts[i-1].Y = passengers[i] - passengers[i-1] //差分

		// 使用消减
		difference = append(difference, []string{
			strconv.FormatFloat(timeVals[i], 'f', -1, 64),
			strconv.FormatFloat(math.Log(passengers[i]-passengers[i-1]), 'f', -1, 64),
		})
	}

	p, err := plot.New()
	if err != nil {
		log.Fatal(err)
	}
	p.X.Label.Text = "time"
	p.Y.Label.Text = "differenceVals"
	p.Add(plotter.NewGrid())

	l, err := plotter.NewLine(pts)
	if err != nil {
		log.Fatal(err)
	}
	l.LineStyle.Width = vg.Points(1)
	l.LineStyle.Color = color.RGBA{B: 255, A: 255}

	p.Add(l)
	if err := p.Save(10*vg.Inch, 4*vg.Inch, "diff.png"); err != nil {
		log.Fatal(err)
	}

	//保存数据
	f, err := os.Create("diff_serices.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	w := csv.NewWriter(f)
	w.WriteAll(difference)
	if err := w.Error(); err != nil {
		log.Fatal(err)
	}
}
自回归移动平均模型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值