学习Scipy
Scipy基于Numpy上提供了丰富和高级的功能扩展,在统计、优化、插值、数值积分、时频转换等方面提供了大量的可用函数,基本覆盖了基础科学计算相关的问题。
import numpy as np
import scipy.stats as stats
import scipy.optimize as opt
统计部分
生成随机数
rv_continuout.rvs
和rv_discrete.rvs
分别表示连续性分布和离散型分布
连续性分布:均匀分布(uniform)、正态分布(norm)、分布等
离散型分布:伯努利分布(bernoulli)、几何分布(geom)、泊松分布(possion)等。
例如:生成10个区间在[0,1]上的随机数,和10个服从参数的β分布的随机数。
rv_unif = stats.uniform.rvs(size=10)
print( rv_unif)
rv_beta = stats.beta.rvs(size=10, a = 4, b= 2)
print( rv_beta)
[0.69072505 0.39568667 0.97696895 0.82618711 0.96705591 0.42781496
0.72790962 0.52970213 0.36345893 0.111741 ]
[0.91115421 0.69658873 0.70382818 0.40820351 0.55986853 0.89834803
0.70352751 0.49542004 0.98184075 0.54660852]
假设检验
norm_dist = stats.norm(loc=0.5, scale=2)
n = 200
data = norm_dist.rvs(size=n)
print("mean of data is : " + str(np.mean(data)))
print("median of data is : " + str(np.median(data)))
print("standard deviation of data is : " + str(np.std(data)))
生成正态分布的数据作为我们实际的某些数据,如股票数据。我们对数据进行简单的分析。
最简答的检验这一组数据是否服从假设的分布,如正态分布。最常见的解决方案是K-S检验(Kolmogorov-Smirnov test)。当样本K-S检验的原假设是给定的数据来自和假设分布相同的分布。
补充:K-S检验是比较一个频率分布f(x)和理论分布g(x)或者两个观测分布的检验方法
假设:两个数据分布一致或者数据符合理论分布。则
其中基本步骤
- 建立假设检验
- 有样本计算经验分布与理论函数,带入计算
- 查表确定临界值
- 做出判断 若,拒接零假设,认为拟合满意。
Scipy中提供了kstest函数,参数分别是数据、拟检验的分布名称和对应的参数。
mu = np.mean(data)
sigma = np.std(data)
stat_val , p_val = stats.kstest(data, 'norm', (mu, sigma))
print("KS-statistic D = %6.3f p-value %6.3f" %(stat_val, p_val))
KS-statistic D = 0.030 p-value 0.994
因为检验的p-value的值很大,所以接收原假设。
在正态分布的前提下,可以进一步检验这组数据的均值是不是0,典型的方法是t检验,其中单样本的t检验为ttest_1samp
。
T检验用于两个样本平均值差异程度的检验方法,用t分布的理论来推断差异发生的概率,从而判定两个平均数的差异是否显著。
stat_val , p_val = stats.ttest_1samp(data, 0)
print("One-sample t-statistic D=%6.3f , p-value = %6.3f" %(stat_val, p_val))
# One-sample t-statistic D= 4.376 , p-value = 0.000
因为p-vale < 0.05 ,所以在显著水平为0.05的前提下,我们应该拒接原假设。
再重新生成一个组数据进行两个数据组的测试
norm_dist2 = stats.norm(loc=-0.2, scale=1.2)
n = 200
data2 = norm_dist.rvs(size=n/2)
stat_val , p_val = stats.ttest_ind(data, data2, equal_var=False)
print("Two-sample t-statistic D=%6.3f , p-value = %6.3f" %(stat_val, p_val))
# Two-sample t-statistic D=-0.755 , p-value = 0.451
采用Welch‘s test 需要将equal_var =False。
stats还提供了大量的其他假设检验,如bartlett和levene用于检验方法是否相等,anderson_kasm 用于进行Anderson-Darling的K-样本检验。
其他函数
想要知道一个数值在某个分布中的分位,或者给定一个分布,某个分位上的数值,就可以使用cdf和ppf来完成。
g_dist = stats.gamma(a=2)
print("quantiles of 2, 4 and 5:")
print(g_dist.cdf([2, 4, 5]))
print("Values of 25%, 50% and 90%:")
print(g_dist.pdf([0.25, 0.5, 0.95]))
"""
quantiles of 2, 4 and 5:
[0.59399415 0.90842181 0.95957232]
Values of 25%, 50% and 90%:
[0.1947002 0.30326533 0.36740397]
"""
对于一个给定的分布,可以用moment方便的查看分布的矩信息。
print(stats.norm.moment(6, loc=0, scale=1))
# 15.00000000089533
describe 函数提供对数据集的统计描述分析,包括数据样本大小、极值、均值、方差、偏度和峰度。
norm_dist = stats.norm(loc=0, scale=1.8)
data = norm_dist.rvs(size=100)
info = stats.describe(data)
print("Data size is : " + str(info[0]))
print("Minimum value is : " + str(info[1][0]))
print("Maximum value is : " + str(info[1][1]))
print("Arithmetic mean is : "+ str(info[2]))
print("Unbiased variance is : " + str(info[3]))
print("Biased skewness is : "+ str(info[4]))
print("Biased kurtosis is :" + str(info[5]))
"""
Data size is : 100
Minimum value is : -4.428362346333642
Maximum value is : 3.9482904759937503
Arithmetic mean is : 0.3467482918091648
Unbiased variance is : 3.7927405291493415
Biased skewness is : -0.2728575318219303
Biased kurtosis is :-0.6224601079005065
"""
当我们知道某些分布的时候,可以调用fit
函数来得到分布参数的极大似然估计(MLE,maximum-likelihood estimation)。
最大似然估计目的:已知样本结果,反推最有可能的导致这种结果的参数的参数值。
norm_dist = stats.norm(loc=0, scale=1.8)
data = norm_dist.rvs(size=100)
mu, sigma = stats.norm.fit(data)
print("MLE of data mean: " + str(mu))
print("MLE of data standard deviation: " + str(sigma))
"""
MLE of data mean: 0.32015564648710865
MLE of data standard deviation: 1.671667393210974
"""
pearsonr 和 spearmanr 可以计算Pearson和Spearman相关系数,这两个相关系数度量了这两组数据的相互线性关联程序。
norm_dist = stats.norm()
data1 = norm_dist.rvs(size = 100)
exp_dist = stats.expon()
data2 = exp_dist.rvs(size = 100)
cor, pval = stats.pearsonr(data1, data2)
print("Pearson correlation coefficient: " +str(cor))
cor, pval = stats.spearmanr(data1, data2)
print("Spearman's rank correlation coefficient: " + str(cor))
"""
Pearson correlation coefficient: 0.028887835045354134
Spearman's rank correlation coefficient: 0.0114011401140114
"""
其中p-value表示原假设下,相关系数的显著性。
在StatsModels模块提供了更为专业的模块。