SciPy和StatsModels的使用

在这一部分,我们介绍SciPy和StatsModels这两个库的使用,以及Python中的时间类型和Pandas中的时间序列。

1. SciPy

SciPy模块依赖于NumPy模块,能够提供方便快捷的N维数组操作。SciPy数组可以和NumPy的ndarray,Pandas的Series、DataFrame一起使用,并且提供包括积分、优化等许多高效的数值运算。SciPy模块不仅易于使用,而且功能强大。

在下表中,我们列出了SciPy模块主要的子模块:

子模块名称 功能
cluster 聚类算法
constants 物理数学常数
fftpack 快速傅里叶变换
integrate 积分和常微分方程求解
interpolate 插值处理
io 输入输出
linalg 线性代数
ndimage 图像处理模块
odr 正交距离回归
optimize 优化和求根
signal 信号处理
sparse 稀疏矩阵
spatial 空间数据结构和算法
special 特殊函数模块
stats 统计分布和函数

1.1 线性代数

我们首先演示如何利用linalg子模块进行一些常见的线性代数运算。

首先是计算方阵的行列式:

from scipy import linalg
import numpy as np
a = np.array([[2, 3], [4, 8]])
print(linalg.det(a))

输出为:

3.999999999999999

计算方阵的逆矩阵:

a = np.array([[2, 3], [4, 8]])
b = linalg.inv(a)
print(b)

输出为:

[[ 2.   -0.75]
 [-1.    0.5 ]]

我们可以用numpy.dot来检验一下两个矩阵相乘的结果:

np.dot(a, b)

输出为一个单位阵:

array([[1., 0.],
       [0., 1.]])

我们也可以进行奇异值分解:

u, s, v = linalg.svd(a)
print(u)
print(s)
print(v)

输出为:

[[-0.37208166 -0.9282    ]
 [-0.9282      0.37208166]]
[9.63471004 0.41516558]
[[-0.46259444 -0.88657001]
 [-0.88657001  0.46259444]]

我们也可以检验一下结果,需要注意要将向量s变成一个对角线元素的矩阵:

print(u.dot(np.diag(s)).dot(v))

输出为原本的矩阵:

[[2. 3.]
 [4. 8.]]

1.2 优化和求根

我们接下来看一下optimize这个子模块的使用。

1.2.1

优化是找到最小值或等式的数值解的问题,optimize这个子模块提供了函数最小值、曲线拟合和寻找等式的根的有用算法。

我们首先定义一个函数:

def f(x):
   return x ** 2 + 10 * np.sin(x)


import matplotlib
import matplotlib.pyplot as plt
x = np.arange(-10, 10, 0.1)
plt.plot(x, f(x))
plt.show()

如下图所示:
图片说明

可以看到这个函数f大概在x为-1.3时有个全局最小值,在x为3.8时有个局部最小值。接下来我们从初始点使用梯度下降法寻找最小值,例如使用BFGS算法:

from scipy import optimize
optimize.fmin_bfgs(f, 0)

打印和输出的信息如下:

Optimization terminated successfully.
         Current function value: -7.945823
         Iterations: 5
         Function evaluations: 18
         Gradient evaluations: 6
array([-1.30644012])

可以看到当初始点为0时,我们可以找到全局最优点-1.30644012,然而这个方法一个可能的问题在于,如果函数有局部最小值,会因初始点不同找到这些局部最小而不是全局最小:

optimize.fmin_bfgs(f, 5)

打印和输出的信息为:

Optimization terminated successfully.
         Current function value: 8.315586
         Iterations: 5
         Function evaluations: 18
         Gradient evaluations: 6
array([3.83746712])

例如当我们改变初始点为5时,找到的是局部最优点3.83746712。

如果我们不知道全局最小值的邻近值来选定合适的初始点,那么为了找到全局最小点,最简单的算法是蛮力算法:

# 定义要搜索的x的范围
grid = (-10, 10, 0.1)
xmin_global = optimize.brute(f, (grid,))
print(xmin_global)

输出为:

[-1.30641113]

当输入的搜索范围很大时,scipy.optimize.brute()会变得非常慢。在这种情况下,需要考虑更加复杂的启发式算法。

1.2.2 求根

我们可以使用scipy.optimize.fsolve来找到f(x)=0的根:

