- Python量化投资:技术、模型与策略
- 赵志强 刘志伟
- 2698字
- 2021-04-04 11:20:21
5.3 回归分析
5.3.1 最小二乘法
回归分析是通过建立模型来研究变量之间的相互关系并进行模型预测的一种有效工具。
我们来看一个案例:以平安银行的月度收益率为例来了解某只股票的风险回报率是否与大盘指数基金风险回报率有关,且相关度有多高?
从万德下载平安银行以及深证成指历史股价时间序列。示例代码如下:
import pandas as pd #读取平安银行数据 y = pd.read_excel('000001close.xlsx')
运行结果如图5-12所示。
#读取深证成指数据 x = pd.read_excel("399001close.xlsx")
运行结果如图5-13所示。
图 5-12
图 5-13
我们先对数据进行清理(过程在此略去),得到如图5-14所示的DataFrame。
图 5-14
得到平安银行的月度收益率以及深证成指指数基金月度收益率后,假定无风险收益率为0%。
一个值得思考的问题是,如果大盘涨1个点,那么平安银行股票统计概率上会上涨多少点?这就是回归分析要解决的基本问题。为了解答这个问题,我们可以假定如下模型:
平方银行月度收益率=α+β*深证成指月度收益率+ε
即平安银行月度收益率与深证成指月度收益率呈线性相关,并且受随机扰动项影响。我们的目标就是利用手上的数据估计出上述的各项参数。利用上述模型,我们在现有的数据集上的假设就变成了:
参数取值决定了扰动项的大小,为了保证参数能够最优地反映相关关系,并且使得模型具有解释性,可考虑使用如下方式优化问题:
得出的解其实就是我们预估的上述模型参数。
上述模型的解决方法在统计中称为最小二乘法(Ordinary Least Square,简称OLS)。顾名思义,就是普通的、最少的扰动项平方和。Python提供了statsmodels包可用于解决上述优化问题。示例代码如下:
import statsmodels.api as sm X =sm.add_constant(x) results = sm.OLS(y,X).fit() results.summary()
在console里会出现如图5-15所示的结果。
图 5-15
这张表里有很多数据,涉及这个模型不同的统计量,目前只需要关注coef对应的项目即可,它代表了模型的参数。
现在我们可以对模型进行解读了,这个模型代表了深证综指上涨1%,平均来看,平安银行将上涨0.9527%。
5.3.2 假设检验
在5.3.1节中,我们对平安银行月度收益率进行了回归分析,得出了如下结论:深证综指上涨1%,平均来看,平安银行将上涨0.9527%。这又带来了新的问题。这个结论可靠度有多高?这个系数会不会浮动?从历史数据来看,这个浮动区间应该是多少?
我们还可以思考另外一个有趣的问题,假如某个号称股票大师的人宣称,平安银行是牛股中的牛股,在牛市的时候会远超大盘,大盘月度收益率为1%的时候,平安银行月度收益率将超过3%。我们可以考察的是:这个股票大师的说法,大概率是对的还是错的?
先来看一个有趣的问题,我们实质上需要做的工作是建立模型以及对应的假设:
平安银行月度收益率=α+β*深证成指月度收益率+ε
H0:β>3
能否利用数据来拒绝这一假设。这一类问题,在统计学上统称为假设检验(Hypothesis Testing),为了解决这一问题,需要使用的手段被称为统计推断(Statistical Inference)。
针对上述场景,我们可以提出如下这样一个通用的解决方案框架:
定义有限个随机变量{X},属于随机变量空间,对于任意随机变量,其与其他随机变量存在某种对应关系族{f},关系族由参数空间{p}定义。假定我们知道对应关系族{f},并且拥有根据随机变量生成的样本{d},我们需要做的就是通过某种变换g(d|p)(即构建统计量),使得该变换的结果满足某种已知的分布(如Asymptotic Normal Distribution)。在给定的可能性阈值情况下,计算g(d|p)是否属于给定的阈值范围。
其中,拒绝假设的阈值范围称为临界域(critical region),构建的统计量称为检验统计量(test statistics)。即假如构建的统计量属于临界域的范围之外,则我们认为该假设有很大的可能是不成立的。
针对股票大师假设的问题,我们实现上述解决方案。数学上可以证明,以下统计量服从t(n-1)分布:
其中,分母为参数估计量的样本估计值,n为数据量,k为模型参数数量,β为我们的假设值。
证明思路:分子服从的分布为正态分布,分母为服从自由度为n-k卡方分布的随机变量的1/2次幂。
其中,n为样本的个数。
如何设定阈值?这是一个充满艺术性的问题。先来看如下几个极端的假设。
1)我拒绝所有可能。即对于的任何值,我们都不相信,于是将临界域设为全集。很明显,这样我们会犯一个错误,即有可能其中一个值是正确的,当我们拒绝这个正确的假设时,我们犯的错误,称为第一类错误(Type I Error)。
2)我不拒绝所有可能,将临界域设为空集。这也会犯另外一个错误,即使假设是错误的,我们也会接受这个假设,这类错误称为第二类错误(Type II Error)。
大多数情况下,为了尽力避免一类问题而采取的努力,会导致我们无法减少另一类错误发生的可能性。我们必须选择尽力避免这两种错误。即,如果我们的假设是正确的,那么我们的推断过程会以最小的概率拒绝这个假设;而当我们的假设是错误的时候,那么推断过程又会以最大的概率拒绝这个假设。拒绝假设的概率函数称为功效函数(Power Function)。而由于我们无法同时满足最小化两类错误,因此必须要寻找到一个平衡点,以控制更严重的错误,并适当牺牲犯不严重错误的概率。哪一类错误更为严重是根据实际问题来确定的。比如,我们在判断一个青少年是否犯有偷窃罪时,首先要假定青少年没有犯罪,将这个假设定为我们的目标假设,考虑到可能会影响青少年身心发展问题,我们应尽可能地避免犯第一类错误。而相对立的,当我们在判断多起恐怖袭击案件犯罪团伙被抓获的犯罪嫌疑人时,如果假定的嫌疑人并没有犯罪,则我们需要尽可能地避免第二类错误。因为不能够拒绝这个假设意味着我们认定嫌疑人未犯罪,而放走一个可能的恐怖案件嫌疑犯将会导致社会稳定性大大降低,这个成本是我们不能够接受的。有意思的是,我们可以通过改变假设本身来使得第一类错误和第二类错误的描述是截然相反的,比如,我们可以将上面那个青少年偷窃案例的假设改为青少年实际犯罪了,那么这样一来,第一类错误和第二类错误就交换了。
基于上述讨论,常用的设计检测框架的模式是,控制第一类错误的发生概率,并且调节假设,使得发生第一类错误更加严重,这个严重度会得到统计学者的控制。
关于统计推断框架中功效函数与控制错误发生的平衡更深层次的讨论,可以参考Neyman-Pearson Lemma,感兴趣的读者可以自行深入研究。
回到月度收益率问题,我们假定发生第一类错误的概率不能够超过1%。即,针对统计量而言,我们需要找到一个c,使得,即如果假设大盘涨1个点,平安银行涨大于3个点是正确的假设,则观测值构建的统计量将假设拒绝的概率最大为0.01。前面提到,我们可以找到这个值,代码如下:
From scipy import stats stats.t(len(y)-2).ppf(0.01) Out[123]: -2.3374308785509292
于是基于这个值,我们可以构建临界域:假如,我们拒绝这个假设。
下面从常理来推断这个假设检验流程的合理性。假如说平安银行涨幅真的大于3个点,那么我们构建的统计量计算出来小于临界值的概率应该会非常小,我们假定这个概率为0.01。因此我们的拒绝流程应设为当观测值统计量小于某个值的时候,则拒绝假设。
读者可以用5.3.1节提到的数据计算一下,这位股票大师的推断是多么地不靠谱。代码如下:
(results.params['深证综指月度收益率']-3)/results.bse['深证综指月度收益率'] Out[121]: -50.29784830620411