-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.json
1 lines (1 loc) · 41.6 KB
/
search.json
1
[{"title":"ARMA 学习笔记","path":"/2024/05/08/ARMA-Learning/","content":"参考书:Time Series Analysis and Its Applications, 4-th Edition 基础概念 时间序列:一组随机变量按照时间顺序下标得到的序列,被称为时间序列 be defined as a collection of random variables indexed according to the order they are obtained in time. 白噪声:从不相关的随机变量中生成的时间序列被称为白噪声序列 The time series generated from uncorrelated variables is used as a model for noise in engineering applications, where it is called white noise 移动平均过程:对白噪声序列应用移动平均计算获得的时间序列。可以起到filter的效果 differ from the moving average series because one particular kind of oscillatory behavior seems to predominate, producing a sinusoidal type of behavior. A number of methods exist for generating series with this quasi-periodic behavior; we illustrate a popular one based on the autoregressive model 有周期性的时序数据不是移动平均过程 A complete description of a time series, observed as a collection of n random variables at arbitrary time points \\(t_1, t_2, . . . , t_n\\) , for any positive integer \\(n\\), is provided by the joint distribution function, evaluated as the probability that the values of the series are jointly less than the \\(n\\) constants, \\(c_1, c_2, . . . , c_n\\) \\[ F_{t_1, t_2, ..., t_n}(c_1, c_2, ..., c_n) = \\Pr(x_{t_1} \\le c_1, x_{t_2} \\le c_2, ..., x_{t_n} \\le c_n) \\] Although the joint distribution function describes the data completely, it is an unwieldy tool for displaying and analyzing time series data. The distribution func- tion (1.8) must be evaluated as a function of n arguments, so any plotting of the corresponding multivariate density functions is virtually impossible. 上述完整的概率分布函数只是一个模型,并不能直接使用。更有用的是下面的几个函数 marginal distribution functions: \\[ F_t(x) = P\\{x_t \\le x\\} \\] marginal density functions: \\[ f_t(x) = \\frac{\\partial F_t(x)}{\\partial x} \\] 期望函数(mean function): \\[ \\mu_{xt} = \\mathrm{E}(x_t) = \\int_{-\\infty}^{\\infty} xf_t(x)\\mathrm{d}x \\] \\(x\\)指随机变量,当只讨论一个时间序列时,通常把\\(\\mu_{xt}\\)简写作\\(\\mu_t\\) 自协方差函数(autocovariance function): \\[ \\gamma_x(s, t) = \\mathrm{cov}(x_s, x_t) = \\mathrm{E}[(x_s - \\mu_s)(x_t - \\mu_t)] \\] 其中\\(s\\)和\\(t\\)是下标,\\(x\\)是随机变量,只讨论一个时间序列时可简写为\\(\\gamma(s, t)\\)。注意自协方差有性质\\(\\gamma(s, t) = \\gamma(t, s)\\)自协方差衡量同一时间序列中不同时间两点的线性相关性。平滑的序列,其自协方差会很大;不平滑的序列中,当\\(s\\)和\\(t\\)相隔很远时,自协方差会接近0。当自协方差\\(\\gamma(s, t) = 0\\)时,\\(x_s\\)和\\(x_t\\)线性不相关,但仍然有可能有其他的相关性结构。 当\\(s = t\\)时,自协方差退化为方差\\(\\gamma(t, t) = \\mathrm{var}(x_t)\\) 性质:线性组合的协方差 对于两组随机变量\\(\\{X_j\\}\\)和\\(\\{Y_k\\}\\),令\\(U = \\sum_{j=1}^m a_jX_j\\),\\(V=\\sum_{k=1}^r b_kY_k\\),则有 \\[ \\mathrm{cov}(U, V) = \\sum_{j=1}^m\\sum_{k=1}^r a_jb_k\\mathrm{cov}(X_j,Y_k)\\\\ \\mathrm{var}(U) = \\mathrm{cov}(U,U) \\] 该公式在后面会有广泛应用。 例子:MA的自协方差 以MA模型 \\[ v_t = \\frac{1}{3}(w_{t-1}+w_t+w_{t+1}) \\] 为例,其自协方差为 \\[ \\begin{align*} \\gamma(s, t) &= \\mathrm{cov}(v_s, v_t) \\\\ &= \\left\\{ \\begin{array}{ll} \\frac{3}{9}\\sigma_w^2 & s = t, \\\\ \\frac{2}{9}\\sigma_w^2 & |s-t|=1, \\\\ \\frac{1}{9}\\sigma_w^2 & |s-t|=2, \\\\ 0 & |s-t| > 2 \\end{array} \\right. \\end{align*} \\] This particular autocovariance is interesting because it only depends on the time separation or lag and not on the absolute location of the points along the series. We shall see later that this dependence suggests a mathematical model for the concept of weak stationarity. 自相关函数(autocorrelation function, ACF) \\[ \\rho(s, t) = \\frac{\\gamma(s, t)}{\\sqrt{\\gamma(s, s)\\gamma(t, t)}} \\] The ACF measures the linear predictability of the series at time \\(t\\), say \\(x_t\\) , using only the value \\(x_s\\). 强稳定性(strictly stationary) \\[ \\Pr\\{x_{t_1}\\le c_1, ..., x_{t_k}\\le c_k\\} = \\Pr\\{x_{t_1+h}\\le c_1, ..., x_{t_k+h}\\le c_k\\} \\] 对所有的\\(k\\),\\(t_1, t_2, ..., t_k\\),\\(c_1, c_2, ..., c_k\\)和\\(h\\)都成立。 严格稳定的时间序列的任何一段数据点的概率行为和将这一段在时间上平移\\(h\\)个单位后的数据点的概率行为相同 推论1:强稳定的时间序列,当\\(k=1\\)时,上式变成 \\[ \\Pr\\{x_s \\le c\\}=\\Pr\\{x_t \\le c\\} \\] 因而,其均值\\(\\mu_t = \\mu_s\\)对任意\\(s, t\\)都成立,进而\\(\\mu_t\\)是常数 推论2:当\\(k=2\\)时,上式可变为 \\[ \\Pr\\{x_s\\le c_1, x_t\\le c_2\\}=\\Pr\\{x_{s+h}\\le c_1, x_{t+h}\\le c_2\\} \\] 进而当该时序过程存在方差时,其自协方差满足 \\[ \\gamma(s, t) = \\gamma(s+h, t+h) \\] 即自协方差只取决于\\(s\\)到\\(t\\)的距离。 强稳定性的定义太强而在实际数据分析中不实用,只是作为一个理论模型而存在。 弱稳定性(weak stationarity) 满足强稳定性定义中的推论1(均值为常数)和推论2(自协方差只依赖于时间点之差)的性质的时间序列,被称为弱稳定的时间序列。通常称「稳定的」即是指弱稳定性。 在弱稳定时间序列中,均值为常数因此可写为\\(\\mu_t = \\mu\\),自协方差可转写为只与时间差相关的形式 \\[ \\gamma(t+h, t) = \\mathrm{cov}(x_{t+h}, x_t) = \\mathrm{cov}(x_h, x_0) = \\gamma(h, 0) \\] ACF则可以改写为 \\[ \\rho(h) = \\frac{\\gamma(t+h, t)}{\\sqrt{\\gamma(t+h, t+h)\\gamma(t, t)}} = \\frac{\\gamma(h)}{\\gamma(0)} \\] 趋势稳定性(trend stationarity) 例如\\(x_t = \\alpha + \\beta t + y_t\\),其中\\(y_t\\)是弱稳定的时间序列,则\\(\\mu_{xt} = \\alpha + \\beta t + \\mu_y\\),不是与时间无关的常数,但其自协方差\\(\\gamma_x(h) = \\mathrm{cov}(x_{t+h}, x_t) = \\mathrm{E}[(x_{t+h}-\\mu_{x,t+h})(x_t - \\mu_{x,t})] = \\mathrm{E}[(y_{t+h}-\\mu_y)(y_t-\\mu_y)] = \\gamma_y(h)\\),因此该时序模型被认为是在线性趋势下有稳定性的,这种稳定性被称为趋势稳定性。 对于稳定序列,其自协方差是偶函数。即 \\[ \\gamma(h) = \\gamma((t+h)-t) = \\mathrm{cov}(x_{t+h}, x_t) = \\mathrm{cov}(x_t, x_{t+h}) = \\gamma(t - (t+h)) = \\gamma(-h) \\] 显然,这是因为\\(\\mathrm{cov}\\)中的两个参数是可以交换的,而稳定序列中自协方差只和两点的时间距离有关 估计(estimation)一般指通过采样数据计算统计指标。 样本自协方差(sample autocovariance function) \\[ \\hat\\gamma(h) = \\frac{1}{n}\\sum_{t=1}^{n-h}(x_{t+h}-\\bar x)(x_t - \\bar x) \\] 其中\\(\\bar x\\)是样本均值,\\(h\\)是两个样本点的间隔 样本自相关函数(sample autocorrelation function) \\[ \\hat\\rho(h) = \\frac{\\hat\\gamma(h)}{\\hat\\gamma(0)} \\] 性质:样本量足够大时,如果时间序列\\(x_t\\)是白噪声序列,则样本ACF,即\\(\\hat\\rho_x(h), h=1,2,...,H\\),其中\\(H\\)是任意的但固定值,基本服从\\(N(0, \\frac{1}{n})\\)的正态分布。 Based on the previous result, we obtain a rough method of assessing whether peaks in \\(\\hat\\rho(h)\\) are significant by determining whether the observed peak is outside the interval \\(\\pm2/\\sqrt n\\) (or plus/minus two standard errors), for a white noise sequence, approximately \\(95\\%\\) of the sample ACFs should be within these limits. 时序回归和EDA分析技巧 EDA:Exploratory Data Analysis,探索性数据分析。用于初步分析数据集的统计特性,以寻找进一步分析方向或进行可视化。 时序场景下的回归分析 \\[ x_t = \\beta_0 + \\beta_1 z_{t_1} + ... + \\beta_q z_{t_q} + w_t, w_t \\sim wn(0, \\sigma_w^2) \\] 上述式子的实际应用中,\\(w_t\\)实际上是误差项。上式同时包含了一个对误差项属于白噪声分布的前提假设。 - OLS (ordinary least square) - SSE (error sum of squares), SSR (regression sum of squares) - MSE (mean squared error) - \\(F\\)-statistics - \\(R^2\\) (coefficient of determination) - AIC, AICc - BIC (a.k.a SIC) EDA 真实数据集很可能不满足稳定性,而存在一些趋势。如何处理以构造稳定性? 去趋势(detrending) \\[ x_t = \\mu_t + y_t \\] 其中\\(x_t\\)是观测集(即真实数据集),\\(\\mu_t\\)表示趋势,\\(y_t\\)是一个稳定过程。强趋势往往可能使得\\(y_t\\)被隐藏起来,因此EDA的第一步通常是移除观测集中的趋势项,得到残差序列(这个操作被称为detrending) \\[ \\hat y_t = x_t - \\hat\\mu_t \\] 在这里,\\(\\mu_t\\)可以是前述线性回归得到的序列,也可以是其他有趋势性的随机过程建模的序列(比如漂移随机游走 random walk with drift) 差分(differencing) 使用随机游走过程对\\(\\mu_t\\)建模,即 \\[ \\mu_t = \\delta + \\mu_{t-1} + w_t \\] 则可对\\(x_t\\)做差分,得到 \\[ \\begin{align*} x_t - x_{t-1} &= (\\mu_t + y_t) - (\\mu_{t-1} + y_{t-1}) \\\\ &=\\delta + w_t + y_t - y_{t-1} \\end{align*} \\] 令\\(z_t = y_t - y_{t-1}\\),则得到的序列\\(z_t\\)也是稳定序列,因为其均值为常数\\(0\\),且其自协方差只与延迟(lag)相关 \\[ \\begin{align*} \\gamma_z(h) &= \\mathrm{cov}(z_{t+h}, z_t) = \\mathrm{cov}(y_{t+h}-y_{t+h-1}, y_t-y_{t-1}) \\\\ &= 2\\gamma_y(h) - \\gamma_y(h+1) - \\gamma_y(h-1) \\end{align*} \\] 实际上,类似地也可以证明\\(x_t - x_{t-1}\\)也是稳定序列,这就是差分序列。 差分(differencing)相比去趋势(detrending)有一项优势,就是差分中没有需要估计的参数。同样也有一项劣势,即无法对前文设定的稳定序列\\(y_t\\)作出估计。当估计\\(y_t\\)很重要时,detrending可能是更合适的办法;而当目标只是为了调整数据获得稳定序列时,差分会更好用一些。差分在时间序列分析中有很重要的地位。 一阶差分的符号表示为 \\[ abla x_t = x_t - x_{t-1} \\] 一阶差分可以消除线性趋势,类似的,二阶差分可以消除二次趋势(quadratic trend) p.s. 二次的 quadratic,四次的 quartic 后移算子(backshift operator) \\[ Bx_t = x_{t-1} \\] 其中\\(B\\)为后移算子(也有用\\(L\\)来指代滞后算子lag operator的,效果相同)。 \\[ B^k x_t = x_{t-k}\\\\ B^{-1}x_{t-1} = x_t \\] 即\\(B^{-1}\\)为前移算子(forward-shift operator) \\(d\\)阶差分算子 \\[ abla^d = (1-B)^d \\] 使用后移算子可以简便描述\\(d\\)阶差分算子。\\(d\\)阶差分即 \\[ \\begin{align*} abla^d x_t &= (1-B)^d x_t \\\\ &= x_t - \\binom{d}{1}Bx_t + \\binom{d}{2}B^2x_t -... + (-1)^dB^dx_t \\end{align*} \\] 平滑化(smoothing)或滤波 例子 - moving average smoother - kernel smoothing - Lowess - Smoothing splines - smoothing one series as a function of another ARIMA模型 Idea: Classical regression is often insufficient for explaining all of the interesting dynamics of a time series. Instead, the introduction of correlation that may be generated through lagged linear relations leads to proposing the autoregressive (AR) and autoregressive moving average (ARMA) models. Adding nonstationary models to the mix leads to the autoregressive integrated moving average (ARIMA) model. 关键点:parameter estimation, forecasting AR模型 经典回归模型 vs 自回归模型 经典回归模型建立在「静态」场景上,只让因变量被独立变量的当前值所影响。在时间序列场景下,人们需要让因变量受到独立变量的过去值乃至因变量自身的过去值的影响。而如果当前状态可以完全由独立变量的过去值建模的话,就可以进行预测了。 定义:自回归模型(autoregressive model) \\[ x_t = \\phi_1 x_{t-1} + \\phi_2 x_{t-2} + ... + \\phi_p x_{t-p} + w_t \\] 是\\(p\\)阶自回归模型,简写做\\(\\mathrm{AR}(p)\\)。其中\\(w_t \\sim wn(0, \\sigma_w^2)\\)是白噪声项,\\(\\phi_1, \\phi_2, ..., \\phi_p\\)是常数,且\\(\\phi_p e 0\\)。 在AR模型中,\\(x_t\\)是稳定的,且可以认为均值为0。如果其均值\\(\\mu\\)不为0,则将\\(x_t\\)用\\(x_t - \\mu\\)来替代,得到 \\[ x_t - \\mu = \\phi_1(x_{t-1}-\\mu) + ... + \\phi_p(x_{t-p} - \\mu) + w_t \\] 上式等价于 \\[ x_t = \\alpha + \\phi_1 x_{t-1} + \\phi_2 x_{t-2} + ... + \\phi_p x_{t-p} + w_t,\\\\ where\\ \\alpha = \\mu(1-\\phi_1 - ... - \\phi_p) \\] 这就是常见的另外一种AR模型的定义式。 对自回归模型的定义式应用后移算子并稍作变形,得到下式 \\[ (1-\\phi_1 B - \\phi_2 B^2 - ... - \\phi_p B^p)x_t = w_t \\] 实际应用模型时,需要首先解出\\(\\phi_1, \\phi_2, ..., \\phi_p\\),上式对此有重要意义。为此有如下定义: 定义:自回归算子(autoregressive operator) \\[ \\phi(B) = 1-\\phi_1 B - \\phi_2 B^2 - ... - \\phi_p B^p \\] 为自回归算子。则AR模型可重新写成\\(\\phi(B)x_t = w_t\\). AR(1)模型与因果性(causality) 考虑AR(1)模型如下 \\[ x_t = \\phi x_{t-1} + w_t \\] 迭代计算可得 \\[ \\begin{align*} x_t &= \\phi x_{t-1} + w_t \\\\ &= \\phi (\\phi x_{t-2} + w_{t-1}) + w_t \\\\ &= \\phi^2 x_{t-2} + \\phi w_{t-1} + w_t \\\\ &=... \\\\ &= \\phi^k x_{t-k} + \\sum_{i=0}^{k-1}\\phi^i w_{t-i} \\end{align*} \\] - 当\\(|\\phi| < 1\\)时,由于 \\[ \\lim_{k\\to\\infty}\\mathrm{E}\\left(x_t-\\sum_{j=0}^{k-1}\\phi^jw_{t-j}\\right)^2 = \\lim_{k\\to\\infty}\\phi^{2k}\\mathrm{E}(x_{t-k}^2) = 0 \\] 故可以无限迭代上式,得到 \\[ x_t = \\sum_{i=0}^\\infty \\phi^i w_{t-i} \\] 均方收敛。其均值为 \\[ \\mu = \\mathrm{E}(x_t) = \\sum_{i=0}^\\infty \\phi^i\\mathrm{E}(w_{t-i}) = 0 \\] 自协方差为 \\[ \\begin{align*} \\gamma(h) &= \\mathrm{cov}(x_{t+h}, x_t) = \\mathrm{cov}\\left[\\left(\\sum_{i=0}^\\infty \\phi^iw_{t+h-i}\\right), \\left(\\sum_{j=0}^\\infty\\phi^j w_{t-j}\\right)\\right] \\\\ &= \\underbrace{\\sum_{i=0}^{h-1}\\sum_{j=0}^\\infty \\phi^i \\phi^j\\mathrm{cov}(w_{t+h-i}, w_{t-j})}_{=0} + \\underbrace{\\sum_{i=h}^\\infty\\sum_{j=0}^{\\infty,j e i-h}\\phi^i\\phi^j\\mathrm{cov}(w_{t+h-i}, w_{t-j})}_{=0} + \\sum_{k=0}^\\infty\\phi^{k+h}\\phi^k\\mathrm{cov}(w_k, w_k)\\\\ &=\\sigma_w^2 \\sum_{i=0}^\\infty \\phi^{h+i}\\phi^i \\\\ &=\\sigma_w^2\\phi^h\\sum_{i=0}^\\infty\\phi^{2i} = \\frac{\\sigma_w^2\\phi^h}{1-\\phi^2}, \\ h\\ge 0. \\end{align*} \\] 进而可以得到ACF的表达式如下 \\[ \\rho(h) = \\frac{\\gamma(h)}{\\gamma(0)} = \\phi^h, \\ h\\ge 0 \\] 即\\(\\rho(h)\\)是关于\\(h\\)的等比数列,\\(\\rho(h) = \\phi\\rho(h-1), h=1,2,...\\) 一个有趣的现象是,当\\(-1 < \\phi < 0\\)时,得到的时间序列\\(\\{x_t\\}\\)中,相邻两项呈负相关,而隔了一项后的两项(\\(x_t, x_{t-2}\\))呈正相关。因而此时的时序图线会很曲折。 现在考虑\\(|\\phi| \\ge 1\\)的情况(explosive case) 当\\(\\phi = 1\\)时,\\(x_t = x_{t-1}+w_t\\),退化成随机游走模型, 其自协方差为\\(\\gamma_x(s, t) = \\mathrm{cov}(x_s, x_t) = \\min\\{s,t\\}\\sigma_w^2\\)。因而该随机游走模型不稳定。 当\\(|\\phi| > 1\\)时,有\\(|\\phi|^j \\to \\infty\\),因此\\(\\sum_{j=0}^{k-1} \\phi^j w_{t-j}\\)在\\(k\\to\\infty\\)时均方不收敛,因而不能直接用前面的方式来进行后续推导。做变形如下,令\\(x_{t+1}=\\phi x_t+w_{t+1}\\),则有 \\[ \\begin{align*} x_t &= \\phi^{-1}x_{t+1} - \\phi^{-1}w_{t+1} = \\phi^{-1}(\\phi^{-1}x_{t+2}-\\phi^{-1}w_{t+2})-\\phi^{-1}w_{t+1}\\\\ &= ... \\\\ &= \\phi^{-k}x_{t+k} - \\sum_{j=1}^{k-1}\\phi^{-j}w_{t+j} \\end{align*} \\] 即向前迭代\\(k\\)步,由于\\(|\\phi|^{-1} < 1\\),故该前向递推式仍然适用之前的推导,可得 \\[ x_t = -\\sum_{j=1}^\\infty \\phi^{-j}w_{t+j} \\] 同样可以证明该过程是稳定的。 当然,这个式子没有什么用,因为当前状态依赖于未来状态,故此情景下无法用该模型去预测未来的数据。当前状态不依赖于未来状态的时间序列被称为因果过程(causal process)。 根据上式计算自协方差得到: \\[ \\begin{align*} \\gamma_x(h) &= \\mathrm{cov}(x_{t+h}, x_t) = \\mathrm{cov}\\left(-\\sum_{j=1}^\\infty\\phi^{-j}w_{t+h+j}, -\\sum_{k=1}^\\infty\\phi^{-k}w_{t+k} \\right)\\\\ &=\\frac{\\sigma_w^2\\phi^{-2}\\phi^{-h}}{1-\\phi^{-2}} \\end{align*} \\] 下面是有趣的地方了。定义下述因果过程 \\[ y_t = \\phi^{-1}y_{t-1} + v_t \\] 其中\\(v_t\\sim \\mathrm{iid}\\ \\mathrm{N}(0, \\sigma_w^2\\phi^{-2})\\)为白噪声,则\\(\\{y_t\\}\\)与\\(\\{x_t\\}\\)随机等价(stochastically equal)。 如果用自回归算子来表示AR(1)过程,则有 \\[ \\phi(B) x_t = w_t,\\ where\\ \\phi(B) = 1-\\phi B \\] 又从上文得到 \\[ x_t = \\sum_{j=0}^\\infty \\psi_j w_{t-j} = \\psi(B)w_t \\] 代入前式,于是有 \\[ \\phi(B)\\psi(B) w_t = w_t \\] 即 \\[ \\begin{align*} & (1-\\phi B)(1+\\psi_1 B + \\psi_2 B^2 + ... + \\psi_j B^j + ...) = 1 \\\\ \\implies &(1-\\phi B)(1 + (\\psi_1 - \\phi)B + (\\psi_2-\\psi_1 \\phi)B^2 + ... + (\\psi_j-\\psi_{j-1}\\phi)B^j + ...) = 1 \\end{align*} \\] 于是有\\(\\psi_j = \\psi_{j-1}\\phi\\),且\\(\\psi_0=1\\),因此\\(\\psi_j = \\phi^j\\). 从多项式的角度看,可以定义\\(\\phi(B)\\)的逆算子\\(\\phi^{-1}(B)\\),则有上面的推导可知 \\[ \\phi^{-1}(B) = 1 + \\phi B + \\phi^2 B^2 + ... + \\phi^j B^j + ... = \\frac{1}{1-\\phi B} \\] 逆算子刚好符合多项式的性质。 p.s. 浅补一下泛函分析相关概念: 空间:集合+距离 泛函:空间到数域的映射 算子:空间到空间的映射 线性算子:满足线性性的算子,即\\(f(\\alpha x + \\beta y) = \\alpha f(x) + \\beta f(y)\\) 线性算子的多项式还是个线性算子 p.p.s. 随机过程相关概念 均方收敛: 随机等价:两个随机过程的有限分布都相同 MA模型 MA模型假设观测数据由白噪声组成。下面是\\(q\\)阶移动平均(moving average)模型的定义,也可记为\\(\\mathrm{MA}(q)\\): \\[ x_t = w_t + \\theta_1 w_{t-1} + \\theta_2 w_{t-2} + ... + \\theta_q w_{t-q} \\] 其中\\(w_t\\sim wn(0, \\sigma_w^2)\\)是白噪声项(误差项),\\(\\theta_1, \\theta_2, ..., \\theta_q(\\theta_q e 0)\\)是参数。 可以发现AR(1)模型就是一个有无限项的MA模型。 定义移动平均算子(moving average operator)为 \\[ \\theta(B) = 1 + \\theta_1B + \\theta_2 B^2 + ... + \\theta_q B^q \\] 则MA模型可重新写成\\(x_t = \\theta(B)w_t\\). MA(1)模型的非唯一性(non-uniqueness)与可逆性(invertibility) 考虑MA(1)模型\\(x_t = w_t + \\theta w_{t-1}\\),分别计算均值、自协方差和ACF,则有 \\[ \\begin{align*} &\\mathrm{E}(x_t) = 0\\\\ &\\gamma(h) = \\left\\{ \\begin{array}{lr} (1+\\theta^2)\\sigma_w^2 & h=0,\\\\ \\theta \\sigma_w^2 & h=1,\\\\ 0 & h > 1,\\\\ \\end{array} \\right.\\\\ &\\rho(h) = \\left\\{ \\begin{array}{lr} \\frac{\\theta}{1+\\theta^2} & h=1,\\\\ 0 & h > 1,\\\\ \\end{array} \\right. \\end{align*} \\] 注意到\\(\\rho(1)\\)对\\(\\theta\\)和\\(1/\\theta\\)是相同的。例如,取\\(\\theta=5\\),再调整一下\\(\\sigma_w\\),可以得到两个MA(1)序列,它们的自协方差和ACF完全相同: \\[ x_t = w_t + \\frac{1}{5}w_{t-1}, \\ w_t\\sim\\mathrm{iid}\\ N(0,25)\\\\ y_t = v_t + 5v_{t-1}, \\ v_t\\sim\\mathrm{iid}\\ N(0, 1) \\] 因此两个序列从观测值\\(x_t, y_t\\)上来说完全无法区分,即非唯一的。 为了确定一个模型用来分析,参考AR模型的因果性,对MA模型引入了可逆性——即存在一个等价的无穷项AR模型。 将\\(x_t\\)与\\(w_t\\)的地位交换,重写MA模型的等式可得\\(w_t = -\\theta w_{t-1}+x_t\\),当\\(|\\theta| < 1\\)时,可以得到\\(w_t = \\sum_{j=0}^\\infty(-\\theta)^jx_{t-j}\\),即为我们想要的AR表达式。 同样地,MA模型可以用算子表达成如下形式 \\[ x_t = \\theta(B)w_t \\] 令\\(\\pi(B) = \\theta^{-1}(B)\\),当\\(\\theta(B) = 1 + \\theta B\\)时,可以得到 \\[ \\pi(B) = \\sum_{j=0}^\\infty(-\\theta)^jB^j \\] ARMA模型 定义如下时间序列\\(\\{x_t; t=0,\\pm 1, \\pm 2, ...\\}\\)为\\(\\mathrm{ARMA}(p,q)\\)模型,当\\(x_t\\)是稳定时间序列且满足 \\[ x_t = \\phi_1 x_{t-1}+...+\\phi_p x_{t-p} + w_t + \\theta_1w_{t-1} + ... + \\theta_qw_{t-q} \\] 其中\\(\\phi_p e 0, \\theta_q e 0\\)且\\(\\sigma_w^2 > 0\\). \\(p\\)被称为自回归阶数(autoregressive order),\\(q\\)为移动平均阶数(moving average order)。如果\\(x_t\\)的均值\\(\\mu e 0\\),则可以令\\(\\alpha = \\mu(1-\\phi_1 - ... - \\phi_p)\\)并重写上述模型如下 \\[ x_t = \\alpha + \\phi_1 x_{t-1}+...+\\phi_p x_{t-p} + w_t + \\theta_1w_{t-1} + ... + \\theta_qw_{t-q} \\] 从而使得\\(w_t\\sim wn(0, \\sigma_w^2)\\)是白噪声。 用算子来表示则有 \\[ \\phi(B)x_t = \\theta(B)w_t \\] 过参数化(over parameterization) 对上述算子表示的ARMA式子左右同时乘以一个新的多项式\\(\\eta(B)\\),得到 \\[ \\eta(B)\\phi(B)x_t = \\eta(B)\\theta(B)w_t \\] 这样做会得到新的关于\\(B\\)的多项式,新式子仍然满足ARMA模型的定义,然而新式子里出现了多余的参数,使得该模型过度参数化了(或者称参数冗余,parameter redundancy)。例如,考虑白噪声过程\\(x_t = w_t\\),将等号左右同时乘以\\(\\eta(B) = 1-0.5B\\),得到 \\[ x_t = 0.5x_{t-1}-0.5w_{t-1}+w_t \\] 长得像一个ARMA(1,1)模型,从而误导了人们忘记\\(x_t\\)实际上是白噪声。 在实际操作中,对一个数据集用ARMA拟合时,有可能将白噪声拟合成一个ARMA模型并且参数还很显著,从而得出数据集有自相关性的错误结论。 p.s. 过参数化在神经网络中有时能表现得比没有过参数化的网络更好的效果(https://zhuanlan.zhihu.com/p/98649543) ARMA模型的问题与解决方法 从上述讨论总结出可能出现的问题有3个: - 过参数化 - AR模型部分为了稳定性而依赖于未来数据 - MA模型不唯一 为了解决上述问题,需要对ARMA模型的参数增加一些限制。为此首先定义AR多项式\\(\\phi(z)\\)和MA多项式\\(\\theta(z)\\)如下 \\[ \\phi(z) = 1-\\phi_1z - ... - \\phi_p z^p,\\ \\phi_p e 0,\\\\ \\theta(z) = 1 + \\theta_1z + ... + \\theta_q z^q,\\ \\theta_q e 0 \\] 其中\\(z\\)是复数。 针对过参数化的处理 规定\\(ARMA(p, q)\\)模型是最简形式,即\\(\\phi(z)\\)和\\(\\theta(z)\\)没有公因式。这样就解决了过度参数化的问题。 针对未来依赖的处理 为了解决未来依赖的问题,定义ARMA模型的因果性(causality)如下: 一个ARMA(p,q)模型是causal的,如果其时间序列\\(\\{x_t;t=0,\\pm1,\\pm2,...\\}\\)可以被写成等号同一侧的线性过程(one-sided linear process) \\[ x_t = \\sum_{j=0}^\\infty \\psi_j w_{t-j} = \\psi(B)w_t \\] 其中\\(\\psi(B) = \\sum_{j=0}^\\infty \\psi_j B^j\\),且\\(\\sum_{j=0}^\\infty|\\psi_j| < \\infty\\),并设\\(\\psi_0 = 1\\). 定理:ARMA模型存在因果性当且仅当\\(\\phi(z) e 0\\)对所有\\(|z| \\le 1\\)都成立,换言之\\(\\phi(z)\\)的根都在单位圆之外。此时\\(\\psi(z)\\)的系数可以通过下式求出 \\[ \\psi(z) = \\sum_{j=0}^\\infty\\psi_jz^j = \\frac{\\theta(z)}{\\phi(z)},\\ |z|\\le 1. \\] 通过对AR(1)模型的讨论可以稍微理解这个结论。证明思路则是先由\\(|z|\\le 1\\)时\\(\\phi(z) e 0\\)来构造\\(\\psi(z)\\)的存在性,再由待定系数法证明\\(\\phi(z)\\psi(z) = \\theta(z)\\),最后反证法论证\\(\\phi(z)\\)有单位圆内的根会导致\\(\\theta(z)\\)与\\(\\phi(z)\\)有公因式导致矛盾。 p.s. 证明如下设\\(\\phi(z)\\)的根为\\(z_1, ..., z_p\\)。假设所有根都在单位圆之外,并有顺序\\(1<|z_1|\\le|z_2|\\le...\\le|z_p|\\)。令\\(|z_1| = 1+\\epsilon,\\ \\epsilon > 0\\)。则对任意\\(|z|<|z_1|=1+\\epsilon\\),都有\\(\\phi(z) e 0\\),因此\\(\\phi^{-1}(z)=1/\\phi(z)\\)存在,并且可以按幂级数展开 \\[\\frac{1}{\\phi(z)} = \\sum_{j=0}^\\infty a_j z^j,\\ |z|<1+\\epsilon.\\] 任取\\(\\delta\\)满足\\(0<\\delta<\\epsilon\\),设\\(z=1+\\delta\\),则\\(\\phi^{-1}(1+\\delta)<\\infty\\)收敛,即 \\[\\phi^{-1}(1+\\delta) = \\sum_{j=0}^\\infty a_j(1+\\delta)^j < \\infty\\] 于是上式中级数的每一项都有界,即存在\\(c>0\\),\\(|a_j(1+\\delta)^j|<c\\),转写一下有\\(|a_j|<c(1+\\delta)^j\\),进而\\(\\sum_{j=0}^\\infty|a_j|<\\infty\\).于是\\(\\phi^{-1}(B)\\)存在,并且可以应用于ARMA模型的等式\\(\\phi(B)x_t = \\theta(B)w_t\\)两端,得到 \\[x_t = \\phi^{-1}(B)\\phi(B)x_t = \\phi^{-1}(B)\\theta(B)w_t\\] 取\\(\\psi(B) = \\phi^{-1}(B)\\theta(B)\\)就有 \\[x_t = \\psi(B)w_t = \\sum_{j=0}^\\infty\\psi_jw_{t-j}.\\]现在反过来,假设\\(x_t\\)是一个因果过程,即存在如下表示 \\[x_t = \\sum_{j=0}^\\infty\\psi_jw_{t-j},\\ \\sum_{j=0}^\\infty|\\psi_j|<\\infty.\\] 将上式改写成\\(x_t = \\psi(B)w_t\\)并左右同乘以\\(\\phi(B)\\)得到 \\[\\phi(B)x_t = \\phi(B)\\psi(B)w_t\\] 又因为\\(x_t\\)是ARMA模型,于是\\(\\phi(B)x_t = \\theta(B)w_t\\),因此 \\[\\phi(B)\\psi(B)w_t = \\theta(B)w_t.\\] 接下来用待定系数法证明\\(\\phi(z)\\psi(z) = \\theta(z),\\ |z|\\le 1\\)。令 \\[a(z) = \\phi(z)\\psi(z) = \\sum_{j=0}^\\infty a_j z^j\\ |z|\\le 1\\] 则有 \\[\\sum_{j=0}^\\infty a_jw_{t-j} = \\sum_{j=0}^q\\theta_j w_{t-j}\\] 两边同乘以\\(w_{t-h}, h=0,1,2,...\\)并计算其均值。由于\\(\\mathrm{E}(w_iw_j) = 0,\\ i e j\\),且两式相等则其均值相等,对比系数可得 \\[\\begin{array}{ll}a_h = \\theta_h, & h=0,1,...,q,\\\\a_h = 0, & h > q.\\end{array}\\] 从而证明了\\(\\phi(z)\\psi(z) = a(z) = \\theta(z),\\ |z|\\le 1\\).最后要说明当\\(x_t\\)是因果过程时,\\(\\phi(z)\\)的根都在单位圆之外。用反证法,假设存在\\(z_0\\),\\(|z_0|\\le 1\\)使得\\(\\phi(z_0) = 0\\),则前面的讨论知道\\(\\phi(z_0)\\psi(z_0) = \\theta(z_0) = 0\\)仍然成立。于是\\(z_0\\)是\\(\\phi(z)\\)和\\(\\theta(z)\\)的公共根,即\\(\\phi(z)\\)和\\(\\theta(z)\\)有公因式\\((1-z_0^{-1}z)\\),与前面讨论规定的二者无公因式前提矛盾。从而命题得证。 针对MA模型不唯一的处理 对ARMA模型引入可逆性,一个ARMA(p,q)模型被称为可逆的,如果其时间序列\\(\\{x_t; t=0,\\pm1,\\pm2,...\\}\\)可以被写成如下形式: \\[ \\pi(B)x_t = \\sum_{j=0}^\\infty\\pi_jx_{t-j} = w_t \\] 其中\\(\\pi(B) = \\sum_{j=0}^\\infty\\pi_jB^j\\),且\\(\\sum_{j=0}^\\infty|\\pi_j|<\\infty\\)。设\\(\\pi_0 = 1\\). 定理:ARMA模型是可逆的当且仅当\\(\\theta(z)=0\\)的所有解\\(z\\)都满足\\(|z| > 1\\),即\\(\\theta(z)\\)的根都在单位圆之外。此时\\(\\pi(z)\\)的系数可以通过下式求出 \\[ \\pi(z) = \\sum_{j=0}^\\infty\\pi_jz^j = \\frac{\\phi(z)}{\\theta(z)},\\ |z|\\le 1. \\] 通过对MA(1)的讨论同样可以初步理解这个结论,证明类似于因果性的证明。 差分方程(difference equation) The study of the behavior of ARMA processes and their ACFs is greatly enhanced by a basic knowledge of difference equations, simply because they are difference equations. 假设存在一个数列\\(u_0, u_1, u_2, ...\\),满足 \\[ u_n-\\alpha u_{n-1}=0,\\ \\alpha e 0,\\ n=1,2,... \\] 例如AR(1)模型的ACF就满足该性质 \\[ \\rho(h) - \\phi\\rho(h-1)=0,\\ h=1,2,... \\] 上述方程叫一阶齐次(线性)差分方程(homogeneous difference equation of order 1)。容易发现该数列是等比数列,令\\(u_0 = c\\),则有\\(u_n = \\alpha^n c\\). 关键的点在于将上述方程改写成后移算子的形式,得到\\((1-\\alpha B)u_n = 0\\),算子对应的多项式为\\(\\alpha(z) = 1-\\alpha z\\),其根为\\(z_0 = 1/\\alpha\\). 则通项公式可重新写作 \\[ u_n = \\alpha^n c = (z_0^{-1})^n c \\] 其中\\(z_0\\)为特征多项式的根。 对于\\(p\\)阶齐次差分方程 \\[ u_n - \\alpha_1u_{n-1} - ... - \\alpha_pu_{n-p},\\ \\alpha_p e 0,\\ n=p,p+1,... \\] 其特征多项式为\\(\\alpha(z) = 1-\\alpha_1z-...-\\alpha_pz^p\\). 假设\\(\\alpha(z)\\)有\\(r\\)个不同的根\\(z_1, z_2, ..., z_r\\),其中\\(z_j\\)的次数为\\(m_j\\),则有\\(m_1+m_2+...+m_r = p\\). 该齐次差分方程的通解为 \\[ u_n = z_1^{-n}P_1(n) + z_2^{-n}P_2(n) + ... + z_r^{-n}P_r(n) \\] 其中\\(P_j(n)\\)是\\(n\\)的\\(m_j-1\\)次多项式,\\(P_1(n),...,P_r(n)\\)可通过初始条件\\(u_0, ..., u_{p-1}\\)求出来。 证明思路是先求出差分方程基础解,再由基础解线性组合得到通解。设特征多项式\\(\\alpha(z)\\)有\\(k\\)个根,其中\\(z_j\\)是\\(r_j\\)重根,则 \\[\\alpha(B)n^lz_j^{-n} = 0,\\ l=0,1,...,r_j-1\\] 从而基础解为 \\[n^lz_j^{-n},\\ j=1,2,...,k,\\ l=0,1,...,r_j-1\\] 可由数学归纳法证明。进而可以得到通解为上述基础解的线性组合,组合的系数则由初始状态唯一确定。详细的证明略。 p.s. 若差分方程的特征多项式所有根都在单位圆外,则该方程任意解会随\\(n\\to \\infty\\)收敛到0;若特征多项式存在单位根,则该方程有一个周期解;若特征多项式在单位圆内有根,则该方程有一个发散解(爆炸解)。 应用例——AR模型的ACF:比如在AR(2)过程中,\\(x_t = \\phi_1x_{t-1}+\\phi_2x_{t-2}+w_t\\),则两边乘以\\(x_{t-h},\\ h>0\\),并取期望,得到方程 \\[ \\mathrm{E}(x_tx_{t-h})=\\phi_1\\mathrm{E}(x_{t-1}x_{t-h})+\\phi_2\\mathrm{E}(x_{t-2}x_{t-h})+\\underbrace{\\mathrm{E}(w_tx_{t-h})}_{=0} \\] 即 \\[ \\gamma(h) = \\phi_1\\gamma(h-1)+\\phi_2\\gamma(h-2),\\ h=1,2,... \\] 等号两边再同时除以\\(\\gamma(0)\\),就有 \\[ \\rho(h)-\\phi_1\\rho(h-1)-\\phi_2\\rho(h-2)=0,\\ h=1,2,... \\] 初始状态是\\(\\rho(0) = 1,\\rho(1)=\\rho(-1)=\\phi_1/(1-\\phi_2)\\). 于是就可以利用差分方程比较方便地求出ACF了。对于一般的ARMA(p,q)模型,ACF也满足差分方程 \\[ \\rho(h) - \\phi_1\\rho(h-1)-\\cdots-\\phi_p\\rho(h-p) = 0,\\ h\\ge \\max(p,q+1) \\] 此外,AR多项式的复数根还会为时间序列带来周期性。 应用例——ARMA模型的\\(\\psi\\)权重:一个有因果性的ARMA模型,可以转写成 \\[ x_t = \\sum_{j=0}^\\infty\\psi_j w_{t-j} \\] 其中,\\(\\psi_j\\)满足\\(\\phi(z)\\psi(z) = \\theta(z)\\) 展开得到 \\[ \\begin{align*} \\psi_0 &= 1\\\\ \\psi_1-\\phi_0\\psi_0 &= \\theta_1\\\\ \\psi_2 - \\phi_1\\psi_1 - \\phi_2\\psi_0 &= \\theta_2\\\\ \\psi_3 - \\phi_1\\psi_2 - \\phi_2\\psi_1 - \\phi_3\\psi_0 &= \\theta_3\\\\ &\\vdots \\end{align*} \\] 前\\(\\max(p,q+1)\\)条等式是初始条件,后面的就是一个齐次差分方程 \\[ \\psi_j - \\sum_{k=1}^p\\phi_k\\psi_{j-k} = 0,\\ j\\ge\\max(p,q+1) \\] 进而可以通过解差分方程来计算\\(\\psi\\)系数。 偏自相关函数(partial autocorrelation, PACF) 定义 为什么有了ACF后,还要引入一个PACF?这里有个例子。 ARMA(1,1)模型的自相关函数为 \\[ \\rho(h) = \\frac{(1+\\theta\\phi)(\\phi+\\theta)}{1+2\\theta\\phi+\\theta^2}\\phi^{h-1},\\ h\\ge 1 \\] 其满足性质\\(\\rho(h) = \\phi\\rho(h-1)\\). 而AR(1)模型的ACF恰好也满足这个性质,这意味着在根据观测数据进行模型拟合时,仅通过估计ACF值无法区分AR(1)模型和ARMA(1,1)模型。 而对于MA(q)模型,其ACF为 \\[ \\rho(h) = \\left\\{ \\begin{align*} &\\frac{\\sum_{j=0}^{q-h}\\theta_j\\theta_{j+h}}{1+\\theta_1^2+\\cdots+\\theta_q^2} & 1\\le h\\le q\\\\ &0 & h > q\\\\ \\end{align*} \\right. \\] 特性是ACF在间隔大于\\(q\\)的时候为0,并且在间隔等于\\(q\\)的时候不为0. 因此ACF为MA模型的依赖性提供了足够信息。因此在处理AR模型和ARMA模型时,人们想到设计一种函数能有像MA模型下的ACF一样的特性,这就是偏自相关函数(partial autocorrelation function, PACF)。 首先假设有随机变量\\(X,Y,Z\\),则\\(X,Y\\)关于\\(Z\\)的偏相关系数\\(\\rho_{XY|Z} = \\mathrm{corr}\\{X-\\hat{X}, Y-\\hat Y\\}\\),其中\\(\\hat X\\)是将\\(X\\)在\\(Z\\)上做回归得到的预测值。即\\(X-\\hat X\\)是回归的残差。 在时间序列分析中,上述motivation变成了在衡量两个时间点取值的自相关性时,要去掉两者之间所有取值的影响。 定义:一个稳定过程\\(x_t\\)的偏自相关函数(PACF),记为\\(\\phi_{hh},\\ h=1,2,...\\),其定义为 \\[ \\phi_{11} = \\mathrm{corr}(x_{t+1}, x_t) = \\rho(1)\\\\ \\phi_{hh} = \\mathrm{corr}(x_{t+h}-\\hat{x}_{t+h}, x_t - \\hat{x}_t),\\ h\\ge 2 \\] 其中\\(\\hat x_{t+h}\\)表示\\(x_{t+h}\\)在\\(\\{x_{t+h-1},x_{t+h-2},...,x_{t+1}\\}\\)上的回归值(这里的回归指的是它们的多元线性回归,即使得均方误差最小的线性组合),而\\(\\hat x_t\\)则表示\\(x_t\\)在\\(\\{x_{t+h-1},x_{t+h-2},...,x_{t+1}\\}\\)上的回归(注意还是夹在\\(x_t\\)和\\(x_{t+h}\\)之间的值)。 令\\(\\hat x_{t+h}\\)写成如下表达式 \\[ \\hat x_{t+h} = \\beta_1x_{t+h-1} + \\beta_2 x_{t+h-2} + \\cdots + \\beta_{h-1}x_{t+1} = \\sum_{j=1}^{h-1}\\beta_j x_{t+h-j} \\] 则由\\(x_t\\)序列的稳定性(这里主要用到\\(\\gamma(-h) = \\gamma(h)\\))可以推出 \\[ \\hat x_t = \\beta_1 x_{t+1} + \\beta_2 x_{t+2} + \\cdots + \\beta_{h-1}x_{t+h-1} = \\sum_{j=1}^{h-1}\\beta_j x_{t+j} \\] p.s. 以AR(1)的PACF为例计算\\(\\phi_{22}\\),考虑\\(x_{t+2}\\)和\\(x_t\\)分别在\\(x_{t+1}\\)上的线性回归,求各自的回归系数。 假设\\(x_{t+2}=\\beta x_{t+1}\\),则需要最小化均方误差 \\[\\begin{align*}\\mathrm{E}(x_{t+2}-\\beta x_{t+1})^2 &=\\mathrm{E}(x_{t+2})^2 - 2\\beta\\mathrm{E}(x_{t+2}x_{t+1}) + \\beta^2\\mathrm{E}(x_{t+1})^2\\\\&=\\gamma(0)-2\\beta\\gamma(1)+\\beta^2\\gamma(0)\\end{align*}\\] 假设\\(x_t = \\beta^* x_{t+1}\\),需要最小化均方误差,同样有 \\[\\begin{align*}\\mathrm{E}(x_t - \\beta^* x_{t+1})^2 &=\\mathrm{E}(x_t)^2 - 2\\beta^*\\mathrm{E}(x_tx_{t+1}) + {\\beta^*}^2\\mathrm{E}(x_{t+1})^2\\\\&=\\gamma(0) - 2\\beta^*\\gamma(-1) + {\\beta^*}^2\\gamma(0)\\\\&=\\gamma(0) - 2\\beta^*\\gamma(1) + {\\beta^*}^2\\gamma(0)\\end{align*}\\] 因此可以发现两个均方误差是相同的方程,从而回归系数解出来也是相同的。 特性 TL;DR 拖尾(tails off) 截尾(cuts off) 模型预测 ARIMA","tags":["Time Series","Machine Learning"]},{"title":"Hello World","path":"/2024/02/11/hello-world/","content":"Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick Start Create a new post 1$ hexo new "My New Post" More info: Writing Run server 1$ hexo server More info: Server Generate static files 1$ hexo generate More info: Generating Deploy to remote sites 1$ hexo deploy More info: Deployment"},{"title":"Go语言入门","path":"/2020/08/02/golang-fundamental/","content":"How to build 1. 安装go语言: 2. 配置与编译 2.1 配置 2.2 编译 Types 1. 主要类型 2. 类型声明 3. 接口 Array & Slice & Map 1. 数组(Array) 2. 切片(Slice) 3. 映射(Map) // Coming soon - Modules - Control - Advanced topics 这里是一些纲要性的内容,有些有趣的话题另外有博客专门讨论。 内容如果有错,欢迎提issue指正。 (正在不断更新中......) How to build 1. 安装go语言: 去官网下载go语言,然后按照上面的步骤安装即可 2. 配置与编译 2.1 配置 Go语言的几个重要的环境变量:GOPATH、GOROOT - GOPATH:go语言拉取依赖的下载路径,GOPATH下应该有3个文件夹:bin, pkg, src - GOROOT:一般为go语言的安装路径 2.2 编译 如果是要运行单个go代码,可以运行go run <filename.go> 如果要编译一个用go写的项目,在项目的根目录下运行go build即可 Types 1. 主要类型 Go语言的主要类型有 - int - int8 - int16 - int32 - int64 - float - float16 - float32 - float64 - complex - byte - string 此外每种type都有对应的指针类型 Go语言支持结构体(struct)、接口(interface)与自定义类型 自定义类型可以与原生类型一样,但是允许定义方法(method,一种需要类型实例调用的函数),而原生类型无法自定义方法 12type int MyTypefunc (m MyType) myfunc() 零值(Zero value) Go语言为每个类型都规定了一个零值,在提到类型的时候,就不得不提每个类型的零值是什么。int类的零值就是\\(0\\),float类的零值为\\(0.0\\),string类的零值为\"\",此外所有的指针、以及结构体等复杂一点的类型的零值为nil。 强制类型转换 使用类型名加括号,就像调用函数一样。例: 12a := 12 // a is an int or int32b := int64(a) // b is an int64 2. 类型声明 Go语言中的变量有两种声明方式 12var a stringb := "this is a string" 上述变量a和b都是string,其中:=称为隐式声明,仅当这个变量名在这个作用域下第一次出现时需要,其变量类型是由所赋的值所决定的。当然如果是int的话,会默认为int(即int32),而如果要使用int64则需要强转。 Go的类型声明遵循var var_name type的顺序,可以看做是后缀表达式(而C风格的类型声明相当于中缀表达式)。 后缀表达式的好处是在函数与指针嵌套定义的时候非常清晰。例如 1func Myfunc(func(int, string) []*byte, func(func(int), string) func()) *func(int) error 3. 接口 Go语言中的接口(interface)也是一种类型,它定义了一系列方法,实现了这些方法的任何类型都等价于实现了这个接口,而不用显式声明。例如 1234567// fmt/pring.gotype State interface { Write(b []byte) (n int, err error) Width() (wid int, ok bool) Precision() (prec int, ok bool) Flag(c int) bool} 但是如果想要让一个类型实现一个接口,就必须实现这个接口里的所有方法 Array & Slice & Map 1. 数组(Array) Go语言中的数组是固定长度的,在声明的时候就要确定好。例如 1var p = [5]int{1,2,3,4,5} 数组在Go语言中直接使用的场景不多,更多的是作为切片(slice)的隐含实现。切片在Go语言编程中十分普遍。 2. 切片(Slice) (参考:Go Slices: usage and internals) Slice可以通过对array进行切片操作得到,也可以对直接声明与初始化。 每个slice都是对一个underlying array的引用。因此修改了underlying array就会修改所有引用其中元素的slice。 切片是可变长度的,并且支持append, slice操作,十分灵活。 - 初始化: 有两种初始化方式,第一种是直接指定值,第二种是使用make函数来初始化。注意在使用make初始化时,元素会被初始化成对应类型的零值。 12var p = []int{1,2,3,4,5} // p = {1,2,3,4,5}q := make([]int, 5) // q = {0,0,0,0,0} - 切片操作: slice有长度(length)和容量(capacity)两个属性,分别可以调用len(p)和cap(p)来查看。 Go语言中array可以进行切片,切片得到的是一个slice;slice也可以继续切片,仍然得到slice类型的实例。例如 12var p = []int{1,2,3,4,5}q := p[2:4] // q = {3,4},不包含下标为4的元素 注意切片是对underlying array的引用,切片的切片也是对同一个underlying array的引用,因此改变切片时会改变underlying array,可能改变其他切片。例如 123456789p := [7]int{1,2,3,4,5,6,7}q := p[2:7] // now q = {3,4,5,6,7}r := p[1:5] // now r = {2,3,4,5}s := q[1:4] // now s = {4,5,6}r[2] = 10// now q = {3,10,5,6,7}// now r = {2,3,10,5}// now s = {10,5,6}// now p = {1,2,3,10,5,6,7} - append操作: 类似于python的list.append和C++ STL里的vector<T>::push_back,追加元素在指定的slice后面 Go语言中的追加元素很有意思,如果有两个不同的slice是从同一个slice那里追加不同的元素得到的,则append会为这两个slice各分配一个新的underlying array,并且与上一个slice也不同 12345678910p := [3]int{1,2,3}s := append(p[:], 4,5,6) // append方法可以追加一列元素,按照参数顺序追加,append只能对切片操作// s = {1,2,3,4,5,6}s = append(s, 7) // s = {1,2,3,4,5,6,7}r := append(s, 7) // r = {1,2,3,4,5,6,7,7}r[1] = 10 // now r = {1,10,3,4,6,7,7}, // s = {1,10,3,4,5,6,7}, // p = {1,2,3},// 这里r与s是同一个underlying array的引用 123456789p := [3]int{1,2,3}s := append(p[:], 4,5,6)r := append(s, 7)a := append(s, 8)r[1] = 10// now r = {1,10,3,4,5,6,7}, // a = {1,2,3,4,5,6,8}, // s = {1,2,3,4,5,6},// 可以看到只改变了r - 比较:slice只能喝nil进行比较,即判断一个slice是否为空 - (问题:如何查看和比较两个slice的underlying array?) 3. 映射(Map) Map,即存储键值对的结构。Go语言中的map也是采用散列来存储和索引键,类似于python中的dict。例: 1m := map[string]int 其中方括号内为键的类型,之后紧跟的是值的类型。Map的零值是nil。 Map支持插入(insert)、获取(retrieve)和删除(delete)等操作。 - 插入: 1m[key] = elem - 获取: 1elem = m[key] - 删除: 1delete(m, key) - 此外map还可以测试key是否存在,只要在查找时用两个变量来接收返回值即可,后一个是bool类型 1elem, ok := m[key] 当ok = true时,说明key存在;否则key不在m中,此时elem为map对应值类型的零值。 Functions 函数也可以被当作value传给其他操作 Go语言支持内嵌函数(closure),例如: 1234567func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum }} 实现了一个加法器(相当于python里的一个实现了__call__方法的加法类)","tags":["Coding"],"categories":["Golang"]}]