我想通过Python进行置信区间为0.95%的概率威布尔拟合。作为测试数据,我使用了测量的失败周期,并针对可靠性R(t)进行了绘制。
到目前为止,我找到了一种进行威布尔拟合的方法,但是,我仍然无法获得置信区间。带有相同测试数据集的Weibull图已经用原点进行过,因此我知道我将“期望”哪种形状作为置信区间。但是我不知道如何到达那里。
我在reliawiki上找到了关于Weibull置信区间的信息(请参阅基于Fisher矩阵置信区间的可靠性边界),并使用那里的描述来计算方差以及置信区间的上限和下限(R_U和R_L)
这是一个适用于我的Weibull拟合的工作代码示例,其可信度与测试数据集的关系基于reliawiki的描述(请参阅可靠性界限)。为了进行拟合,我使用了OLS模型拟合。
import os, sys
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from scipy.optimize import curve_fit
import math
import statsmodels.api as sm
def weibull_ticks(y, pos):
return "{:.0f}%".format(100 * (1 - np.exp(-np.exp(y))))
def loglog(x):
return np.log(-np.log(1 - np.asarray(x)))
class weibull_example(object):
def __init__(self, dat):
self.fits = {}
dat.index = np.arange(1, len(dat) + 1)
dat.sort_values('data', inplace=True)
#define yaxis-values
dat['percentile'] = dat.index*1/len(dat)
self.data = dat
self.fit()
self.plot_data()
def fit(self):
#fit the data points with a the OLS model
self.data=self.data[:-1]
x0 = np.log(self.data.dropna()['data'].values)
Y = loglog(self.data.dropna()['percentile'])
Yx = sm.add_constant(Y)
model = sm.OLS(x0, Yx)
results = model.fit()
yy = loglog(np.linspace(.001, .999, 100))
YY = sm.add_constant(yy)
XX = np.exp(results.predict(YY))
self.eta = np.exp(results.params[0])
self.beta = 1 / results.params[1]
self.fits['syx'] = {'results': results, 'model': model,
'line': np.row_stack([XX, yy]),
'beta': self.beta,
'eta': self.eta}
cov = results.cov_params()
#get variance and covariance
self.beta_var = cov[1, 1]
self.eta_var = cov[0, 0]
self.cov = cov[1, 0]
def plot_data(self, fit='yx'):
dat = self.data
#plot data points
plt.semilogx(dat['data'], loglog(dat['percentile']), 'o')
fit = 's' + fit
self.plot_fit(fit)
ax = plt.gca()
formatter = mpl.ticker.FuncFormatter(weibull_ticks)
ax.yaxis.set_major_formatter(formatter)
yt_F = np.array([0.001, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5,
0.6, 0.7, 0.8, 0.9, 0.95, 0.99])
yt_lnF = loglog(yt_F)
plt.yticks(yt_lnF)
plt.ylim(loglog([.01, .99]))
def plot_fit(self, fit='syx'):
dat = self.fits[fit]['line']
plt.plot(dat[0], dat[1])
#calculate variance to get confidence bound
def variance(x):
return (math.log(x) - math.log(self.eta)) ** 2 * self.beta_var + \
(self.beta/self.eta) ** 2 * self.eta_var - \
2 * (math.log(x) - math.log(self.eta)) * (-self.beta/self.eta) * self.cov
#calculate confidence bounds
def confidence_upper(x):
return 1-np.exp(-np.exp(self.beta*(math.log(x)-math.log(self.eta)) - 0.95*np.sqrt(variance(x))))
def confidence_lower(x):
return 1-np.exp(-np.exp(self.beta*(math.log(x)-math.log(self.eta)) + 0.95*np.sqrt(variance(x))))
yvals_1 = list(map(confidence_upper, dat[0]))
yvals_2 = list(map(confidence_lower, dat[0]))
#plot confidence bounds
plt.semilogx(dat[0], loglog(yvals_1), linestyle="solid", color="black", linewidth=2,
label="fit_u_1", alpha=0.8)
plt.semilogx(dat[0], loglog(yvals_2), linestyle="solid", color="green", linewidth=2,
label="fit_u_1", alpha=0.8)
def main():
fig, ax1 = plt.subplots()
ax1.set_xlabel("$Cycles\ til\ Failure$")
ax1.set_ylabel("$Weibull\ Percentile$")
#my data points
data = pd.DataFrame({'data': [1556, 2595, 11531, 38079, 46046, 57357]})
weibull_example(data)
plt.savefig("Weibull.png")
plt.close(fig)
if __name__ == "__main__":
main()
我的情节中的置信范围看起来不像我预期的那样。我尝试了许多不同的“方差”,只是为了了解功能并检查问题是否只是键入错误。同时,我确信该问题更为普遍,并且我从reliawiki的描述中了解到一些错误。不幸的是,我确实没有遇到什么问题,而且我不认识其他任何人。在互联网和不同的论坛上,我找不到合适的答案。
这就是为什么我决定在这里问这个问题的原因。这是我第一次在论坛中提问。因此,我希望我能充分解释所有内容,并且该代码示例对您有所帮助。 非常感谢:)
答案 0 :(得分:0)
对于迟到的答案深表歉意,但我会为任何未来的读者提供它。 与其尝试自己实现这一点,不如考虑使用专为此设计的包,称为可靠性。 这是您的用例的 example。
如果这个答案对你有帮助,记得点赞 :)