时间序列基础

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了时间序列基础相关的知识,希望对你有一定的参考价值。

参考技术A

1.随机时序分析的基本概念
1)随机变量:简单的随机现象,如某班一天学生出勤人数,是静态的。
2)随机过程:随机现象的动态变化过程。动态的。如某一时期各个时刻的状态。
所谓随机过程,就是说现象的变化没有确定形式,没有必然的变化规律。用数学语言来说,就是事物变化的过程不能用一个(或几个)时间t的确定的函数来描述。
如果对于每一特定的t属于T(T是时间集合),X(t)是一个随机变量,则称这一族无穷多个随机变量X(t),t属于T是一个随机过程。

2.白噪声序列
1)纯随机过程:随机变量X(t)(t=1,2,3……),如果是由一个不相关的随机变量的序列构成的,即对于所有s不等于k,随机变量Xs和Xk的协方差为零,则称其为 纯随机过程
2)白噪声过程:如果一个纯随机过程的期望和方差均为常数,则称之为 白噪声过程 。白噪声过程的样本实称成为白噪声序列,简称白噪声。
3)高斯白噪声序列:如果白噪声具体是服从均值为0、方差为常数的正态分布,那就是 高斯白噪声序列

3.平稳性序列
1)平稳性可以说是时间序列分析的基础。平稳的通俗理解就是时间序列的一些行为不随时间改变, 所谓平稳过程就是其统计特性不随时间的平移而变化的过程。
2)即时间序列内含的规律和逻辑,要在被预测的未来时间段内能够延续下去。这样我们才能用历史信息去预测未来信息,类似机器学习中的训练集和测试集同分布。
3)如果时间序列的变化是没有规律的、完全随机的,那么预测模型也就没有用。
4)平稳性的数学表达:如果时间序列在某一常数附近波动且波动范围有限,即有常数均值和常数方差,并且延迟k期的序列变量的自协方差和自相关系数是相等的或者说延迟k期的序列变量之间的影响程度是一样的,则称该序列为平稳序列。简单说就是没有明显趋势且波动范围有限。

4.严平稳/强平稳
1)通俗来说,就是时间序列的联合分布随着时间变化严格保持不变。
2)数学表达:如果对所有的时刻 t, (yt1,yt2,…ytm)的联合分布与(y(t1+k),(yt2+k),…y(tm+k))的联合分布相同,我们称时间序列 yt 是严平稳的。也就是时间序列的联合分布在时间的平移变换下保持不变。

5.弱平稳
1)数学表达:均值不变,协方差Cov(yt,y(t-k))=γk,γk依赖于k。
2)即协方差也不随时间改变,而仅与时间差k相关。
3)可以根据根据时间序列的折线图等大致观察数据的(弱)平稳性:*所有数据点在一个常数水平上下以相同幅度波动。
4)弱平稳的线性时间序列具有短期相关性(证明见参考书),即通常只有近期的序列值对现时值得影响比较明显,间隔越远的过去值对现时值得影响越小。至于这个间隔,也就是下面要提到的模型的阶数。

6.严平稳和弱平稳的关系
1)严平稳是一个很强的条件,难以用经验的方法验证,所以一般将弱平稳性作为模型的假设条件。
2)两者并不是严格的包含与被包含关系,但当时间序列是正态分布时,二者等价。

7.单位根非平稳序列(可转换为平稳序列的非平稳序列)
在金融数据中,通常假定资产收益率序列是弱平稳的。但还有一些研究对象,比如利率、汇率、资产的价格序列,往往不是平稳的。对于资产的价格序列,其非平稳性往往由于价格没有固定的水平,这样的非平稳序列叫做单位根(unit-root)非平稳序列。
1)最著名的单位根非平稳序列的例子是随机游走(random walk)模型:
pt=μ+p(t-1)+εt
μ是常数项(漂移:drift)。εt是白噪声序列,则pt就是一个随机游走。它的形式和AR模型很像,但不同之处在于,AR模型中,系数的模需要小于1,这是AR的平稳性条件,而随机游走相当于系数为1的AR公式,不满足AR模型的平稳性条件。
随机游走模型可作为(对数)股价运动的统计模型,在这样的模型下,股价是不可预测的。因为εt关于常数对称,所以在已知p(t-1)的条件下,pt上升或下降的概率都是50%,无从预测。
2)带趋势项的时间序列
pt=β0+β1*t+yt,yt是一个平稳时间序列。
带漂移的随机游走模型,其均值和方差都随时间变化;而带趋势项的时间序列,其均值随时间变化,但方差则是不变的常数。
单位根非平稳序列可以进行平稳化处理转换为平稳序列。比如用差分法处理随机游走序列,用用简单的回归分析移除时间趋势处理带趋势项的时间序列。

