计算性能scipy weibull min fit vs Matlab wblfit



使用Matlabwblrndwblfit函数以及Pythonscipy.stats.weibull_min.fit函数来拟合威布尔分布的数据,我发现Matlab的性能比Python高出近2个数量级。我正在寻找一些帮助,以提高Python代码的性能。

问题:

在将Matlab代码转换为Python时,我遇到了以下代码:

weibull_parameters = zeros(10000, 2)
for i = 1:10000
data = sort(wblrnd(alpha, beta, 1, 24))
[weibull_parameters(i, :), ~] = wblfit(data, confidence_interval, censoring_array)
end

此代码从威布尔分布中生成24个随机数,然后将结果数据向量再次拟合到威布尔分布中。

在Python中,我将其翻译为:

from scipy.stats import weibull_min
import numpy as np

data = np.sort(alpha * np.random.default_rng().weibull(beta, (10000, 24)))
weibull_parameters = np.zeros((10000, 2))
for idx, row in enumerate(data):
weibull_parameters[idx, :] = weibull_min.fit(row, floc=0)[2::-2]

在这里,我一次性生成完整的随机数据,然后遍历这些行,使用weibull_min获得相应的Weibull参数。适应函数。最后的切片是只选择输出中的比例和形状参数,并将它们按正确的顺序排列。

我遇到的主要问题是Python的计算性能很糟糕。Matlab在几秒钟内运行此代码,然而对于Python来说,每100次迭代需要1-1.5秒(在我的笔记本电脑上),因此性能差异几乎是2个数量级。

是否有方法可以提高Python的性能?是否有可能对拟合计算进行矢量化?很遗憾,我在网上找不到关于这个话题的任何东西。

注1:Matlab允许用户在wblfit函数中指定置信区间,但是对于Python,我找不到包含它的方法,所以我忽略了它。

注2:我能找到的包含审查的唯一选择是使用surval包,但是性能更糟糕(每100次迭代大约10秒)

Python并不是最快的语言。你可以做一些事情来加快速度,但你会发现在准确性和速度之间有一个平衡。

至于拟合威布尔分布的方法,有几个包可以做到这一点。包的scipy、存活、生命线和可靠性都将适合完整的数据。最后3个还将处理删节数据,而scipy不会。

我是可靠性的作者,所以我将展示一个使用这个包的例子:

from reliability.Distributions import Weibull_Distribution
from reliability.Fitters import Fit_Weibull_2P
import time
import numpy as np
rows=100
samples = 24
data_array = np.empty((rows,samples))
true_parameters = np.empty((rows,2))
for i in range(rows):
alpha = np.random.randint(low=1,high=999) + np.random.rand() #alpha between 1 and 1000
beta = np.random.randint(low=1,high=10) - np.random.rand()/2 #beta between 0.5 and 10
true_parameters[i][0] = alpha
true_parameters[i][1] = beta
dist = Weibull_Distribution(alpha=alpha,beta=beta)
data_array[i]=dist.random_samples(samples)
start_time = time.time()
parameters = np.empty((rows,2))
for i in range(rows):
fit = Fit_Weibull_2P(failures=data_array[i],show_probability_plot=False,print_results=False)
parameters[i][0] = fit.alpha
parameters[i][1] = fit.beta
runtime = time.time()-start_time
# np.set_printoptions(suppress=True) #supresses the scientific notation used by numpy
# print('True parameters:')
# print(true_parameters)
# print('Fitted parameters:')
# print(parameters)
print('Runtime:',runtime,'seconds')
print('Runtime per iteration:',runtime/rows,'seconds')

当我运行这个时,它给出:

Runtime: 3.378781318664551 seconds
Runtime per iteration: 0.033787813186645504 seconds

根据你在问题中引用的时间,这大约是scipy的两倍,但只有surval的三分之一。

我希望这有助于向您展示做同样事情的不同方法,但我知道这可能不是您所寻求的性能改进。获得巨大性能改进的唯一方法是在纯python中使用最小二乘估计,可能使用numba加速。这样的方法可能会给您带来不如MLE的结果,但是正如我前面所说的,在速度和准确性之间,以及在速度和编码便利性之间存在一个平衡。

相关内容

  • 没有找到相关文章

最新更新