# 这里1是我们的初始猜测
root = optimize.fsolve(f, 1)
print(root)

输出为:

[0.]

我们选取的初始值同样会影响我们找到的根:

# 我们改为-3
root = optimize.fsolve(f, -3)
print(root)

输出为:

[-2.47948183]

这里我们找到了另一个根-2.47948183。

1.2.3 带约束的优化

我们最后来看如何用SciPy来求解带约束的优化问题,一般形式如下:
图片说明
其中g(x)是不等式约束,h(x)是等式约束。

我们来考虑一个简单的问题,求解在x,y>=0,x+y=1的约束条件下,minimize 1-xx-yy:

from scipy.optimize import minimize
import numpy as np
e = 1e-10 # 设置一个非常接近0的值
fun = lambda x : 1 - x[0] * x[0] - x[1] * x[1]  # 目标函数
cons = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 1}, # x + y = 1
        {'type': 'ineq', 'fun': lambda x: x[0]}, # x >= 0
        {'type': 'ineq', 'fun': lambda x: x[1]}  # y >= 0
       )
x0 = np.array((1.0, 1.0)) # 设置初始值
res = minimize(fun, x0, method='SLSQP', constraints=cons)
print('最小值:',res.fun)
print('最优解:',res.x)
print('迭代终止是否成功:', res.success)
print('迭代终止原因:', res.message)

输出为:

最小值: 0.4999999999999998
最优解: [0.5 0.5]
迭代终止是否成功: True
迭代终止原因: Optimization terminated successfully.

由于这个问题的对称性,我们不难猜到最终的结果。可以看到我们使用的是minimize函数,完整的定义如下:m(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)。若是求一个函数的最大值,则改为求其相反数的最小值。上面用到的参数说明如下,更多的参数说明可以参考文档:

  • fun:目标函数
  • x0:初始值
  • method:求解问题的算法名,默认是BFGS, L-BFGS-B, SLSQP之一
  • constraints:约束条件

2. StatsModels

StatsModels模块最早起源于SciPy子模块stats中的models工具包,但后来从SciPy中移除了。到了2009年,经过修正、测试、改进并最终以全新的独立模块StatsModels诞生了。此后,StatsModels的开发团队不断添加新模型、绘图工具和统计方法,使得它最终成为了一款功能强大的统计分析工具。

作为示例,我们首先构造一下数据,并且使用OLS函数进行线性回归:

import statsmodels.api as sm
import numpy as np
x = np.linspace(0, 10, 100)
# 增加随机数
y = 3 * x + np.random.randn() + 10
# 加入一列常数项1
X = sm.add_constant(x)
# 用OLS模型进行拟合
mod = sm.OLS(y,X)
result = mod.fit()
print(result.params)

输出为:

[9.49869247 3.        ]

拟合出来的结果为y = 9.49869247 + 3x,与我们构造数据时设置的y = 10 + 3x已经非常接近。我们还可以进一步查看回归拟合的全部摘要:

print(result.summary())

输出为:

OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       1.000
Model:                            OLS   Adj. R-squared:                  1.000
Method:                 Least Squares   F-statistic:                 3.098e+32
Date:                Fri, 03 Jan 2020   Prob (F-statistic):               0.00
Time:                        15:23:48   Log-Likelihood:                 3152.7
No. Observations:                 100   AIC:                            -6301.
Df Residuals:                      98   BIC:                            -6296.
Df Model:                           1                            

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

<p> 在这个专刊中,我们会学习Python在金融中的应用: ·掌握Python进行数据分析和处理的方法; ·了解Python在量化投资中的应用; ·转行到金融数据分析和量化交易领域的基础等内容。 这个专刊适合: ·想要学习Python编程的在校学生; ·想要转行到金融领域的在职人士; ·想要利用业余时间进行量化投资的在职人士等。 本专刊购买后即可解锁所有章节,故不可以退换哦~ </p>

全部评论

相关推荐

07-01 17:14
中北大学 Java
兄弟们是真是假
牛客46374834...:我在boss上投java岗从来没成功过
点赞 评论 收藏
分享
05-20 13:59
门头沟学院 Java
米黑子米黑子:你这个成绩不争取下保研?
点赞 评论 收藏
分享
06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务