建立具体的模型,需解决如下三个问题模型的具体形式、时序变量的滞后期以及随机扰动项的结构。

μ是yt的均值;ψ是系数,决定了时间序列的线性动态结构,也被称为权重,其中ψ0=1;εt为高斯白噪声序列,它表示时间序列yt在t时刻出现了新的信息,所以εt称为时刻t的innovation(新信息)或shock(扰动)。
线性时间序列模型,就是描述线性时间序列的权重ψ的计量经济模型或统计模型,比如ARIMA。因为并非所有金融数据都是线性的,所以不是所有金融数据都适合ARIMA等模型。

①自回归模型(AR)
用变量自身的历史时间数据对变量进行回归,从而预测变量未来的时间数据。
p阶(滞后值,可暂理解为每个移动窗口有p期)自回归公式即AR(p):

②移动平均模型(MA)
移动平均模型关注的是误差项的累加,能够有效消除预测中的随机波动。
可以看作是白噪声序列的简单推广,是白噪声序列的有限线性组合。也可以看作是参数受到限制的无穷阶AR模型。

③自回归移动平均模型(ARMA)
有时候,要用很多阶数的AR和MA模型(见后面的定阶问题),为解决这个问题提出ARMA模型。
对于金融中的收益率序列,直接使用ARMA模型的时候较少,但其概念与波动率建模很相关,GARCH模型可以认为是对εt的ARMA模型。

④自回归差分移动平均模型(ARIMA)
ARIMA比ARMA仅多了个"I",代表的含义可理解为 差分。
一些非平稳序列经过d次差分后,可以转化为平稳时间序列。我们对差分1次后的序列进行平稳性检验,若果是非平稳的,则继续差分。直到d次后检验为平稳序列。

⑤一般分析过程
1、 平稳性检验
ADF检验(单位根检验):这是一种检查数据稳定性的统计测试。
原假设(无效假设):时间序列是不稳定的。
2、 平稳化处理
平稳化的基本思路是:通过建模并估计趋势和季节性这些因素,并从时间序列中移除,来获得一个稳定的时间序列,然后再使用统计预测技术来处理时间序列,最后将预测得到的数据,通过加入趋势和季节性等约束,来还原到原始时间序列数据。
2.0 对数变换
对某些时间序列需要取对数处理,一是可以将一些指数增长的时间序列变成线性增长,二是可以稳定序列的波动性。对数变换在经济金融类时间序列中常用。
2.1 差分法
如果是单位根非平稳的(比如随机游走模型),可以对其进行差分化。它能让数据呈现一种更加平稳的趋势。差分阶数的选择通常越小越好,只要能够使得序列稳定就行。
2.2 平滑法
移动平均、指数加权移动平均
注:经差分或平滑后的数据可能因包含缺失值而不能使用检验,需要将缺失值去除
2.3 分解法
建立有关趋势和季节性的模型,并从模型中删除它们。
3 、建立模型:模型选择和模型的定阶
模型的选择即在AR、MA、ARMA、ARIMA中间如何选择。
模型的定阶即指定上面过程中产生的超参数p、q和d(差分的阶数)。
(1)用ACF和PACF图判断使用哪种线性时间序列模型
AR模型:ACF拖尾,PACF截尾,看PACF定阶。
MA模型:ACF截尾,PACF拖尾,看ACF定阶。
ARMA模型:都拖尾。(EACF定阶)
截尾:在某阶后 迅速 趋于0(后面大部分阶的对应值在二倍标准差以内);
拖尾:按指数衰减或震荡,值到后面还有增大的情况。
ARIMA模型:适用于差分后平稳的序列。
(2)利用 信息准则 函数选择合适的阶
对于个数不多的时序数据,可以通过观察自相关图和偏相关图来进行模型识别,倘若要分析的时序数据量较多,例如要预测每只股票的走势,就不可能逐个去调参了。这时可以依据AIC或BIC准则识别模型的p, q值,通常认为AIC或BIC值越小的模型相对更优。
AIC或BIC准则综合考虑了残差大小和自变量的个数,残差越小AIC或BIC值越小,自变量个数越多AIC或BIC值越大。AIC或BIC准则可以说是对模型过拟合设定了一个标准。
AIC (Akaike information criterion,赤池信息度量准则)
AIC=2k-2ln(L)
· BIC (Bayesian information criterion,贝叶斯信息度量准则)
BIC=kln(n)-2ln(L)
k为模型的超参数个数,n为样本数量,L为似然函数。
类比机器学习中的损失函数=经验损失函数+正则化项。
模型选择标准:AIC和BIC越小越好(在保证精度的情况下模型越简单越好)
4 、模型检验和评估(之前应切分训练集和验证集)
检验残差是否符合标准(QQ图):是否服从均值为0,方差是常数的正态分布(εt是否是高斯白噪声序列)。
拟合优度检验(模型的评估):R 2和调整后的R 2(R^2只适用于平稳序列)。
5 、预测
如果之前进行了标准化、差分化等,需要进行还原:
标准化的还原要注意是log(x+1)还是log(x)。

