刺猬教你量化投资(四):Python科学计算

刺猬教你量化投资(四):Python科学计算_第1张图片

科学计算常用库

在做金融数据分析时,我们通常需要导入以下几个模块:

用途
Numpy 提供了许多高级的数值编程工具,专为进行严格的数字处理而产生。
如:矩阵数据类型、矢量处理,以及精密的运算库。
Scipy 高级科学计算工具包,包括统计、优化、整合、线性代数模块、傅里叶变换、信号和图像处理、常微分方程求解器等。
Pandas 金融数据分析工具包,提供了大量能使我们快速便捷地处理数据的函数和方法
malplotlib 2D绘图库,可以生成绘图,直方图,功率谱,条形图,错误图,散点图等。

关于Numpy

  1. Numpy的数组及处理

Python自带的元素类型多种多样,且能够同时放在一个列表里。但我们做金融数据分析的时候,往往仅在列表中存放数字对象。为了提高计算的效率并节省内存,可使用Python自带的array模块来进行存放。但若涉及到多维数组,Python的array模块就无能为力了,这时我们就需要用到Numpy中的ndarray对象。

ndarray全称为N-dimensional array object,可理解为用于储存单一数据类型的多维数组,比如说:

[3,3,3]
[4,4,4]
#这是一个具有两个纬度的数组

创建一个ndarray对象试试:

In [1]:import numpy as np
a=np.array([1,2,3,4,5,6,7,8])
a
Out[1]:array([1, 2, 3, 4, 5, 6, 7, 8])

当ndarray对象建立后,我们就能很方便地让Numpy进行多种数学运算,例如求最大值、求均值、求方差、求和等:

In [2]:import numpy as np
a=np.array([1,2,3,4,5,6,7,8])
print a.max()
print a.mean()
print a.var()
print a.sum()
a.dtype #查询数据类型,无需对对象进行处理的时候不用加()

8
4.5
5.25
36
Out[2]:dtype('int32') #数据类型为整数

再创建一个多维数组试试:

In [3]:import numpy as np
a=np.array([[1,2,3,4,5,6,7,8],[8,7,6,5,4,3,2,1]])
print a
a.shape #查询行列数

[[1 2 3 4 5 6 7 8]
 [8 7 6 5 4 3 2 1]]
Out[3]:(2L, 8L) #该多维数组有两行两列

除了直接创建数组,我们还能用函数的方法来实现,比如说:

函数 用途说明
arange() 格式为arange(start, stop,step)。range()只能用整数作为步长,而Numpy下的arange()则可以用浮点数,甚至负数作为步长
linspace() 格式为linspace(start,stop,step,endpoint=True/False)。意思是创建一个从start到stop的等差数列数组,一共有step个数。endpoint=True表示包含stop,False表示不包含stop
logspace() 格式为logspace(start,stop,step)。意思是创建一个从10的start次方到10的stop次方的等比数列数组,一共有step个数。
  1. 用Numpy创建矩阵

矩阵即多维列表,通过Numpy的函数one()、zeros()、eye(),我们能很方便地创建全一矩阵、全零矩阵以及单位矩阵。比如说:

In [3]:import numpy as np
a=np.ones((8,2))
print a
a.shape
[[ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]]
Out[3]:(8L, 2L)
In [4]:import numpy as np
a=np.zeros((8,2))
print a
a.shape
[[ 0.  0.]
 [ 0.  0.]
 [ 0.  0.]
 [ 0.  0.]
 [ 0.  0.]
 [ 0.  0.]
 [ 0.  0.]
 [ 0.  0.]]
Out[4]:(8L, 2L)
In [5]:import numpy as np
a=np.eye(5)
print a
a.shape
[[ 1.  0.  0.  0.  0.]
 [ 0.  1.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.]
 [ 0.  0.  0.  1.  0.]
 [ 0.  0.  0.  0.  1.]]
Out[5]:(5L, 5L)
  1. 用Ufunc处理数组

在处理多维数组时,我们会用到ufunc(universal function object),即用于处理数组的函数。比如两个数组相加,可用add():

In [6]:
import numpy as np
a=np.arange(5,9)
b=np.arange(1,5)
print a
print b
c=np.add(a,b)
c

[5 6 7 8]
[1 2 3 4]
Out[6]:array([ 6,  8, 10, 12])

相减可用subtract()

In [7]:import numpy as np
a=np.arange(5,9)
b=np.arange(1,5)
print a
print b
c=np.subtract(a,b)
c

[5 6 7 8]
[1 2 3 4]
Out[7]:array([4, 4, 4, 4])

求幂也很方便,可用power(底数数列,指数数列):

In [8]:import numpy as np
a=np.arange(5,9)
b=np.arange(1,5)
print a
print b
c=np.power(a,b)
c
[5 6 7 8]
[1 2 3 4]
Out[8]:array([   5,   36,  343, 4096])

更多的ufunc函数如下表所示:

