精华内容
下载资源
问答
  • 典型序列及信源编码的一种理解

    万次阅读 多人点赞 2013-06-07 22:58:28
    对于典型集合,r取值为Np,所以典型集合中序列个数为2^NH2(p),我们为其中每一个分配一个二进制(0,1)码字,那么码字长度为M=log|T|,T为典型序列个数,所以M=NH2(p)。 综上,对于任意一个N长信源序列,我们用一...

        


    距离上一篇文章,应该有半年的时间了。这半年有太多的不顺,不安,不静,以至于我真的没有心思来写点感悟或是理解。为了不传播负能量,我决定略过那些烦心事,因为自己希望看我博客的读者都有一颗快乐的心;同时,看着来访量的渐渐增加,心里还是有说不出的感动。我为什么要写这些玩意?请允许我首先借用一位登山家解释他为什么要去登山时的回答:“因为那座山峰在那里”。王小波很喜欢这个答案,他说:“明明是自己想登山,偏说是山在那里使他心里痒痒。”小波的解释赋予了它幽默感,因为小波是一个有趣的人,无法忍受无趣的人生。我一直觉得自己是个无趣的人,但又十分向往着有趣,可是难免有点东施效颦的感觉。所以,当我朋友说我是一个“丰富”的人时,我受宠若惊,立即拿起桌上的镜子,端详良久,除了头发十分丰富繁盛,实在看不出来其它。既然无趣,我就只是记录一些想法,因为我不再有原来的记忆力了。当然就像登山者冒着摔出脑子的危险一样,我也会为每篇文章耗费精力,有时候真的也挺累的。小波把这种“趋害避利”行为看作是---减熵!

        上面这些话的唯一意义,就在于它终于引出了今天的主题---熵。热力学认为自发情况下,熵是不会减少的,它表征了一种无序状态;而要使熵减少,就需要干涉,需要反自发。在信息领域,熵定义了一个随机变量的平均信息量(average of shannon information content)。信息看似很飘渺,很虚幻,但是Shannon给出了它的定量表示,如下:


    其中x代表一个随机变量X(掷硬币结果,正面或者反面)的某一取值,p(x)代表其发生概率,h(x)就是这一事件发生给我们带来的信息量。可见,概率越小,越不可能发生的事情,它的信息量是越大的,合乎常理。虽然小概率事件发生,信息量很大,但是毕竟它发生的几率太小,为了刻画随机变量的信息量(不确定度大小),就需要平均,随机变量熵定义如下:

    其中Ax是所有可能发生事件的集合。对于掷硬币简单例子,假设出现正面或者反面发生的几率是0.5,那么得到H(X)=1bit。即我们用0或者1就可以表征这个随机变量。(写的太不严谨了,大家懂意思就行,下面用H代表正面,T代表反面。)比如:我们要告诉大洋彼岸的某人我们的抛硬币的结果是HTHHTT,那么我们可以把这样的消息编码为010011,然后经过星座映射,滤波成形,调制发送出去。我们希望发送同样的消息,用的比特数越少越好,节约带宽。(我忍不住想插一句,请问平均需要抛掷多少次硬币才会首次出现HTH或者HTT这样的结果呢?这两种样式需要的抛掷次数相等吗?关于这个问题,一直想写,先给出答案:N(HTH)=10,N(HTT)=8,即你从开始抛,平均在第十次时出现HTH,XXXX..HTH,X代表前面几次的结果中,都不会出现HTH样式。同理,平均在第八次出现HTT。)最终,我们是用平均1个比特传输一个信源符号,R = 1比特/信源符号,这也就是码率。(6比特对应6个信源符号)

        当然,硬币不一定均匀的,对应于现实中,各种事件发生也不一定是等概率的,假设P(H)=0.9,P(T)=0.1,即正面的可能性远大于反面,这个时候X(硬币结果)这个随机变量的不确定度大大减小了,因为我们知道它出现正面的机会是很大的,不再像等概率时,我们只有完全靠猜。这有点像天气预报,它告诉你明天下雨,当然天气预报不是100%正确,所以你告诉你自己,明天还是十分有可能下雨的,至少90%,所以你得带上雨伞。但是,如果没有天气预报,你就无法说服自己要拿雨伞了,是不?可见,你对下雨这件事,有了一定的认识和了解,它不再那么难猜了,那么它的随机性不确定性就降低了,那么它的熵也就小了。


    H2(p)代表二元随机变量的熵,代入p=0.1或p=0.9得到,H2(0.1)= 0.469<1。上面两个例子告诉我们,等概率发生时,它的不确定性是最大的,人们无法偏袒任何一方,H2(p)的图像如下:


    横轴是概率p,纵轴H2(p),等概率取最大值1,且满足对称性。

    Shannon告诉我们:如果一个信源X的熵是H(X),那么我们最少可以用平均H(X)个比特来传输一个信源符号。

    (1)显然,对于均匀硬币,等概率发生H,T,我们做到了H(X)个比特传输一个信源符号。

    (2)对于第二种非均匀情况,若我们还是用010011来传输HTTHTH,显然我们用1(1>H(x)=0.469)比特每信源符号,未能满足要求,说明这样的编码不是最优的。

    这个时候,传奇人物---小明又出现了,他不相信了,这怎么可能,我真的可以只需要用不到一个1bit来传输H或者T?0.469个比特能干嘛?冥冥中,他仿佛听见了些什么:

    “请放下你屌丝的短浅目光,不要着急,你才抛掷了六次就要把结果告诉对方,小红不喜欢着急的男生(小明与小红的故事),请沉住气,你先抛掷1000次再告诉她吧,相信我,没有错。”

    小明听后,不明真相,不过还是默默地抛掷了起来:


    (为什么不画好看点?小明很屌丝?不是啦,很多人以为我的博文里出现的贴图是截取别人书上的,其实是我自己用latex编辑好,然后截图的,所以今天我就用手写验证,大的图我就加个水印~)。

    得出了这样的一长串序列有什么用?一共有2^1000个啊,我才抛掷出一个,难道我要一个个抛掷出来,小红可等不起啊。小明揉揉了已经麻木的肩膀,若有期盼地看着Shannon。帅气的Shannon开始提问:你觉得T会在这1000次里出现多少次呢?它的分布如何呢?

    小明想了想,这不小孩子都知道嘛,P(T)=0.1,告诉我们T出现的概率是0.1,当抛掷次数很多时,依据大数定理,概率等于频率了,所以我断定T出现次数应该在1000x0.1=100次左右。哦,对,它是二项分布,方差是Np(1-p)=90,标准差9.5左右,考虑100左右3个标准差[100-3*9,5,100+3*9.5],99%可能性T的次数出现在此区间。那到底是不是这样呢?


    可见,T发生的次数以100为中心,在三个标准差内概率几乎为一。我们得到如下结论:


    当N足够大时,T出现的次数几乎等于Np次。

    终于,小明有所顿悟,他问Shannon,“这么说来,2^1000个1000长的序列中,其实像1111..1111,11110111.111这种序列是几乎不会出现的,那么最可能出现的是有100个T的那种序列”,对吗?

    Shannon满意地点了点头,同时告诉小明,这样的序列构成的集合叫做Typical Set(典型序列集合)。那么这样说来,本来有2^1000种可能结果,现在排除掉了那么多,只用关心典型序列集合里有多少个序列了。我们只需要对这些典型集合编码就行了,其它那些小概率序列我们不用管,如图所示,这样我们需要编码的个数就大大减少了。


    那么Typical Set 里到底有多少个序列呢?经过前面分析,它大概等于1000长序列中出现100次T的个数,即从N中选择Np,一共有多少种可能性呢?考虑下Stirling近似公式!(终于写到我想写的东西了,已经过去两个小时了。)


    对于典型集合,r取值为Np,所以典型集合中序列个数为2^NH2(p),我们为其中每一个分配一个二进制(0,1)码字,那么码字长度为M=log|T|,T为典型序列个数,所以M=NH2(p)。

    综上,对于任意一个N长信源序列,我们用一个标签来标示它,这个标签长为M = NH2(p)比特,形如“01011010”,那么平均每一个信源需要的比特数目:M/N = H2(p)=H(X).

    最后,请欣赏简笔画:

    后记:1、本文只是试图用一种更加直观的方式理解典型序列,存在不严格的地方,若需要严格证明推导,请查考信息论相关书籍。

         2、期末复习期间,逆自发行为,这样的减熵行为让我有种不祥的预兆。

         3、典型序列告诉我们,出现概率大的,也不一定是最典型的,所以有时一味追求后验概率最大,也不一定是最好的模型和假设。 





    展开全文
  • 时间序列分析

    万次阅读 多人点赞 2017-03-22 17:04:51
    这些集合被分析用来了解长期发展趋势,为了预测...但是什么时间序列?与常见的回归问题的不同?1、时间序列是跟时间有关的。所以基于线性回归模型的假设:观察结果是独立的。在这种情况下是不成立的。2、随着上升或者下

    http://blog.csdn.net/pipisorry/article/details/62053938

    时间序列简介

    时间序列是时间间隔不变的情况下收集的时间点集合。这些集合被分析用来了解长期发展趋势,为了预测未来或者表现分析的其他形式。但是什么时间序列?与常见的回归问题的不同?

    1、时间序列是跟时间有关的。所以基于线性回归模型的假设:观察结果是独立的。在这种情况下是不成立的。

    2、随着上升或者下降的趋势,更多的时间序列出现季节性趋势的形式,如:特定时间框架的具体变化。即:如果你看到羊毛夹克的销售上升,你就一定会在冬季做更多销售。

    因为时间序列的固有特性,有各种不同的步骤可以对它进行分析。

    时间序列的数据格式[pandas时间序列分析和处理Timeseries ]

    Note: pandas时间序列series的index必须是DatetimeIndex不能是Index,也就是如果index是从dataframe列中转换来的,其类型必须是datetime类型,不能是date、object等等其它类型!否则会报错:AttributeError: 'Index' object has no attribute 'inferred_freq'。[Decomposing trend, seasonal and residual time series elements]

    什么导致时间序列不稳定?

    这儿有两个主要原因。

    • 趋势-随着时间产生不同的平均值。举例:在飞机乘客这个案例中,我们看到总体上,飞机乘客的数量是在不断增长的。
    • 季节性-特定时间框架内的变化。举例:在特定的月份购买汽车的人数会有增加的趋势,因为车价上涨或者节假日到来。

    模型的根本原理或者预测序列的趋势和季节性,从序列中删除这些因素,将得到一个稳定的序列。然后统计预测技术可以在这个序列上完成。最后一步是通过运用趋势和季节性限制倒回到将预测值转换成原来的区间。


    时间序列的稳定性

    如果一个时间序列的统计特征如平均数,方差随着时间保持不变,我们就可以认为它是稳定的。稳定性的确定标准是非常严格的。但是,如果时间序列随着时间产生恒定的统计特征,根据实际目的我们可以假设该序列是稳定的。如下:

    • 恒定的平均数
    • 恒定的方差
    • 不随时间变化的自协方差

    为什么时间序列的稳定性这么重要?

    大部分时间序列模型是在假设它是稳定的前提下建立的。直观地说,我们可以这样认为,如果一个时间序列随着时间产生特定的行为,就有很高的可能性认为它在未来的行为是一样的。同时,根据稳定序列得出的理论是更加成熟的, 也是更容易实现与非稳定序列的比较。

    时间序列的稳定性测试

    1、绘制滚动统计:我们可以绘制移动平均数和移动方差,观察它是否随着时间变化。随着移动平均数和方差的变化,我认为在任何“t”瞬间,我们都可以获得去年的移动平均数和方差。如:上一个12个月份。但是,这更多的是一种视觉技术。

    2、DF检验:这是一种检查数据稳定性的统计测试。无效假设:时间序列是不稳定的。测试结果由测试统计量和一些置信区间的临界值组成。如果“测试统计量”少于“临界值”,我们可以拒绝无效假设,并认为序列是稳定的。[假设检验-t检验和Augmented Dickey–Fuller test ]

    from statsmodels.tsa.stattools import adfuller
    def test_stationarity(timeseries):
        
        #Determing rolling statistics
        rolmean = pd.rolling_mean(timeseries, window=12)
        rolstd = pd.rolling_std(timeseries, window=12)
    
        #Plot rolling statistics:
        orig = plt.plot(timeseries, color='blue',label='Original')
        mean = plt.plot(rolmean, color='red', label='Rolling Mean')
        std = plt.plot(rolstd, color='black', label = 'Rolling Std')
        plt.legend(loc='best')
        plt.title('Rolling Mean & Standard Deviation')
        plt.show(block=False)
        
        #Perform Dickey-Fuller test:
        print 'Results of Dickey-Fuller Test:'
        dftest = adfuller(timeseries, autolag='AIC')
        dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used'])
        for key,value in dftest[4].items():
            dfoutput['Critical Value (%s)'%key] = value
        print dfoutput

    The code is pretty straight forward. Please feel free to discuss the code in comments if you face challenges in grasping it.

    Let’s run it for our input series:

    test_stationarity(ts)

    皮皮blog



    趋势减少技术

    消除趋势的第一个方法是转换。例如,在本例中,我们可以清楚地看到,有一个显著的趋势。所以我们可以通过变换,惩罚较高值而不是较小值。这可以采用log,平方根,立方跟等等。

    ts_log = np.log(ts)
    我们可以使用一些技术来估计或对这个趋势建模,然后将它从序列中删除:

    聚合Aggregation – taking average for a time period like monthly/weekly averages取一段时间的平均值(月/周平均值)

    平滑Smoothing – taking rolling averages取滚动平均数

    多项式回归分析Polynomial Fitting – fit a regression model适合的回归模型

    平滑

    移动平均

    (英语:Moving Average,MA),又称“移动平均线”(简称均线),也称为滚动平均数(Rolling Average)、滚动平均值或运行平均值,是技术分析中一种分析时间序列数据的工具。移动平均可抚平短期波动,反映出长期趋势或周期。数学上,移动平均可视为一种卷积。

    最常见的是利用股价、回报或交易量等变数计算出移动平均。

    简单移动平均(英语:Simple Moving Average,SMA)是某变数之前n个数值的未作加权算术平均。例如,收市价的10日简单移动平均指之前10日收市价的平均数。

    加权移动平均(英语:Weighted Moving Average,WMA)指计算平均值时将个别数据乘以不同数值,在技术分析中,n日WMA的最近期一个数值乘以n、次近的乘以n-1,如此类推,一直到0。

    指数移动平均(英语:Exponential Moving Average,EMA或EWMA)是以指数式递减加权的移动平均。各数值的加权影响力随时间而指数式递减,越近期的数据加权影响力越重,但较旧的数据也给予一定的加权值。加权的程度以常数α决定,α数值介乎0至1。

    一般形式

    {\text{EMA}}={p_{1}+(1-\alpha )p_{2}+(1-\alpha )^{2}p_{3}+(1-\alpha )^{3}p_{4}+\cdots  \over 1+(1-\alpha )+(1-\alpha )^{2}+(1-\alpha )^{3}+\cdots }
    α可能的取值方法有

    com :     Specify decay in terms of center of mass, \alpha = 1 / (1 + com),  for com >= 0
    span :    Specify decay in terms of span, \alpha = 2 / (span + 1), for span > 1
    halflife : 使用参数“半衰期”来定义指数衰减量Specify decay in terms of half-life, \alpha = 1 - exp(log(0.5) / halflife), for halflife > 0   lz感觉0.5应该改成2??或者pandas内部有相应的转换?

    span: α用天数N来代表:\alpha ={2 \over {N+1}},所以,N=19天,代表α=0.1

    halflife : 在使用halflife计算移动平均时候,EMA计算中(1-α)的指数项为负数,表示与当前时间t的差值?如计算2017.2.30的EMA时,2017.2.29的指数项为-1。而在2017.2.15时,如果halflife设置为15,则p_{2015.2.15}的权重为(1-α)^-15 = (exp(log(0.5) / 15)^-15 = (exp(log(0.5) / 15 ^-15) = exp(-log0.5) = 2?

    [wikipedia移动平均]

    指数衰减

    某个量的下降速度和它的值成比例,称之为服从指数衰减。用符号可以表达为以下微分方程,其中N是指量,λ指衰减常数(或称衰变常数)。{\displaystyle {\ {dN}{dt}}=-\lambda N.}

    方程的一个解为:{\displaystyle N(t)=N_{0}e^{-\lambda t}.\,}

    平均寿命

    如果这个衰减量是一个集合中的离散元素,可以计算元素留在集合中的平均时间长度。这被称为平均寿命(一般称寿命)。并且它可以被证明与衰减速率有关。{\displaystyle \tau ={\frac {1}{\lambda }}.}

    平均时间(或被称为指数时间常数)由此被看做一个简单的缩放时间:{\displaystyle N(t)=N_{0}e^{-t/\tau }.\,}因而,这是量减少到初始量的1/e所需要的时间。

    类似的,下面所述的以2为底的指数缩放时间为半衰期

    半衰期

    对多数人而言更加直观的一个典型指数衰减是当量减少为初始量的一半所需要的时间。这个时间被称为半衰期,表示为{\displaystyle t_{0.5}}

    半衰期可以被写作衰减常数或者平均寿命的形式:{\displaystyle t_{0.5}={\frac {\ln 2}{\lambda }}=\tau \ln 2.}

    代入\tau    {\displaystyle N(t)=N_{0}2^{-t/t_{0.5}}.\,}

    平均寿命\tau等于半衰期除以ln2,或:{\displaystyle \tau ={\frac {t_{0.5}}{ln2}}\approx 1.442695040888963t_{0.5}.}

    [wikipedia指数衰减]

    皮皮blog

    pandas实现

    简单移动平均rolling

    这个方法有一个缺陷:要严格定义时段。在这种情况下,我们可以采用年平均数,但是对于复杂的情况的像预测股票价格,是很难得到一个数字的。所以,我们采取“加权移动平均法”可以对最近的值赋予更高的权重。

    Note: 前面window个rolling值是Nan,我们要丢掉这些NaN值

    Series.rolling(window, min_periods=None, freq=None, center=False, win_type=None, on=None, axis=0)

    主要参数

    window : int, or offset
        Size of the moving window. This is the number of observations used for calculating the statistic. Each window will be a fixed size.
        If its an offset then this will be the time period of each window. Each window will be a variable sized based on the observations included in the time-period. This is only

    valid for datetimelike indexes.

    min_periods : int, default None
        Minimum number of observations in window required to have a value (otherwise result is NA). For a window that is specified by an offset, this will default to 1.

    center : boolean, default False
        Set the labels at the center of the window. By default, the result is set to the right edge of the window. This can be changed to the center of the window by setting center=True.也就是rolling方法默认是将如2011.2.1 ~ 2011.2.30的均值设置为2011.2.30的均值,center=True则是将2011.2.1 ~ 2011.2.30的均值设置为2011.2.15对应的均值。相当于将rolling线向前移动了window/2个单位。

    win_type : string, default None lz猜测应该是取变长window的意思,没用过。这样的话时间间隔长的timeseries的window可能小点。

        Provide a window type. See the notes below.

    on : string, optional
        For a DataFrame, column on which to calculate the rolling window, rather than the index.

    [ref & Examples pandas.Series.rolling]

    指数移动平均ewm

    Note: (不同于rolling)在这种情况下就不会有遗漏值因为所有的值在一开始就被赋予了权重。所以在运行的时候,它没有先前的值参与

    Series.ewm(com=None, span=None, halflife=None, alpha=None, min_periods=0, freq=None, adjust=True, ignore_na=False, axis=0)

    主要参数

    com : float, optional
        Specify decay in terms of center of mass, \alpha = 1 / (1 + com),  for com >= 0
    span : float, optional
        Specify decay in terms of span, \alpha = 2 / (span + 1), for span > 1
    halflife : float, optional
        Specify decay in terms of half-life, \alpha = 1 - exp(log(0.5) / halflife), for halflife > 0

    alpha : float, optional
        Specify smoothing factor \alpha directly, 0 < \alpha <= 1

    [pandas.Series.ewm]

    皮皮blog



    趋势和季节性消除技术

    差分Differencing – taking the differece with a particular time lag采用一个特定时间差的差值

    分解Decomposition – modeling both trend and seasonality and removing them from the model.建立有关趋势和季节性的模型和从模型中删除它们

    差分Differencing

    处理趋势和季节性的最常见的方法之一就是差分法。在这种方法中,我们采用特定瞬间和它前一个瞬间的不同的观察结果。这主要是在提高平稳性。

    一般可以很大程度上减少了趋势。同样可以采取二阶或三阶差分在具体应用中获得更好的结果。

    前向差分

    前向差分有时候也称作数列的二项式变换

    函数的前向差分通常简称为函数的差分。对于函数\ f(x),如果在等距节点:

    x_{k}=x_{0}+kh,(k=0,1,...,n)
    \ \Delta f(x_{k})=f(x_{{k+1}})-f(x_{k})

    则称\ \Delta f(x),函数在每个小区间上的增量y_{{k+1}}-y_{k}\ f(x)一阶差分。

    在微积分学中的有限差分(finite differences),前向差分通常是微分在离散的函数中的等效运算。差分方程的解法也与微分方程的解法相似。当\ f(x)是多项式时,前向差分为Delta算子(称\Delta为差分算子[2]),一种线性算子。前向差分会将多项式阶数降低 1。

    逆向差分

    对于函数\ f(x_{k}),如果:\ \nabla f(x_{k})=f(x_{k})-f(x_{{k-1}}).\,则称\ \nabla f(x_{k})\ f(x)的一阶逆向差分。

    差分的阶

    一阶差分的差分为二阶差分,二阶差分的差分为三阶差分,其余类推。记:\ \Delta ^{n}[f](x)\ f(x)\ n阶差分。

    如果

    \ \Delta ^{n}[f](x)\ =\Delta \{\Delta ^{{n-1}}[f](x)\}\ =\Delta ^{{n-1}}[f](x+1)-\Delta ^{{n-1}}[f](x)

    根据数学归纳法,有

    \ \Delta ^{n}[f](x)=\sum _{{i=0}}^{n}{n \choose i}(-1)^{{n-i}}f(x+i)       其中,\ {n \choose i}为二项式系数。

    特别的,有\ \Delta ^{2}[f](x)=f(x+2)-2f(x+1)+f(x)

    [wikipedia差分]

    与差分相关的均差参考[数据插值方法]

    Pandas实现

    Series.shift(periods=1, freq=None, axis=0)[pandas.Series.shift]

    shift示例

    se
    se.shift()

    2013-01-01    0
    2013-01-02    1
    2013-01-03    2
    2013-01-04    5
    2013-01-05    4


    2013-01-01    NaN
    2013-01-02    0.0
    2013-01-03    1.0
    2013-01-04    2.0
    2013-01-05    5.0

    pandas实现一阶差(前向差分)示例

    ts_diff = ts - ts.shift()

    分解:趋势+季节性+残差

    在这种方法中,趋势和季节性是分别建模的并倒回到序列的保留部分。

    from statsmodels.tsa.seasonal import seasonal_decompose
    decomposition = seasonal_decompose(ts_log)
    
    trend = decomposition.trend
    seasonal = decomposition.seasonal
    residual = decomposition.resid
    
    plt.subplot(411)
    plt.plot(ts_log, label='Original')
    plt.legend(loc='best')
    plt.subplot(412)
    plt.plot(trend, label='Trend')
    plt.legend(loc='best')
    plt.subplot(413)
    plt.plot(seasonal,label='Seasonality')
    plt.legend(loc='best')
    plt.subplot(414)
    plt.plot(residual, label='Residuals')
    plt.legend(loc='best')
    plt.tight_layout()
    16. decompose

    在这里我们可以看到趋势,季节性从数据分离,我们可以建立残差的模型,让我们检查残差的稳定性。

    ts_log_decompose = residual
    ts_log_decompose.dropna(inplace=True)
    test_stationarity(ts_log_decompose)

    这样时间序列是非常接近稳定。你也可以尝试高级的分解技术产生更好的结果。同时,你应该注意到, 在这种情况下将残差转换为原始值对未来数据不是很直观。

    [Source code for statsmodels.tsa.seasonal]

    Note: decomposition = seasonal_decompose(ts_log)

    1 如果你的数据的index不是DatetimeIndex而是其它的就会出错

    AttributeError: 'Index' object has no attribute 'inferred_freq'

    AttributeError: 'Float64Index' object has no attribute 'inferred_freq'

    2 如果你的数据的DatetimeIndex不能自动识别出datetime的freq就会出错

    ValueError: You must specify a freq or x must be a pandas object with a timeseries index

    这时应该手动指定decomposition = seasonal_decompose(ts_log, freq = 1)

    3 warnning

    VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future

    皮皮blog



    时间序列预测

    从上我们看到了不同的技术,并且在使得时间序列得以稳定上运作良好。让我们通过差分后建立时间序列模型,因为差分是很受欢迎的技术,也相对更容易添加噪音和季节性从而倒回到预测残差residuals。

    在执行趋势和季节性评估技术上,有两种情况:

    • 值之间不含依赖的严格稳定系列。简单的情况下,我们可以建立残差residuals模型作为白噪音(指功率谱密度在整个频域内均匀分布的噪声),但这非常罕见。
    • 序列之间含有明显依赖。在这种情况下,我们需要使用一些统计模型像ARIMA(差分自回归移动平均模型)来预测数据。

    这里简要介绍一下ARIMA,但不会介绍技术细节,但如果你希望更有效地应用它们,你应该理解这些概念的细节。ARIMA代表差分自回归移动平均(Auto-Regressive Integrated Moving Averages)。平稳时间序列的ARIMA预测的只不过是一个线性方程(如线性回归)。

    预测依赖于ARIMA模型参数(p d q)

    • 自回归项的数目Number of AR (Auto-Regressive) terms (p):AR条件仅仅是因变量的滞后。如:如果P等于5,那么预测x(t)将是x(t-1)。。。(t-5)。
    • 移动平均项的数目Number of MA (Moving Average) terms (q):MA条件是预测方程的滞后预测错误。如:如果q等于5,预测x(t)将是e(t-1)。。。e(t-5),e(i)是移动平均叔在第ith个瞬间和实际值的差值。
    • 差分数目Number of Differences (d):它们是非季节性的差值的数目,即这种情况下我们采用一阶差分。所以传递变量令d=0或者传递原始变量令d=1,两种方法得到的结果一样。

    如何确定“p”和“q”的值

    我们使用两个坐标来确定这些数字。

    1. 自相关函数Autocorrelation Function (ACF):这是时间序列和它自身滞后版本之间的相关性的测试。比如在自相关函数可以比较时间的瞬间‘t1’…’t2’以及序列的瞬间‘t1-5’…’t2-5’ (t1-5和t2 是结束点)。
    2. 部分自相关函数Partial Autocorrelation Function (PACF):这是时间序列和它自身滞后版本之间的相关性测试,但是是在预测(已经通过比较干预得到解释)的变量后。如:滞后值为5,它将检查相关性,但是会删除从滞后值1到4得到的结果。

    时间序列(在差分后)的自回归函数和部分自回归函数绘制为:

    #ACF and PACF plots:
    from statsmodels.tsa.stattools import acf, pacf
    lag_acf = acf(ts_log_diff, nlags=20)
    lag_pacf = pacf(ts_log_diff, nlags=20, method='ols')
    #Plot ACF: 
    plt.subplot(121) 
    plt.plot(lag_acf)
    plt.axhline(y=0,linestyle='--',color='gray')
    plt.axhline(y=-1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray')
    plt.axhline(y=1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray')
    plt.title('Autocorrelation Function')
    #Plot PACF:
    plt.subplot(122)
    plt.plot(lag_pacf)
    plt.axhline(y=0,linestyle='--',color='gray')
    plt.axhline(y=-1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray')
    plt.axhline(y=1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray')
    plt.title('Partial Autocorrelation Function')
    plt.tight_layout()

    Python

    此图中,0每一边的两条虚线之间是置信区间。这些可以用来确定“p”和“q”的值:

    1、p-部分自相关函数图第一次截断上层置信区间的滞后值。如果你仔细看,该值是p=2。

    2、q- 自相关函数图第一次截断上层置信区间的滞后值。如果你仔细看,该值是q=2。

    [http://discuss.analyticsvidhya.com/t/seasonal-parameter-in-arima-and-adf-test/7385/1]


    现在,考虑个体以及组合效应建立3个不同的ARIMA模型。我也会打印各自的RSS(RSS表示一组统计数据的平方和的平方根)。请注意,这里的RSS是对残差值来说的,而不是实际序列。

    首先,我们需要ARIMA模型。

    from statsmodels.tsa.arima_model import ARIMA

    p,d,q值可以通过ARIMA的order参数即元组(p,d,q)指定。

    建立三种情况下的模型:

    自回归(AR)模型:

    model = ARIMA(ts_log, order=(2, 1, 0))  
    results_AR = model.fit(disp=-1)  
    plt.plot(ts_log_diff)
    plt.plot(results_AR.fittedvalues, color='red')
    plt.title('RSS: %.4f'% sum((results_AR.fittedvalues-ts_log_diff)**2))

    Python

    移动平均数(MA )模型

    model = ARIMA(ts_log, order=(0, 1, 2))  
    results_MA = model.fit(disp=-1)  
    plt.plot(ts_log_diff)
    plt.plot(results_MA.fittedvalues, color='red')
    plt.title('RSS: %.4f'% sum((results_MA.fittedvalues-ts_log_diff)**2))

    Python

    组合模型

    model = ARIMA(ts_log, order=(2, 1, 2))  
    results_ARIMA = model.fit(disp=-1)  
    plt.plot(ts_log_diff)
    plt.plot(results_ARIMA.fittedvalues, color='red')
    plt.title('RSS: %.4f'% sum((results_ARIMA.fittedvalues-ts_log_diff)**2))

    Python

    Note: 如果报错TypeError: Cannot cast ufunc subtract output from dtype('float64') to dtype('int64') with casting rule 'same_kind',说明时序数据的数据类型不是float类型,astype转换一下就可以了。

    ARMAResults及其方法[ARMAResults (class in statsmodels.tsa.arima_model)]

    在这里我们可以看到,自回归函数模型和移动平均数模型几乎有相同的RSS,但相结合效果显著更好。


    倒回到原始区间

    现在,我们只剩下最后一步,即把这些值倒回到原始区间。

    既然组合模型获得更好的结果,让我们将它倒回原始值,看看它如何执行。

    第一步是作为一个独立的序列,存储预测结果并观察。

    predictions_ARIMA_diff = pd.Series(results_ARIMA.fittedvalues, copy=True)
    print predictions_ARIMA_diff.head()

    Python

    Note: 1 这些是从‘1949-02-01’开始,而不是第一个月。为什么?这是因为我们将第一个月份取为滞后值,一月前面没有可以减去的元素。

    2 这里fittedvalues是已知的数据(或者说是训练数据吧),和[statsmodels.tsa.arima_model.ARMAResults.predict]可以得到相同结果,但是不能是未来的结果。

    3 这里只是预测的已有的数据,实际中我们当然是要预测未来的数据。这时应该使用forecast方法,如预测最后时间之后14天的结果:

    print(results_ARIMA.forecast(14)[0])

    [statsmodels.tsa.arima_model.ARMAResults.forecast]

    将差分转换为对数尺度的方法是这些差值连续地添加到基本值。一个简单的方法就是首先确定索引的累计总和,然后将其添加到基本值(这里就是第一个月的值)。

    predictions_ARIMA_diff_cumsum = predictions_ARIMA_diff.cumsum()
    print predictions_ARIMA_diff_cumsum.head()

    Python

    你可以在head()使用之前的输出结果进行回算,检查这些是否正确的。接下来我们将它们添加到基本值。为此我们将使用基本值作为所有的值来创建一个序列,并添加差值。

    predictions_ARIMA_log = pd.Series(ts_log.ix[0], index=ts_log.index)
    predictions_ARIMA_log = predictions_ARIMA_log.add(predictions_ARIMA_diff_cumsum,fill_value=0)
    predictions_ARIMA_log.head()

    Python

    第一个元素是基本值本身,从基本值开始值累计添加。

    最后一步是将指数与原序列比较。

    predictions_ARIMA = np.exp(predictions_ARIMA_log)
    plt.plot(ts)
    plt.plot(predictions_ARIMA)
    plt.title('RMSE: %.4f'% np.sqrt(sum((predictions_ARIMA-ts)**2)/len(ts)))

    Python

    最后我们获得一个原始区间的预测结果。虽然不是一个很好的预测。但是你获得了思路不是吗?现在,我把它留个你去进一步改进,做一个更好的方案。

    在本文中,我试图提供你们一个标准方法去解决时间序列问题。这里我们广泛的讨论了稳定性的概念和最终的预测残差。这是一个漫长的过程,我跳过了一些统计细节,我鼓励大家使用这些作为参考材料。

    皮皮blog

    from: http://blog.csdn.net/pipisorry/article/details/62053938

    ref: [Complete guide to create a Time Series Forecast (with Codes in Python)]*

    [时间序列预测全攻略]

    [平稳时间序列预测法]

    [时间序列分析课件 第三章 平稳时间序列分析.ppt]


    展开全文
  • 1.什么是序列化和反序列化 2.为什么要进行序列化 2.Android中序列化的两种方式 2.1 实现java.io.Serializable 接口 2.1.1 serialVersionUID 属性 2.2 实现android.os.Parcelable 接口 3.Parcelable与...

    目录

     

    1.什么是序列化和反序列化

    2.为什么要进行序列化

    2.Android中序列化的两种方式

    2.1 实现 java.io.Serializable 接口

    2.1.1 serialVersionUID 属性

    2.2 实现 android.os.Parcelable 接口

    3.Parcelable与Serializable的性能比较

    4.Android中如何使用Parcelable进行序列化操作

    5.Parcelable的工作原理

    6.相关实例


    1.什么是序列化和反序列化

    序列化:是指将对象的状态信息转换为可以存储或传输的形式的过程。

    反序列化:是指将序列化后的数据重新恢复成目标对象的过程。

    2.为什么要进行序列化

    1)、永久的保存对象数据(将对象数据保存在文件或磁盘中);

    2)、使对象数据在网络上的传输(由于网络传输是以字节流的方式对数据进行传输的,因此序列化的目的是将对象数据转换成字节流的形式);

    3)、使对象数据能在进程间进行传递(基础类型数据除外,对象类型数据必须进行序列化操作后才能进行传输);

    4)、在Android Intent之间,基本类型的数据可直接进行传输,但是传递复杂类型数据的时候,必须进行序列化操作;

    5)、序列化对象的时候只是针对变量进行序列化,不针对方法进行序列化。

    2.Android中序列化的两种方式

    2.1 实现 java.io.Serializable 接口

    import java.io.Serializable;
    
    public class User implements Serializable {
        //同时在类中声明该字段
        public static final long serialVersionUID = 1L;
    }
    

      示例代码如下

    package com.jiancode.binder.bean;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private String userId;
        private String userName;
        private int age;
    
        public User(String userId, String userName, int age) {
            this.userId = userId;
            this.userName = userName;
            this.age = age;
        }
    
        public String getUserId() {
            return userId;
        }
    
        public void setUserId(String userId) {
            this.userId = userId;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "userId='" + userId + '\'' +
                    ", userName='" + userName + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    package com.jiancode.binder;
    
    import android.util.Log;
    
    import com.jiancode.binder.bean.User;
    
    import org.junit.Test;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    public class SerializableTest {
    
        public static final String TAG = Serializable.class.getSimpleName();
    
        @Test
        public void testSerializable(){
            User user = new User("1","test",23);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(new                     
                    FileOutputStream("cache.txt"));
                oos.writeObject(user);
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Test
        public void testUnSerializable(){
            try {
                ObjectInputStream ois = new ObjectInputStream(new     
                    FileInputStream("cache.txt"));
                User user = (User) ois.readObject();
                Log.e(TAG,user.toString());
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    

    我们可以看到,序列化成功后,文件中保存的数据是一堆乱码

     反序列话口得到的数据如下,

    那么二者究竟是不是同一个对象呢?

    @Test
        public void testEquals(){
            User user = new User("1","test",23);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cache.txt"));
                oos.writeObject(user);
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            User user2 = null;
            try {
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cache.txt"));
                 user2= (User) ois.readObject();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            System.err.println(user);
            System.err.println(user2);
        }

    从上图结果中我们可以看出,二者并不是同一个对象,其实原理很简单,对象序列化完成后,被垃圾回收期回收,在内存中被释放,反序列化出来的对象是一个新的对象,只不过其属性值和原来的对象是一样的。

    2.1.1 serialVersionUID 属性

    刚开始提到,不指定serialVersionUID也可以完成序列化,那么到底要不要指定呢?如果指定的话,其后面的值又表示什么意思呢?其实,这个serialVersionUID是用来辅助序列化和反序列化的,原则上只有序列化后的数据中serialVersionUID和当前类的serialVersionUID是一致的,才能被正常的反序列化。

    serialVersionUID的详细工作机制是这样的:序列化的时候系统会把当前类的serialVersionUID写入序列化文件中,看它时候和当前类的serialVersionUID一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候就可以成功反序列化;否则就说明当前类和序列话的类相比发生了该变,比如成员变量的数量,类型发生了改变,这个时候是无法被反序列化的

    一般情况下,我们应该手动指定该值,比如1L,如果不手动指定,比如增加或者删除了某些变量,那么系统会重新计算当前类的hashCode并把它赋值给serialVersionUID,这样反序列化就会失败。还有一种特殊的情况,如果类的结构发生了非常规的改变,比如修改了类名或者修改类的属性,即使serialVersionUID相同,也会反序列化失败。

    2.2 实现 android.os.Parcelable 接口

    Parcelable也是一个接口,只要实现了该接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递,下面的示例是一个典型的用法。

    package com.jiancode.binder.bean;
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class Book implements Parcelable {
        private int bookId;
        private String bookName;
    
        public Book(int bookId, String bookName) {
            this.bookId = bookId;
            this.bookName = bookName;
        }
    
        public int getBookId() {
            return bookId;
        }
    
        public void setBookId(int bookId) {
            this.bookId = bookId;
        }
    
        public String getBookName() {
            return bookName;
        }
    
        public void setBookName(String bookName) {
            this.bookName = bookName;
        }
    
        @Override
        public String toString() {
            return "Book{" +
                    "bookId=" + bookId +
                    ", bookName='" + bookName + '\'' +
                    '}';
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(bookId);
            dest.writeString(bookName);
        }
    
        public static final Creator<Book> CREATOR = new Parcelable.Creator<Book>(){
    
            @Override
            public Book createFromParcel(Parcel source) {
                return new Book(source);
            }
    
            @Override
            public Book[] newArray(int size) {
                return new Book[size];
            }
        };
    
        private Book(Parcel in){
            bookId = in.readInt();
            bookName = in.readString();
        }
    }

    这里先说下Parcel,Parcel内部包装了可序列化的数据,可以在Binder中自由传输。从上面的代码可以看出,在序列化的过程中需要实现的功能有序列化、反序列化和内容描述。序列化的功能有writeToParcel方法来完成,最终是通过Parcel中的一系列write方法来完成的;反序列化有CREATOR来完成,其内部标明了如何创建序列化对象和数组,并通过Parcel的一系列read方法来完成反序列化操作;内容描述功能有describeContents方法来完成,几乎所有情况下这个方法都应该返回0,当且仅当对象中存在文件描述符时,此方法返回1。

    Parcelable的方法说明
    方法 功能 标记位
    createFromParcel(Parcel in) 从序列化后的对象中创建原始对象  
    new Array(int size) 创建指定长度的原始对象数组  
    Book(Parcel in) 从序列化后的对象中创建原始对象  
    writeToParcel(Parcel out,int flags) 将当前对象写入序列化结构中,其中flags标识有两种:0或1。为1时标识当前对象需要作为返回值返回,不能立即释放资源,几乎所有情况都为0 PARCELABLE_WRITE_RETURN_VALUE
    describeContents 返回当前对象的内容描述,如果含有文件描述符,返回一,否则返回0,几乎所有的情况都返回0。 CONTENTS_FILE_DESCRIPTOR

    3.Parcelable与Serializable的性能比较

    首先Parcelable的性能要强于Serializable的原因我需要简单的阐述一下

      1). 在内存的使用中,前者在性能方面要强于后者

      2). 后者在序列化操作的时候会产生大量的临时变量,(原因是使用了反射机制)从而导致GC的频繁调用,因此在性能上会稍微逊色

      3). Parcelable是以Ibinder作为信息载体的.在内存上的开销比较小,因此在内存之间进行数据传递的时候,Android推荐使用Parcelable,既然是内存方面比价有优势,那么自然就要优先选择.

      4). 在读写数据的时候,Parcelable是在内存中直接进行读写,而Serializable是通过使用IO流的形式将数据读写入在硬盘上.

      但是:虽然Parcelable的性能要强于Serializable,但是仍然有特殊的情况需要使用Serializable,而不去使用Parcelable,因为Parcelable无法将数据进行持久化,因此在将数据保存在磁盘的时候,仍然需要使用后者,因为前者无法很好的将数据进行持久化.(原因是在不同的Android版本当中,Parcelable可能会不同,因此数据的持久化方面仍然是使用Serializable)

    4.Android中如何使用Parcelable进行序列化操作

    可参考上面的额Book示例

    5.Parcelable的工作原理

    更新中......

    6.相关实例

    第一个Activity

       private void startSencondActivity() {
            Book book = new Book(1,"2");
            Bundle bundle = new Bundle();
            bundle.putParcelable("book",book);
            Intent intent = new Intent(this,SecondActivity.class);
            intent.putExtras(bundle);
            startActivity(intent);
        }

    第二个Activity

     private void getData(){
            Bundle bundle = getIntent().getExtras();
            Book book = bundle.getParcelable("book");
            Log.e(TAG,book.toString());
        }

     

    展开全文
  • 时间序列分析和预测(含实例及代码)

    万次阅读 多人点赞 2018-09-17 21:37:34
    研究时间序列主要目的:进行预测,根据已有的时间序列数据预测未来的变化。 时间序列预测关键:确定已有的时间序列的变化模式,并假定这种模式会延续到未来。 时间序列预测法的基本特点 假设事物发展趋势会...

    导论

    研究时间序列主要目的:进行预测,根据已有的时间序列数据预测未来的变化。

    时间序列预测关键:确定已有的时间序列的变化模式,并假定这种模式会延续到未来。

    时间序列预测法的基本特点
    • 假设事物发展趋势会延伸到未来
    • 预测所依据的数据具有不规则性
    • 不考虑事物发展之间的因果关系

    时间序列数据用于描述现象随时间发展变化的特征

    时间序列分析就其发展历史阶段和所使用的统计分析方法看:传统的时间序列分析和现代时间序列分析

    一、时间序列及其分解

    时间序列(time series)是同一现象在不同时间上的相继观察值排列而成的序列。根据观察时间的不同,时间序列中的时间可以是可以是年份、季度、月份或其他任何时间形式。

    时间序列:

    (1)平稳序列(stationary series)

    是基本上不存在趋势的序列,序列中的各观察值基本上在某个固定的水平上波动,在不同时间段波动程度不同,但不存在某种规律,随机波动

    (2)非平稳序列(non-stationary series)

    是包含趋势、季节性或周期性的序列,只含有其中一种成分,也可能是几种成分的组合。可分为:有趋势序列、有趋势和季节性序列、几种成分混合而成的复合型序列。

    趋势(trend):时间序列在长时期内呈现出来的某种持续上升或持续下降的变动,也称长期趋势。时间序列中的趋势可以是线性和非线性。

    季节性(seasonality):季节变动(seasonal fluctuation),是时间序列在一年内重复出现的周期波动。销售旺季,销售淡季,旅游旺季、旅游淡季,因季节不同而发生变化。季节,不仅指一年中的四季,其实是指任何一种周期性的变化。含有季节成分的序列可能含有趋势,也可能不含有趋势。

    周期性(cyclicity):循环波动(cyclical fluctuation),是时间序列中呈现出来的围绕长期趋势的一种波浪形或振荡式波动。周期性是由商业和经济活动引起的,不同于趋势变动,不是朝着单一方向的持续运动,而是涨落相间的交替波动;不同于季节变动,季节变动有比较固定的规律,且变动周期大多为一年,循环波动则无固定规律,变动周期多在一年以上,且周期长短不一。周期性通常是由经济环境的变化引起。

    除此之外,还有偶然性因素对时间序列产生影响,致使时间序列呈现出某种随机波动。时间序列除去趋势、周期性和季节性后的偶然性波动,称为随机性(random),也称不规则波动(irregular variations)。

    时间序列的成分可分为4种:趋势(T)、季节性或季节变动(S)、周期性或循环波动(C)、随机性或不规则波动(I)。传统时间序列分析的一项主要内容就是把这些成分从时间序列中分离出来,并将它们之间的关系用一定的数学关系式予以表达,而后分别进行分析。按4种成分对时间序列的影响方式不同,时间序列可分解为多种模型:加法模型(additive model),乘法模型(multiplicative model)。乘法模型:Y_t=T_t\times S_t\times C_t\times I_t

    二、描述性分析

    1、图形描述

    2、增长率分析

    是对现象在不同时间的变化状况所做的描述。由于对比的基期不同,增长率有不同的计算方法。

    (1)增长率(growth rate):增长速度,是时间序列中报告期观察值与基期观察值之比减1后的结果,用%表示。由于对比的基期不同,可分为环比增长率和定基增长率。

    环比增长率:是报告期观察值与前一时期观察值之比减1,说明现象逐期增长变化的程度;

    定基增长率是报告期观察值与某一固定时期观察值之比减1,说明现象在整个观察期内总的增长变化程度。

    设增长率为G:          环比增长率 :G_i=\frac{Y_i-Y_{i-1}}{Y_{i-1}}=\frac{Y_i}{Y_{i-1}}-1,i=1,2...,n

                                           定基增长率 :G_i=\frac{Y_i-Y_{0}}{Y_{0}}=\frac{Y_i}{Y_{0}}-1,i=1,2...,n

    (2)平均增长率(average rate of increase):平均增长速度,是时间序列中逐期环比值(环比发展速度)的几何平均数减1的结果:\bar{G}=\sqrt[n]{\frac{Y_1}{Y_{0}}\times \frac{Y_2}{Y_{1}}...\times \frac{Y_n-Y_{n-1}}{Y_{i-1}}}-1=\sqrt[n]{\frac{Y_n-Y_{n-1}}{Y_{0}}}-1   n:环比值的个数

    (3)增长率分析中应注意的问题

    i:    当时间序列中的观察出现0或负数时,不宜计算增长率。这种序列计算增长率,要么不符合数学公理,要么无法解释其实际意义。可用绝对数进行分析。

    ii:    有些情况下,不能单纯就增长率论增长率,注意增长率与绝对水平结合起来。增长率是一个相对值,与对比的基数值的大小有关。这种情况,计算增长1%的绝对值来克服增长率分析的局限性:

    增长1%的绝对值表示增长率每增长一个百分点而增加的绝对数量:增长1%的绝对值=前期水平/100

    三、时间序列预测的程序

    时间序列分析的主要目的之一是根据已有的历史数据对未来进行预测。时间序列含有不同的成分,如趋势、季节性、周期性和随机性。对于一个具体的时间序列,它可能含有一种成分,也可能同时含有几种成分,含有不同成分的时间序列所用的预测方法是不同的。预测步骤:

    第一步:确定时间序列所包含的成分,确定时间序列的类型

    第二步:找出适合此类时间序列的预测方法

    第三步:对可能的预测方法进行评估,以确定最佳预测方案

    第四步:利用最佳预测方案进行预测

    1、确定时间序列成分

    (1)确定趋势成分

    确定趋势成分是否存在,可绘制时间序列的线图,看时间序列是否存在趋势,以及存在趋势是线性还是非线性。

    利用回归分析拟合一条趋势线,对回归系数进行显著性检验。回归系数显著,可得出线性趋势显著的结论。

    (2)确定季节成分

    确定季节成分是否存在,至少需要两年数据,且数据需要按季度、月份、周或天来记录。可绘图,年度折叠时间序列图(folded annual time series plot),需要将每年的数据分开画在图上,横轴只有一年的长度,每年的数据分别对应纵轴。如果时间序列只存在季节成分,年度折叠时间序列图中的折线将会有交叉;如果时间序列既含有季节成分又含有趋势,则年度折叠时间序列图中的折线将不会有交叉,若趋势上升,后面年度的折线将会高于前面年度的折线,若下降,则后面年度的折线将会低于前面年度的折线。

    2、选择预测方法

    确定时间序列类型后,选择适当的预测方法。利用时间数据进行预测,通常假定过去的变化趋势会延续到未来,这样就可以根据过去已有的形态或模式进行预测。时间序列的预测方法:传统方法:简单平均法、移动平均法、指数平滑法等,现代方法:Box-Jenkins 的自回归模型(ARMA)。

    一般来说,任何时间序列都会有不规则成分存在,在商务和管理数据中通常不考虑周期性,只考虑趋势成分和季节成分。

    不含趋势和季节成分的时间序列,即平稳时间序列只含随机成分,只要通过平滑可消除随机波动。因此,这类预测方法也称平滑预测方法。

    3、预测方法的评估

    在选择某种特定的方法进行预测时,需要评价该方法的预测效果或准确性。评价方法是找出预测值与实际值的差距,即预测误差。最优的预测方法就是预测误差达到最小的方法。

    预测误差计算方法:平均误差,平均绝对误差、均方误差、平均百分比误差、平均绝对百分比误差。方法的选择取决于预测者的目标、对方法的熟悉程度。

    (1)平均误差(mean error):Y:观测值,F:预测值,n预测值个数

                   ME=\frac{\sum_{i=1}^{n}(Y_i-F_i)}{n}     

    由于预测误差的数值可能有正有负,求和的结果就会相互抵消,这种情况下,平均误差可能会低估误差。

    (2)平均绝对误差(mean absolute deviation)是将预测误差取绝对值后计算的平均无擦,MAD:

                  MAD=\frac{\sum_{i=1}^{n}|Y_i-F_i|}{n}

    平均绝对误差可避免误差相互抵消的问题,因而可以准确反映实际预测误差的大小。

    (3)均方误差(mean square error):通过平方消去误差的正负号后计算的平均误差,MSE:

                MSE=\frac{\sum_{i=1}^{n}(Y_i-F_i)^2}{n}

    (4)平均百分比误差和平均绝对百分比误差

    ME,MAD,MSE的大小受时间序列数据的水平和计量单位的影响,有时并不能真正反映预测模型的好坏,只有在比较不同模型对同一数据的预测时才有意义。平均百分比误差(mean percentage error,MPE)和平均绝对百分比误差(mean absolute percentage error,MAPE)则不同,它们消除了时间序列数据的水平和计量单位的影响,是反映误差大小的相对值。

    MPE=\frac{\sum_{i=1}^{n}(\frac{Y_i-F_i}{Y_i}\times 100)}{n} 

    MAPE=\frac{\sum_{i=1}^{n}(\frac{|Y_i-F_i|}{Y_i}\times 100)}{n}

    4、平稳序列的预测

    平稳时间序列只含有随机成分,预测方法:简单平均法、移动平均法、指数平滑法。主要通过对时间序列进行平滑以消除随机波动,又称平滑法。平滑法可用于对时间序列进行短期预测,也可对时间序列进行平滑以描述序列的趋势(线性趋势和非线性趋势)。

    (1)简单平均法:根据已有的t期观察值通过简单平均法来预测下一期的数值。设时间序列已有的t期观察值为Y_1,Y_2,...,Y_t,则t+1期的预测值F_{t+1}为:F_{t+1}=\frac{1}{t}(Y_1+Y_2+...+Y_t)=\frac{1}{t}\sum_{i=1}^{t} Y_i

    到了t+1期后,有了t+1期的实际值,t+1期的预测误差e_{t+1}为:e_{t+1}=Y_{t+1}-F_{t+1}

    t+2期预测值:F_{t+2}=\frac{1}{t+1}(Y_1+Y_2+...+Y_t+Y_{t+1})=\frac{1}{t+1}\sum_{i=1}^{t+1} Y_i

    简单平均法适合对较为平稳的时间序列进行预测,即当时间序列没有趋势时,用该方法比较好。但如果时间序列有趋势或季节成分,该方法的预测则不够准确。简单平均法将远期的数值和近期的数值看作对未来同等重要。从预测角度,近期的数值比远期的数值对未来有更大的作用,因此简单平均法预测的结果不够准确。

    (2)移动平均法(moving average):通过对时间序列逐期递移求得平均数作为预测值的一种预测方法,有简单移动平均法(simple moving average)和加权移动平均法(weighted moving average).

    简单移动平均将最近k期数据加以平均,作为下一期的预测值。设移动平均间隔为k(1<k<t),则t期的移动平均值为:

    \bar{Y}_{t}=\frac{Y_{t-k+1}+Y_{t-k+2}+...+Y_{t-1}+Y_{t}}{k}  是对时间序列的平滑结果,通过这些平滑值可描述出时间序列的变化形态或趋势。也可以用来预测。

    t+1期的简单移动平均预测值为:F_{t+1}=\bar{Y}_{t}=\frac{Y_{t-k+1}+Y_{t-k+2}+...+Y_{t-1}+Y_{t}}{k}

    t+2期的简单移动平均预测值为:F_{t+2}=\bar{Y}_{t+1}=\frac{Y_{t-k+2}+Y_{t-k+3}+...+Y_{t}+Y_{t+1}}{k}

    移动平均法只使用最近k期的数据,在每次计算移动平均值时,移动的间隔都为k,也适合对较为平稳的时间序列进行预测。应用关键是确定合理的移动平均间隔k。对于同一个时间序列,采用不同的移动间隔,预测的准确性是不同的。可通过试验的方法,选择一个使均方误差达到最小的移动间隔。移动间隔小,能快速反映变化,但不能反映变化趋势;移动间隔大,能反映变化趋势,但预测值带有明显的滞后偏差。

    移动平均法的基本思想:移动平均可以消除或减少时间序列数据受偶然性因素干扰而产生的随机变动影响,适合短期预测。

    (3)指数平滑法(exponential smoothing)是通过对过去的观察值加权平均进行预测,使t+1期的预测值等t期的实际观察值与t期的预测值的加权的平均值。指数平滑法是从移动平均法发展而来,是一种改良的加权平均法,在不舍弃历史数据的前提下,对离预测期较近的历史数据给予较大权数,权数由近到远按指数规律递减,因此称指数平滑。指数平滑有一次指数平滑法、二次指数平滑法、三次指数平滑法等。

    一次指数平滑法也称单一指数平滑法(single exponential smoothing),只有一个平滑系数,且观察值离预测时期越久远,权数变得越小。一次指数平滑是将一段时期的预测值与观察值的线性组合作为t+1时期的预测值,预测模型为:

    F_{t+1}=\alpha Y_t+(1-\alpha )F_t      \alpha:平滑系数(0\leq \alpha\leq 1

    t+1期的数据是t期的实际观察值与t期的预测值的加权平均。1期的预测值=1期的观察值

    2期预测值:F_{2}=\alpha Y_1+(1-\alpha )F_1=\alpha Y_1+(1-\alpha )Y_1=Y_1

    3期预测值:F_{3}=\alpha Y_2+(1-\alpha )F_2=\alpha Y_2+(1-\alpha )Y_1

    4期预测值:F_{4}=\alpha Y_3+(1-\alpha )F_3=\alpha Y_3+\alpha (1-\alpha )Y_2+ (1-\alpha )^2Y_1

    对指数平滑法的预测精度,用均方误差来=衡量:

    F_{t+1}=\alpha Y_t+(1-\alpha )F_t

              =F_t+\alpha (Y_t-F_t)

    F_{t+1}是t期的预测值F_{t}加上用\alpha调整的t期预测误差(Y_t-F_t)。

    使用指数平滑法时, 关键问题是确定一个合适的平滑系数\alpha,不同的\alpha对预测结果产生不同的影响。

    \alpha=0,预测值仅仅是重复上一期的预测结果;\alpha=1,预测值就是上一期的实际值;

    \alpha越接近1,模型对时间序列变化的反应就越及时,因为它给当前的实际值赋予了比预测值更大的权数;

    \alpha越接近0,给当前的预测值赋予了更大的权数,模型对时间序列变化的反应就越慢。

    当时间序列有较大随机波动时,选较大\alpha,以便能很快跟上近期的变化;当时间序列比较平稳时,选较小\alpha

    实际应用中,需考虑预测误差,用均方误差衡量预测误差大小。确定\alpha时,可选择几个\alpha进行预测,然后找出预测误差最小的作为最后的\alpha值。

    与移动平均法一样,一次指数平滑法可用于对时间序列进行修匀,以消除随机波动,找出序列的变化趋势。

    用一次指数平滑法进行预测时,一般\alpha取值不大于0.5,若大于0.5,才能接近实际值,说明序列有某种趋势或波动过大。

    阻尼系数  \beta=1-\alpha ,阻尼系数越小,近期实际值对预测结果的影响越大,反之,越小。阻尼系数是根据时间序列的变化特性来选取。

    5、趋势型序列的预测

    时间序列的趋势可分为线性趋势和非线性趋势,若这种趋势能够延续到未来,就可利用趋势进行外推预测。有趋势序列的预测方法主要有线性趋势预测、非线性趋势预测和自回归模型预测。

    (1) 线性趋势预测

    线性趋势(linear trend)是指现象随着时间的推移而呈现稳定增长或下降的线性变化规律。

    趋势方程:\hat{Y}_t=b_0+b_1t     \hat{Y}_t:时间序列Y_t的预测值;b_1是趋势线斜率,表示时间t 变动一个单位,观察值的平均变动数量

    (2) 非线性趋势预测

    序列中的趋势通常可认为是由于某种固定因素作用同一方向所形成的。若这种因素随时间推移按线性变化,则可对时间序列拟合趋势直线;若呈现出某种非线性趋势(non-linear trend),则需要拟合适当的趋势曲线。

    i:   指数曲线(exponential curve):用于描述以几何级数递增或递减的现象,即时间序列的观察值Y_t按指数规律变化,或者时间序列的逐期观察值按一定的增长率增长或衰减。一般的自然增长及大多数经济序列都有指数变化趋势。

    趋势方程:\hat{Y}_t=b_0b_1^{t}     b_0,b_1为待定系数

    b_1>1,则增长率随着时间t的增加而增加;若b_1<1,则增长率随着时间t的增加而降低;若b_0>0,b_1<1,则预测值\hat{Y}_t逐渐降低以到0为极限。

    为确定b_0,b_1,可采用线性化手段将其化为对数直线形式,两端取对数:lg\hat{Y}_t=lgb_0+tlgb_1

    根据最小二乘原理,按直线形式的常数确定方法求得 lgb_0,lgb_1,求出 lgb_0,lgb_1后,再取其反对数,即可得到b_0,b_1

    \left\{\begin{matrix}\sum lgY=nlgb_0+lgb_1\sum t\\\sum t lgY_t=lgb_0\sum t+lgb_1\sum t^2\end{matrix}\right.

    ii:   多阶曲线:

    有些现象变化形态复杂,不是按照某种固定的形态变化,而是有升有降,在变化过程中可能有几个拐点。这时就需要拟合多项式函数。当只有一个拐点时,可拟合二项曲线,即抛物线;当有两个拐点时,需要拟合三阶曲线;有k-1个拐点时,需要拟合k阶曲线。

    6、复合型序列的分解预测

    复合型序列是指含有趋势、季节、周期和随机成分的序列。对这类序列的预测方法是将时间序列的各个因素依次分解出来,然后进行预测。由于周期成分的分析需要有多年的数据,实际中很难得到多年的数据,因此采用的分解模型为:Y_t=T_t\times S_t\times I_t

    预测方法有:季节性多元回归模型、季节自回归模型和时间序列分解法预测。

    分解法预测步骤:

    第一步:确定并分离季节成分。计算季节指数,以确定时间序列中的季节成分。然后将季节成分从时间序列中分离出去,即用每一个时间序列观察值除以相应的季节指数,以消除季节性。

    第二步:建立预测模型并进行预测。对消除了季节成分的时间序列建立适当的预测模型,并根据这一模型进行预测。

    第三步:计算最后的预测值。用预测值乘以相应的季节指数,得到最终的预测值。

    (1)确定并分离季节成分

    季节性因素分析是通过季节指数来表示各年的季节成分,以此描述各年的季节变动模式。

    i:  计算季节指数(seasonal index)

    季节指数刻画了序列在一个年度内各月或各季度的典型季节特征。在乘法模型中,季节指数以其平均数等于100%为条件而构成的,反映了某一月份或季度的数值占全年平均值的大小。若现象的发展没有季节变动,则各期的季节指数应等于100%;若某一月份或季度有明显的季节变化,则各期的季节指数应大于或小于100%。因此,季节变动的程度是根据各季节指数与其平均数(100%)的偏差程度来测定的。

    季节指数计算方法较多,移动平均趋势剔除法步骤:

    第一步:计算移动平均值(若是季节数据,采用4项移动平均,月份数据则采用12项移动平均),并对其结果进行中心化处理,即将移动平均的结果再进行一次二项移动平均,即得出中心化移动平均值(CMA)。

    第二步:计算移动平均的比值,即季节比率,即将序列的各观察值除以相应的中心化移动平均值,然后计算出各比值的季度或月份平均值。

    第三步:季节指数调整。由于各季节指数的平均数应应等于1或100%,若根据第二步计算的季节比率的平均值不等于1,则需要进行调整。具体方法:将第二步计算的每个季节比率的平均值除以它们的总平均值。

    ii:  分离季节成分

    计算出季节指数后,可将各实际观察值分别除以相应的季节指数,将季节成分从时间序列中分离出去:\frac{Y}{S}=\frac{T*S*I}{S}=T*I

    结果即为季节成分分离后的序列,反映了在没有季节因素影响下时间序列的变化形态。

    iii: 建立预测模型并进行预测

    7、时序案例分析

    https://blog.csdn.net/mengjizhiyou/article/details/104765862

     

    参考:贾俊平《统计学》第六版

    《统计学》pdf及课后答案:链接: https://pan.baidu.com/s/1dZPW0smz2cO-67zfn1BFyQ 提取码: ktxq 

    展开全文
  • Java序列化与反序列化的深度思考

    千次阅读 2021-01-21 14:13:57
    Java序列化与反序列
  • 已知出栈序列求所有的入栈序列头条实习一面的算法题,当时没有想出来,事后想起来求出栈序列的所有入栈序列和求进栈序列的所有出栈序列其实答案是一样的,所以只要按照求进栈序列的所有出栈序列来算就行了。...
  • 炼丹笔记干货作者:一元,四品炼丹师Informer:最强最快的序列预测神器01简介在很多实际应用问题中,我们需要对长序列时间序列进行预测,例如用电使用规划。长序列时间序列预测(LSTF...
  • 序列模式PrefixSpan算法介绍

    千次阅读 2016-09-13 15:35:36
    序列 序列(sequence)是一组排好序的项集,不一定是直接连续的,但依然满足次序。...sequence patternmining,针对Frequent Sequences,典型的应用还是限于离散型的序列,happens-after relationship and not just
  • 统计学——时间序列预测

    万次阅读 2019-02-15 10:43:12
    统计学(第6版) 贾俊平 读书笔记 第13章 时间序列分析和预测 ...非平稳序列是包含趋势、季节性或周期性的序列,又可以分为有趋势的序列、有趋势和季节性的序列、几种成分混合而成的复合型序列。 趋势是...
  • 时间序列的聚类方法

    万次阅读 多人点赞 2019-05-30 14:36:13
    时间序列的聚类方法 时间序列是按照时间排序的一组随机变量,它通常是在相等间隔的时间段内,依照给定的采样率,对某种潜在过程进行观测的结果。 时间序列数据是实值型的序列数据,具有数据量大、数据维度高以及数据...
  • 基本的序列模式挖掘:主要包括一些经典...增量式序列模式挖掘:用来研究当序列增加时,如何维护序列模式,提高数据挖掘效率的问题,典型算法有:ISM算法、ISE算法、IUS算法。 多维序列模式挖掘:它是将多维有价值...
  • 时间序列异常点检测

    千次阅读 2019-11-05 17:31:23
    时间序列异常检测--简单的语言介绍当前时间序列异常检测方法 在Statsbot,我们不断地回顾异常检测方法,并在此基础上改进我们的模型。 本文概述了目前最流行的时间序列异常检测算法及其优缺点。 这篇文章是写给...
  • serialize序列化和json

    千次阅读 2016-05-24 15:41:47
    序列化的概念】 序列化是将对象状态转换为可保持或可传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。 将对象的状态信息转换为可以存储或...
  • 时间序列分类算法ST及其实现代码

    千次阅读 2020-05-06 20:18:49
    时间序列分类(TSC)问题对分类算法提出了一个特殊的挑战:如何度量序列间的相似性。shapelet是一个时间序列序列,它允许基于形状的局部、相位无关相似性进行时间序列分类。(Shapelets是时间序列的辨别性子序列,...
  • 机器学习的一个重要方向是序列模式探索,典型的序列模式探索包括时间序列分析和非时间序列分析。...其中ARIMA模型多用于时间序列数量较多的趋势预测应用中,通常的数据量级为数十、数百、至数千;而GM模型多用于时间
  • 时间序列之ARIMA模型原理

    千次阅读 2019-04-18 22:55:50
    时间序列模型的意义: 在经典的回归模型中,主要是通过回归分析来建立不同变量之间的函数关系(因果关系),以考察事物之间的联系。本案例要讨论如何利用时间序列数据本身建立模型,以研究事物发展自身的规律,并...
  • 了解 TCP 系统调用序列

    千次阅读 2014-09-25 22:34:47
    TCP 堆栈代码数量繁多,深入到内核级别的完整调用序列可以帮助您了解 TCP 堆栈。在本文中,将回顾和学习关于 TCP 调用序列的详细信息,其中包括对 FreeBSD 的引用,以及在用户级进行系统调用后在 TCP 堆栈中发生的...
  • 第3章 序列化与压缩 3.1序列

    千次阅读 2013-07-19 08:28:06
    《Hadoop技术内幕:深入解析Hadoop Common和HDFS架构设计与实现原理》第3章序列化与压缩,本章涉及了org.apache.hadoop.io包下最重要的两部分内容:序列化和压缩。本节为大家介绍序列化。 第3章 序列化与压缩 ...
  • 时间序列及异常检测综述(资料)

    千次阅读 2019-03-06 17:11:28
    文章目录1. 背景2. 时间序列预测方法3. ARIMA3.1 ARIMA模型预测的流程3.2 学习资料4. Prophet4.1 Prophet流程4.2 Prophet注意4.3 学习资料5. 其他时序方法6. 异常诊断相关方法7....时间序列是一种典型的数据,...
  • 5.1循环序列模型 觉得有用的话,欢迎一起讨论相互学习~Follow Me 1.5不同类型的循环神经网络 上节中介绍的是 具有相同长度输入序列和输出序列的循环神经网络,但是对于很多应用Tx和TyTx和TyT_{x}和T_{y}并不...
  • ASP.NET中JSON的序列化和反序列

    千次阅读 2012-06-06 13:16:21
    在网站应用中使用JSON的场景越来越多,本文介绍ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介绍,ASP.NET如何序列化和反序列化的处理,在序列化和反序列化对日期时间、集合、字典的处理。  一、JSON简介...
  • 时间序列数据的典型示例是股市数据,其中股价随时间变化。 递归神经网络(RNN)已被证明可以有效解决序列问题。特别地,作为RNN的变体的长期短期记忆网络(LSTM)当前正在各种领域中用于解决序列问题。 序列问题的...
  • 文章目录时间序列分析和预测时间序列及其分解时间序列的描述性分析时间序列预测的程序确定时间序列成分选择预测方法预测方法的评估平稳序列的预测简单平均法移动平均法指数平滑法趋势型序列的预测线性趋势预测非线性...
  • 序列化和json区别

    千次阅读 2018-04-08 14:32:23
    序列化是将对象状态转换为可保持或可传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。将对象的状态信息转换为可以存储或传输的窗体的过程。 在序列...
  • 时间序列预测背景知识

    千次阅读 2019-01-19 19:01:39
    时间序列预测背景知识1、时间序列预测简介(introduction)2、时间序列可视化3、判断预测法4、线性回归模型5、时间序列分解1、时间序列预测简介(introduction)1、1 什么是可以被预测的1、2预测,计划和目标1、3预测...
  • 时间序列常用算法总结

    千次阅读 2020-12-14 10:06:06
    时间序列预测算法总结 文章目录时间序列预测算法总结前言一、基于统计的时序数据建模方法1.1传统时序数据建模方法1.1.1周期因子法1.1.2移动平均法1.1.3ARIMA模型1.1.3.1模型原理1.平稳性要求2.AR模型3.MA模型4.ARMA...
  • 混沌时间序列的几个例子

    万次阅读 多人点赞 2016-07-12 23:01:27
    混沌时间序列的例子:虫口模型、洛伦兹方程(天气预报模型)、CHne's吸引子 奇怪吸引子、吸引子 几个例子的MATLB程序,可以看到混沌序列的样子
  • 金融时间序列分析入门

    千次阅读 2019-02-18 23:50:20
    对某一个或者一组变量X(t)进行观察测量,将在一系列时刻t1, t2, …, tn所得的离散序列集合,称之为时间序列。(注意,X(ti)X(t_i)X(ti​)是一个随机变量) 特征 趋势:是时间序列在长时期内呈现出来的持续向上或...
  • java序列化方案对比

    千次阅读 2015-03-20 18:19:55
    另外如一些视频、音乐、购物等软件,凡是收藏的视频、歌曲、商品以及个人主页等,也应将这些用户私有的内容做序列化,以便无网进入时也能看到相关内容,并正常使用软件。  陆陆续续使用和测试
  • java序列化笔记

    千次阅读 2011-01-25 10:36:00
    概念: Java序列化是把对象状态保存到一个字节流中的过程,反序列化则是把由序列化生成的这一个字节流重新转换成对象的过程。   二.作用: 目前,一个典型的企业化应用程序一般会由多个组件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 70,068
精华内容 28,027
关键字:

典型序列的数量