1 、基础概念
波动率
在期权交易中,波动率是标的资产的收益率的条件标准差。之前的平稳序列假设方差为常数,但当序列的方差不是常数时,我们需要用波动率对其变化进行描述。
对于金融时间序列,波动率往往具有以下特征:
存在波动率聚集(volatility cluster)现象。 即波动率在一些 时间段 上高,一些时间段上低。
波动率以连续时间变化,很少发生跳跃。
波动率不会发散到无穷,而是在固定的范围内变化(统计学角度上说,其是平稳的)
杠杆效应:波动率对价格大幅上升和大幅下降的反应是不同的。
波动率模型/条件异方差模型
给资产收益率的波动率进行建模的模型叫做条件异方差模型。这些波动率模型试图刻画的数据有这样的特性: 它们是序列不相关或低阶序列相关的(比如股票的日收益率可能相关,但月收益率则无关),但又不是独立的 。波动率模型就是试图刻画序列的这种非独立性。
定义信息集F(t-1)是包含过去收益率的一切线性函数,假定F(t-1)给定,那么在此条件下时间序列yt的条件均值和条件方差分别表示为:

java基础之 序列化

一、序列化和反序列化的概念

  把对象转换为字节序列的过程称为对象的序列化。   

      把字节序列恢复为对象的过程称为对象的反序列化。   

     对象的序列化主要有两种用途:   

    1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;   

    2) 在网络上传送对象的字节序列。

  在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。

  当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

 

二、JDK类库中的序列化API

  java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。         java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。   

       只有实现了SerializableExternalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以 采用默认的序列化方式 。   

     对象序列化包括如下步骤:   

     1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;   

     2) 通过对象输出流的writeObject()方法写对象。


  对象反序列化的步骤如下:   

     1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;   

     2) 通过对象输入流的readObject()方法读取对象。

对象序列化和反序列范例:

  定义一个Person类,实现Serializable接口

技术分享
import java.io.Serializable;

/**
 * <p>ClassName: Person<p>
 * <p>Description:测试对象序列化和反序列化<p>
 * @author xudp
 * @version 1.0 V
 * @createTime 2014-6-9 下午02:33:25
 */
public class Person implements Serializable {

    /**
     * 序列化ID
     */
    private static final long serialVersionUID = -5809782578272943999L;
    private int age;
    private String name;
    private String sex;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public String getSex() {
        return sex;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}
person类

    序列化和反序列化Person类对象

技术分享
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.MessageFormat;

/**
 * <p>ClassName: TestObjSerializeAndDeserialize<p>
 * <p>Description: 测试对象的序列化和反序列<p>
 * @author xudp
 * @version 1.0 V
 * @createTime 2014-6-9 下午03:17:25
 */
public class TestObjSerializeAndDeserialize {