函数名 运算含义
multiply(a,b) a*b
divide(a,b) a/b,整数相除返回整数
true_divide(a,b) a/b,返回精确结果
floor_divide(a,b) a//b,对返回值取整
negative(a) -a
remainder(a,b)或mod(a,b) a%b,求a/b的余数
  1. 矩阵运算

使用矩阵的格式进行运算,能够简化某些复杂的方程计算。比如用最小二乘法求回归方程。

已知x和y的一系列数据,那么就可以建立两个ndarray数组,如果要进行多元回归,则x可以用matrix矩阵,将x1、x2等数据放入多维的数组。

假设一元回归的方差为y=b0+b1x+e,转换成矩阵的形式:
[y……]=[1,x1……]*(b0,b1)+[e……]

矩阵相乘的方式是逐个相乘,比如(1+x1)(b0+b1)=b0+b1*x1。

假设[1,x1]=X、(b0,b1)=b,则有y=Xb+e。要求两组数据的一元回归,就要用最小二乘法求残差平方和的最小值。

这里有e=y-Xb,min e'e就等于(y-Xb)'(y-Xb),即求min(y'y-2b'X'y+b'X'Xb)时的b。加'表示转置的意思。

对该式子求一阶导,得出极值b=(X'y)[(X'X)^-1]

为了得到(1,X),我们还需要一个全一矩阵:

In [9]:import numpy as np
x=np.arange(5,9)
y=np.arange(1,5)
print x
print y
X=np.vstack([np.ones(len(x)),x]).T   #.T表示转置
#vstack表示垂直堆放,hstack表示水平堆放,拼接在一起
X

[5 6 7 8]
[1 2 3 4]
Out[9]:
array([[ 1.,  5.],
       [ 1.,  6.],
       [ 1.,  7.],
       [ 1.,  8.]])

接着求b0和b1:

In [10]:import numpy as np
x=np.arange(5,9)
y=np.arange(1,5)
X=np.vstack([np.ones(len(x)),x]).T   
Y=y.T
XY=np.dot(X.T,Y) #点乘用dot()函数
XX=np.dot(X.T,X) 
XX_inv=np.linalg.inv(XX) #linale.inv()函数意味着线性代数取逆
b=np.dot(XX_inv,XY)
b
​
Out[10]:
array([-4.,  1.])

除了用Numpy求回归系数,我们还能用更简便的Statsmodel模块来达到同样的目的:

In [10]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
df=pd.read_excel('learning notebook.xlsx') #导入数据
print '*'*30
print df
y=df['price']
x=df['salary'] #多元回归可引用多列,如df['x1','x2']
print '*'*30
print y
print '*'*30
print x
print '*'*30 
x=sm.add_constant(x) #为x加上一个常数项作为截距
print x
print '*'*30
models=sm.OLS(y,x) #对x,y进行最小二乘法运算
a=models.fit() #使用models的方法进行模拟拟合
a.params #查看参数结果
print '*'*30
a.summary() #查看拟合的结果

******************************
   salary  price
0    0.40      3
1    0.45      5
2    0.48      7
3    0.51      9
4    0.53     14
5    0.59     18
******************************
0     3
1     5
2     7
3     9
4    14
5    18
Name: price, dtype: int64
******************************
0    0.40
1    0.45
2    0.48
3    0.51
4    0.53
5    0.59
Name: salary, dtype: float64
******************************
   const  salary
0      1    0.40
1      1    0.45
2      1    0.48
3      1    0.51
4      1    0.53
5      1    0.59
******************************
Out[10]:
OLS Regression Results
Dep. Variable:  price   
R-squared:  0.938
Model:  OLS 
Adj. R-squared: 0.922
Method: Least Squares   
F-statistic:    60.30
Date:   Thu, 28 Sep 2017    
Prob (F-statistic): 0.00148
Time:   11:34:59    
Log-Likelihood: -10.057
No. Observations:   6   
AIC:    24.11
Df Residuals:   4   
BIC:    23.70
Df Model:   1       
Covariance Type:    nonrobust       
          coef      std err     t    P>|t|      [95.0% Conf. Int.]
const   -31.8282    5.340   -5.960  0.004   -46.655 -17.002
salary  83.4356     10.745  7.765   0.001   53.603  113.268
Omnibus:    nan 
Durbin-Watson:  1.727
Prob(Omnibus):  nan 
Jarque-Bera (JB):   0.684
Skew:   0.010   
Prob(JB):   0.710
Kurtosis:   1.346   
Cond. No.   20.7

最后,可用matplotlib将数据成图:

In[11]
%matplotlib inline
plt.scatter(df['salary'],df['price'])

Out[10]


刺猬教你量化投资(四):Python科学计算_第2张图片
房价与人均收入的关系(模拟数据,单位:千)

结语

至此,我们对Python的基本编程内容已不再陌生,接下来我们进阶学习强大的金融数据分析工具——Pandas,敬请期待。



刺猬偷腥
2017年9月28日


to be continued.

你可能感兴趣的:(刺猬教你量化投资(四):Python科学计算)