    public static void main(String[] args) throws Exception {
        SerializePerson();//序列化Person对象
        Person p = DeserializePerson();//反序列Perons对象
        System.out.println(p.toString);
    }
    
    /**
     * MethodName: SerializePerson 
     * Description: 序列化Person对象
     * @author xudp
     * @throws FileNotFoundException
     * @throws IOException
     */
    private static void SerializePerson() throws FileNotFoundException,
            IOException {
        Person person = new Person();
        person.setName("gacl");
        person.setAge(25);
        person.setSex("男");
        // ObjectOutputStream 对象输出流,将Person对象存储到E盘的Person.txt文件中,完成对Person对象的序列化操作
        ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
                new File("E:/Person.txt")));
        oo.writeObject(person);
        System.out.println("Person对象序列化成功!");
        oo.close();
    }

    /**
     * MethodName: DeserializePerson 
     * Description: 反序列Perons对象
     * @author xudp
     * @return
     * @throws Exception
     * @throws IOException
     */
    private static Person DeserializePerson() throws Exception, IOException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                new File("E:/Person.txt")));
        Person person = (Person) ois.readObject();
        System.out.println("Person对象反序列化成功!");
        return person;
    }

}
View Code

代码运行结果如下:

技术分享

三、serialVersionUID的作用

s?e?r?i?a?l?V?e?r?s?i?o?n?U?I?D?:? ?字?面?意?思?上?是?序?列?化?的?版?本?号?,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量

private static final long serialVersionUID

serialVersionUID有两种生成方式:

采用add default serial version ID 这种方式生成的serialVersionUID是1L,例如:

private static final long serialVersionUID = 1L;

采用add generated serial version ID这种方式生成的serialVersionUID是根据类名,接口名,方法和属性等来生成的,例如:

 private static final long serialVersionUID = 4603642343377807741L;

 

 

技术分享
class Customer implements Serializable {
    //Customer类中没有定义serialVersionUID
    private String name;
    private int age;

    //新添加的sex属性
    private String sex;
    
    public Customer(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public Customer(String name, int age,String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    /*
     * @MethodName toString
     * @Description 重写Object类的toString()方法
     * @author xudp
     * @return string
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "name=" + name + ", age=" + age;
    }
}
增加属性

然后执行反序列操作,此时就会抛出如下的异常信息:

1 Exception in thread "main" java.io.InvalidClassException: Customer;
2 local class incompatible:
3 stream classdesc serialVersionUID = -88175599799432325,
4 local class serialVersionUID = -5182532647273106745

意思就是说,文件流中的class和classpath中的class,也就是修改过后的class,不兼容了,处于安全机制考虑,程序抛出了错误,并且拒绝载入。那么如果我们真的有需求要在序列化后添加一个字段或者方法呢?应该怎么办?那就是自己去指定serialVersionUID。在TestSerialversionUID例子中,没有指定Customer类的serialVersionUID的,那么java编译器会自动给这个class进行一个摘要算法,类似于指纹算法,只要这个文件 多一个空格,得到的UID就会截然不同的,可以保证在这么多类中,这个编号是唯一的。所以,添加了一个字段后,由于没有显指定 serialVersionUID,编译器又为我们生成了一个UID,当然和前面保存在文件中的那个不会一样了,于是就出现了2个序列化版本号不一致的错误。因此,只要我们自己指定了serialVersionUID,就可以在序列化后,去添加一个字段,或者方法,而不会影响到后期的还原,还原后的对象照样可以使用,而且还多了方法或者属性可以用。

 

 

四、serialVersionUID的取值

  serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。   类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的 serialVersionUID,也有可能相同。为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值

  显式地定义serialVersionUID有两种用途:     1、 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;     2、 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。

 

 

 

 

 

 

以上是关于时间序列基础的主要内容,如果未能解决你的问题,请参考以下文章

QIIME基础应用(二)

时间序列基础

基础练习 时间转换

java基础之 序列化

python基础===时间处理模块

Python基础 序列和词典