matthewreid854 / reliability Goto Github PK
View Code? Open in Web Editor NEWReliability engineering toolkit for Python - https://reliability.readthedocs.io/en/latest/
License: GNU Lesser General Public License v3.0
Reliability engineering toolkit for Python - https://reliability.readthedocs.io/en/latest/
License: GNU Lesser General Public License v3.0
Find this package gem yesterday, and was reading documentation trying to figure it out if I can use it to adjust stress test times.
In https://reliability.readthedocs.io/en/latest/Working%20with%20fitted%20distributions.html was reading:
If you want to know the system reliability at a certain time, then you are specifying time (CI_x) and seeking bounds on reliability (CI_type=’reliability’). If you want to know the time that the system will reach a certain reliability, then you are specifying reliability (CI_y) and seeking bounds on time (CI_type=’time’)
Then using my data the Weibull_Mixture
Was trying to use:
from reliability.Fitters import Fit_Weibull_Mixture
fit = Fit_Weibull_Mixture(failures=failures,show_probability_plot=True,print_results=True)
My expectation was to use fit.distribution.CDF(CI_type='reliability',CI_x=660*60/2)
to know the reliability if I decrease test time by half but I go the AttributeError: 'Line2D' object has no property 'CI_type'
error below.
What am not sure and I appreciate feedback is if I could use the results of the best_distribution
to try to answer questions like:
Appreciate reference material to read on this topic as well.
Describe the bug
Resulting probability of failure is ~0%, need a larger number of trapezoids (x, defined by np.linspace) for the interval to converge on the expected value.
Also, the shading to the right of the salmon region should probably be blue (although I could also see the argument for filling with salmon since there is a high probability of failure in this region...)
To Reproduce
from reliability import Distributions
from reliability.Other_functions import stress_strength
import matplotlib.pyplot as plt
mu = 5.07
sigma = 1.68
stress = Distributions.Lognormal_Distribution(mu=mu, sigma=sigma )
beta = 3
eta = 250
strength = Distributions.Weibull_Distribution(alpha=eta, beta=beta)
stress_strength(stress=stress, strength=strength)
plt.xlim(0,600)
Result:
Stress - Strength Interference
Stress Distribution: Lognormal Distribution (μ=5.07,σ=1.68)
Strength Distribution: Weibull Distribution (α=250,β=3)
Probability of failure (stress > strength): 3.11692e-06 %
Expected behavior
Probability of failure should be ~44%
Additional context
In my case, I needed >8K trapezoids to get this to converge. I can come up with other examples where more trapezoids would be needed, but these examples are less and less realistic. I'd propose increasing the number of trapezoids to 100K or 1M to cover 99.9% of use cases without impacting performance.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
list=[]
for num_trapz in range(1000,1000000,1000):
x = np.linspace(
min(stress.quantile(1e-8), strength.quantile(1e-8)),
max(strength.quantile(1 - 1e-8), stress.quantile(1 - 1e-8)),
num_trapz,
) # we take the min and max here since there may be cases when stress > strength
prob_of_failure = np.trapz(
strength.PDF(x, show_plot=False) * stress.SF(x, show_plot=False), x
)
list.append([num_trapz, prob_of_failure])
df_probability = pd.DataFrame(list, columns=['Number of Trapezoids', 'Probability of Failure'])
df_probability.plot(x='Number of Trapezoids', y='Probability of Failure', kind='scatter')
plt.xscale('log')
For the fill, here's another example of how the current method of filling can get mixed up:
from reliability import Distributions
from reliability.Other_functions import stress_strength
import matplotlib.pyplot as plt
beta = 3
eta = 250
stress = Distributions.Weibull_Distribution(alpha=eta, beta=beta, gamma=100)
strength = Distributions.Weibull_Distribution(alpha=eta, beta=beta)
stress_strength_og(stress=stress, strength=strength)
plt.xlim(0,600)
Need to add in support for discrete probability distributions.
Specifically we need Binomial and Poisson probability distributions.
Others may be added if a use case can be provided.
Example1 for Fitting a specific distribution to data
succeed with packages below;
reliability==0.8.7
matplotlib==3.6.1
% python
Python 3.11.2 (v3.11.2:878ead1ac1, Feb 7 2023, 10:02:41) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from reliability.Fitters import Fit_Weibull_2P
>>> import matplotlib.pyplot as plt
>>> data = [58,75,36,52,63,65,22,17,28,64,23,40,73,45,52,36,52,60,13,55,82,55,34,57,23,42,66,35,34,25] # made using Weibull Distribution(alpha=50,beta=3)
>>> wb = Fit_Weibull_2P(failures=data)
Results from Fit_Weibull_2P (95% CI):
Analysis method: Maximum Likelihood Estimation (MLE)
Optimizer: TNC
Failures / Right censored: 30/0 (0% right censored)
Parameter Point Estimate Standard Error Lower CI Upper CI
Alpha 51.858 3.55628 45.3359 59.3183
Beta 2.80086 0.41411 2.09624 3.74233
Goodness of fit Value
Log-likelihood -129.063
AICc 262.57
BIC 264.928
AD 0.759805
>>> plt.show()
But, when I uninstall matplotlib and reliability, then install them again as below,
% pip uninstall matplotlib reliability
Successfully uninstalled matplotlib-3.6.1
Successfully uninstalled reliability-0.8.7
% pip install matplotlib reliability
Collecting matplotlib
Using cached matplotlib-3.7.0-cp311-cp311-macosx_10_12_x86_64.whl (7.4 MB)
Collecting reliability
Using cached reliability-0.8.7-py3-none-any.whl (256 kB)
Requirement already satisfied: contourpy>=1.0.1 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (1.0.7)
Requirement already satisfied: cycler>=0.10 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (0.11.0)
Requirement already satisfied: fonttools>=4.22.0 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (4.38.0)
Requirement already satisfied: kiwisolver>=1.0.1 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (1.4.4)
Requirement already satisfied: numpy>=1.20 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (1.24.2)
Requirement already satisfied: packaging>=20.0 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (23.0)
Requirement already satisfied: pillow>=6.2.0 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (9.4.0)
Requirement already satisfied: pyparsing>=2.3.1 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (3.0.9)
Requirement already satisfied: python-dateutil>=2.7 in ./l3aa/lib/python3.11/site-packages (from matplotlib) (2.8.2)
Requirement already satisfied: autograd>=1.3 in ./l3aa/lib/python3.11/site-packages (from reliability) (1.5)
Requirement already satisfied: scipy>=1.7.0 in ./l3aa/lib/python3.11/site-packages (from reliability) (1.10.1)
Requirement already satisfied: pandas>=1.1.2 in ./l3aa/lib/python3.11/site-packages (from reliability) (1.5.3)
Requirement already satisfied: autograd-gamma>=0.5.0 in ./l3aa/lib/python3.11/site-packages (from reliability) (0.5.0)
Requirement already satisfied: mplcursors>=0.3 in ./l3aa/lib/python3.11/site-packages (from reliability) (0.5.2)
Requirement already satisfied: docutils<0.18 in ./l3aa/lib/python3.11/site-packages (from reliability) (0.17.1)
Requirement already satisfied: future>=0.15.2 in ./l3aa/lib/python3.11/site-packages (from autograd>=1.3->reliability) (0.18.3)
Requirement already satisfied: pytz>=2020.1 in ./l3aa/lib/python3.11/site-packages (from pandas>=1.1.2->reliability) (2022.7.1)
Requirement already satisfied: six>=1.5 in ./l3aa/lib/python3.11/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)
Installing collected packages: matplotlib, reliability
Successfully installed matplotlib-3.7.0 reliability-0.8.7
% pip freeze
appnope==0.1.3
asttokens==2.2.1
autograd==1.5
autograd-gamma==0.5.0
backcall==0.2.0
contourpy==1.0.7
cycler==0.11.0
decorator==5.1.1
docutils==0.17.1
executing==1.2.0
fonttools==4.38.0
future==0.18.3
ipython==8.10.0
jedi==0.18.2
kiwisolver==1.4.4
matplotlib==3.7.0
matplotlib-inline==0.1.6
mplcursors==0.5.2
numpy==1.24.2
packaging==23.0
pandas==1.5.3
parso==0.8.3
pexpect==4.8.0
pickleshare==0.7.5
Pillow==9.4.0
prompt-toolkit==3.0.36
ptyprocess==0.7.0
pure-eval==0.2.2
Pygments==2.14.0
pyparsing==3.0.9
python-dateutil==2.8.2
pytz==2022.7.1
reliability==0.8.7
scipy==1.10.1
six==1.16.0
stack-data==0.6.2
traitlets==5.9.0
wcwidth==0.2.6
Example1 for Fitting a specific distribution to data fails with error and fit line is not drawn in plot while "Results from Fit_Weibull_2P" comes out.
% python
Python 3.11.2 (v3.11.2:878ead1ac1, Feb 7 2023, 10:02:41) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from reliability.Fitters import Fit_Weibull_2P
>>> import matplotlib.pyplot as plt
>>> data = [58,75,36,52,63,65,22,17,28,64,23,40,73,45,52,36,52,60,13,55,82,55,34,57,23,42,66,35,34,25] # made using Weibull Distribution(alpha=50,beta=3)
>>> wb = Fit_Weibull_2P(failures=data)
Results from Fit_Weibull_2P (95% CI):
Analysis method: Maximum Likelihood Estimation (MLE)
Optimizer: TNC
Failures / Right censored: 30/0 (0% right censored)
Parameter Point Estimate Standard Error Lower CI Upper CI
Alpha 51.858 3.55628 45.3359 59.3183
Beta 2.80086 0.41411 2.09624 3.74233
Goodness of fit Value
Log-likelihood -129.063
AICc 262.57
BIC 264.928
AD 0.759805
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/hyakutakeshinkoku/l3aa/lib/python3.11/site-packages/reliability/Fitters.py", line 2333, in __init__
Weibull_probability_plot(
File "/Users/hyakutakeshinkoku/l3aa/lib/python3.11/site-packages/reliability/Probability_plotting.py", line 373, in Weibull_probability_plot
plt.grid(b=True, which="major", color="k", alpha=0.3, linestyle="-")
File "/Users/hyakutakeshinkoku/l3aa/lib/python3.11/site-packages/matplotlib/pyplot.py", line 2589, in grid
return gca().grid(visible=visible, which=which, axis=axis, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/hyakutakeshinkoku/l3aa/lib/python3.11/site-packages/matplotlib/axes/_base.py", line 3196, in grid
self.xaxis.grid(visible, which=which, **kwargs)
File "/Users/hyakutakeshinkoku/l3aa/lib/python3.11/site-packages/matplotlib/axis.py", line 1655, in grid
self.set_tick_params(which='major', **gridkw)
File "/Users/hyakutakeshinkoku/l3aa/lib/python3.11/site-packages/matplotlib/axis.py", line 927, in set_tick_params
kwtrans = self._translate_tick_params(kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/hyakutakeshinkoku/l3aa/lib/python3.11/site-packages/matplotlib/axis.py", line 1071, in _translate_tick_params
raise ValueError(
ValueError: keyword grid_b is not recognized; valid keywords are ['size', 'width', 'color', 'tickdir', 'pad', 'labelsize', 'labelcolor', 'zorder', 'gridOn', 'tick1On', 'tick2On', 'label1On', 'label2On', 'length', 'direction', 'left', 'bottom', 'right', 'top', 'labelleft', 'labelbottom', 'labelright', 'labeltop', 'labelrotation', 'grid_agg_filter', 'grid_alpha', 'grid_animated', 'grid_antialiased', 'grid_clip_box', 'grid_clip_on', 'grid_clip_path', 'grid_color', 'grid_dash_capstyle', 'grid_dash_joinstyle', 'grid_dashes', 'grid_data', 'grid_drawstyle', 'grid_figure', 'grid_fillstyle', 'grid_gapcolor', 'grid_gid', 'grid_in_layout', 'grid_label', 'grid_linestyle', 'grid_linewidth', 'grid_marker', 'grid_markeredgecolor', 'grid_markeredgewidth', 'grid_markerfacecolor', 'grid_markerfacecoloralt', 'grid_markersize', 'grid_markevery', 'grid_mouseover', 'grid_path_effects', 'grid_picker', 'grid_pickradius', 'grid_rasterized', 'grid_sketch_params', 'grid_snap', 'grid_solid_capstyle', 'grid_solid_joinstyle', 'grid_transform', 'grid_url', 'grid_visible', 'grid_xdata', 'grid_ydata', 'grid_zorder', 'grid_aa', 'grid_c', 'grid_ds', 'grid_ls', 'grid_lw', 'grid_mec', 'grid_mew', 'grid_mfc', 'grid_mfcalt', 'grid_ms']
>>> plt.show()
pip check do not raise any warnings.
% pip check
No broken requirements found.
So far, I can succeed Example1 for Fitting a specific distribution to data by installing matplotlib 3.6.1 and I do not have inconvenience about that, but this problem with matplotlib-3.7.0 might be confusing.
% pip install "matplotlib==3.6.1"
Collecting matplotlib==3.6.1
Using cached matplotlib-3.6.1-cp311-cp311-macosx_10_12_x86_64.whl (7.3 MB)
Requirement already satisfied: contourpy>=1.0.1 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (1.0.7)
Requirement already satisfied: cycler>=0.10 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (0.11.0)
Requirement already satisfied: fonttools>=4.22.0 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (4.38.0)
Requirement already satisfied: kiwisolver>=1.0.1 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (1.4.4)
Requirement already satisfied: numpy>=1.19 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (1.24.2)
Requirement already satisfied: packaging>=20.0 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (23.0)
Requirement already satisfied: pillow>=6.2.0 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (9.4.0)
Requirement already satisfied: pyparsing>=2.2.1 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (3.0.9)
Requirement already satisfied: python-dateutil>=2.7 in ./l3aa/lib/python3.11/site-packages (from matplotlib==3.6.1) (2.8.2)
Requirement already satisfied: six>=1.5 in ./l3aa/lib/python3.11/site-packages (from python-dateutil>=2.7->matplotlib==3.6.1) (1.16.0)
Installing collected packages: matplotlib
Attempting uninstall: matplotlib
Found existing installation: matplotlib 3.7.0
Uninstalling matplotlib-3.7.0:
Successfully uninstalled matplotlib-3.7.0
Successfully installed matplotlib-3.6.1
macOS 13.1
Intel Core i5
Python 3.11.2
I'm doing the following in MATLAB to extract CI and plot them:
[~,pCov] = wbllike([parameters1(1),parameters1(2)],H-sogliaH);
[H_cdf_W, H_cdf_W_ci1,H_cdf_W_ci2] =wblcdf(H0,parameters1(1),parameters1(2),pCov,0.05);
I know I can plort CI directly in reliability, but.. how can I extract values and have something like H_cdf_W_ci1 and H_cdf_W_ci2 ?
Is this a known error? Is there a known resolution?
https://reliability.readthedocs.io/en/latest/API/Fitters/Fit_Everything.html
Traceback (most recent call last):
File "C:\fitters.py", line 15, in
output = Fit_Everything(logt)
File "C:.conda\envs\battery\lib\site-packages\reliability\Fitters.py", line 1263, in init
Fit_Everything.__probability_plot(self)
File "C:.conda\envs\battery\lib\site-packages\reliability\Fitters.py", line 1755, in __probability_plot
Weibull_probability_plot(
File "C:.conda\envs\battery\lib\site-packages\reliability\Probability_plotting.py", line 373, in Weibull_probability_plot
plt.grid(b=True, which="major", color="k", alpha=0.3, linestyle="-")
File "C:.conda\envs\battery\lib\site-packages\matplotlib\pyplot.py", line 3144, in grid
gca().grid(visible=visible, which=which, axis=axis, **kwargs)
File "C:.conda\envs\battery\lib\site-packages\matplotlib\axes_base.py", line 3196, in grid
self.xaxis.grid(visible, which=which, **kwargs)
File "C:.conda\envs\battery\lib\site-packages\matplotlib\axis.py", line 1697, in grid
self.set_tick_params(which='major', **gridkw)
File "C:.conda\envs\battery\lib\site-packages\matplotlib\axis.py", line 958, in set_tick_params
kwtrans = self._translate_tick_params(kwargs)
File "C:.conda\envs\battery\lib\site-packages\matplotlib\axis.py", line 1102, in _translate_tick_params
raise ValueError(
ValueError: keyword grid_b is not recognized; valid keywords are ['size', 'width', 'color', 'tickdir', 'pad', 'labelsize', 'labelcolor', 'labelfontfamily', 'zorder', 'gridOn', 'tick1On', 'tick2On', 'label1On', 'label2On', 'length', 'direction', 'left', 'bottom', 'right', 'top', 'labelleft', 'labelbottom', 'labelright', 'labeltop', 'labelrotation', 'grid_agg_filter', 'grid_alpha', 'grid_animated', 'grid_antialiased', 'grid_clip_box', 'grid_clip_on', 'grid_clip_path', 'grid_color', 'grid_dash_capstyle', 'grid_dash_joinstyle', 'grid_dashes', 'grid_data', 'grid_drawstyle', 'grid_figure', 'grid_fillstyle', 'grid_gapcolor', 'grid_gid', 'grid_in_layout', 'grid_label', 'grid_linestyle', 'grid_linewidth', 'grid_marker', 'grid_markeredgecolor', 'grid_markeredgewidth', 'grid_markerfacecolor', 'grid_markerfacecoloralt', 'grid_markersize', 'grid_markevery', 'grid_mouseover', 'grid_path_effects', 'grid_picker', 'grid_pickradius', 'grid_rasterized', 'grid_sketch_params', 'grid_snap', 'grid_solid_capstyle', 'grid_solid_joinstyle', 'grid_transform', 'grid_url', 'grid_visible', 'grid_xdata', 'grid_ydata', 'grid_zorder', 'grid_aa', 'grid_c', 'grid_ds', 'grid_ls', 'grid_lw', 'grid_mec', 'grid_mew', 'grid_mfc', 'grid_mfcalt', 'grid_ms']
The current method of estimating the gamma parameter for location shifted distributions (Weibull_3P, Gamma_3P, Exponential_2P) is not always accurate. The method is an over-simplification and works by setting the gamma parameter equal to a value that is slightly less than the lowest failure time and then adjusting the rest of the data so that it looks like a non-location shifted distribution.
This was done because reliability.Fitters uses scipy.stats to provide the initial guess into the optimization routine when trying to minimize the log-likelihood. Unfortunately, scipy.stats is really bad at giving an accurate guess for the gamma parameter and it was found that convergence rarely worked or the solution provided was very wrong.
In order to fix this, I suspect that we will need to come up with another method of providing the initial guesses for the optimizer so that we do not need to rely on the fit (of the failure data) provided by scipy.stats.
This problem is most prevalent when there is a lot of censored data or when there is not much data.
Hi,
I'd like to fit some failure and censored data, but show_probability_plot = True
return me an error.
This is my code:
# time quantity category
# 0 40.0 1 F
# 1 30.5 1 F
# 2 33.5 1 F
# 3 27.5 1 F
# 4 20.5 1 F
# 5 4.0 1 F
# 6 26.5 1 F
# 7 23.5 1 F
# 8 5.0 1 F
# 9 11.0 1 F
# 10 16.5 1 F
# 11 13.0 1 F
# 12 13.0 1 F
# 13 56.0 23 C
# 14 33.0 94 C
# 15 40.0 93 C
# 16 34.0 111 C
# 17 27.0 36 C
# 18 14.0 96 C
# 19 38.0 123 C
# 20 36.0 117 C
# 21 24.0 111 C
# 22 27.0 36 C
# 23 40.0 93 C
# 24 46.0 12 C
# 25 60.0 17 C
def main():
df = pd.read_excel(io=cfg.XLSX_DATA_FILE, usecols="A:C")
wb = Fit_Weibull_2P_grouped(
dataframe=df,
show_probability_plot=True,
print_result=True,
CI=0.95,
force_beta=None,
initial_guess_method='scipy', # Use MLE method
optimizer='L-BFGS-B', # 'TNC'
CI_type='time')
And this is the errors:
Results from Fit_Weibull_2P_grouped (95% CI):
Point Estimate Standard Error Lower CI Upper CI
Parameter
Alpha 841.936432 718.088263 158.229997 4479.915126
Beta 1.340325 0.350346 0.803000 2.237198
Log-Likelihood: -114.06196026616448
Number of failures: 13
Number of right censored: 962
Fraction censored: 98.66667 %
Traceback (most recent call last):
File "reliasc.py", line 75, in <module>
main()
File "reliasc.py", line 57, in main
wb = Fit_Weibull_2P_grouped(
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\reliability\Fitters.py", line 1194, in __init__
Weibull_probability_plot(failures=failures, right_censored=right_censored, __fitted_dist_params=self, CI=CI, CI_type=CI_type, **kwargs)
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\reliability\Probability_plotting.py", line 216, in Weibull_probability_plot
wbf.CDF(label=label, **kwargs)
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\reliability\Distributions.py", line 339, in CDF
p = plt.plot(X, cdf, **kwargs)
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\pyplot.py", line 2840, in plot
return gca().plot(
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\axes\_axes.py", line 1743, in plot
lines = [*self._get_lines(*args, data=data, **kwargs)]
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\axes\_base.py", line 273, in __call__
yield from self._plot_args(this, kwargs)
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\axes\_base.py", line 418, in _plot_args
return [func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\axes\_base.py", line 418, in <listcomp>
return [func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\axes\_base.py", line 312, in _makeline
seg = mlines.Line2D(x, y, **kw)
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\lines.py", line 390, in __init__
self.update(kwargs)
File "C:\Users\tmonti\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\artist.py", line 996, in update
raise AttributeError(f"{type(self).__name__!r} object "
AttributeError: 'Line2D' object has no property 'print_result'
Thank you.
Describe the bug
Using the "Canadian Senators" data from lifelines, and removing the 0 values, the results from reliability are a bit different to those of lifelines. It is worth investigating:
To Reproduce
import lifelines
from lifelines.datasets import *
from reliability.Fitters import *
df = load_canadian_senators()
x = df['diff_days'].values
c = 1 - df['observed'].astype(int)
zero_idx = (x == 0)
x = x[~zero_idx]
c = c[~zero_idx]
# Failed/suspended format
f = x[c == 0]
s = x[c == 1]
rel_model = Fit_Exponential_1P(f, s, print_results=False, show_probability_plot=False)
print("Rate:")
print(rel_model.Lambda)
ef = lifelines.ExponentialFitter()
ll_lambda = 1./ef.fit(x, 1 - c).params_.values[0]
print(ll_lambda)
print("Life:")
print(1./rel_model.Lambda)
print(1./ll_lambda)
Expected behavior
I would expect the results to be closer to the lifelines results. I came across this error testing my own package, SurPyval
, against reliability
and lifelines
. SurPyval
consistently achieves the same results as lifelines, and of all three packages lifelines is the most mature and most popular. Therefore it is the standard so results should probably match it.
You might consider using numpy's random sampling for the distributions it supports because it is significantly faster than scipy's. A brief check indicates that loglogistic is the only one numpy doesn't have built in.
Here's a quick test using a Weibull:
%%timeit
fit.distribution.random_samples(1)
54.9 µs ± 2.06 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
np.random.weibull(fit.distribution.beta) * fit.distribution.alpha
1.95 µs ± 19.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Not a huge deal in terms of usability, but if someone is drawing lots of samples (like me) it could be nice.
I'd be happy to do an PR, but it sounds like you're not interested in direct contributions.
Hello everyone,
Firstly, I want to thank @MatthewReid854 for his outstanding work on this entire library. I am blown away by the fact that he is a "one-man-band" for this entire repository.
I am currently working on a class-inclusion probability model. My goal is to determine how likely it is that a given sample belongs to a specific class. To get this class-inclusion probability model working, I need to fit one three parameter reversed Weibull distribution to each class. I am new to the whole reliablitiy engineering topic and therefore lacking an understanding of what the meaning of the reversed Weibull distribution in comparison to the normal one is. I am wondering whether I can use the Fit_Weibull_3P
function to fit the reversed Weibull distribution (see formula below) as well?
Describe the bug
Hi
First of all, thanks for creating this intuitive package for Reliability!
I'm trying out the sample codes you've given under each topic in the package, getting a few errors in some parts, one those is below,
In the Package Doc - "see how the confidence bounds on time or reliability should be used based on what we are trying to predict" - "EXAMPLE 1"
To Reproduce
`from reliability.Distributions import Weibull_Distribution
from reliability.Fitters import Fit_Weibull_2P
import matplotlib.pyplot as plt
dist = Weibull_Distribution(alpha=500,beta=3)
data = dist.random_samples(10,seed=1)
fit = Fit_Weibull_2P(failures=data,show_probability_plot=False,print_results=False)
plt.figure(figsize=(10,7))
plt.subplot(121)
arrow_x = 25
arrow_y = 0.025
X_lower,X_point,X_upper = fit.distribution.CDF(CI_type='time',CI_y=0.7)
plt.arrow(x=0,y=0.7,dx=X_upper,dy=0,color='red',head_width=arrow_y,head_length=arrow_x,length_includes_head=True)
plt.arrow(x=X_lower,y=0.7,dx=0,dy=-0.7,color='red',head_width=arrow_x,head_length=arrow_y,length_includes_head=True)
plt.arrow(x=X_point,y=0.7,dx=0,dy=-0.7,color='red',head_width=arrow_x,head_length=arrow_y,length_includes_head=True)
plt.arrow(x=X_upper,y=0.7,dx=0,dy=-0.7,color='red',head_width=arrow_x,head_length=arrow_y,length_includes_head=True)
plt.xlim(0,dist.quantile(0.99))
plt.ylim(0,1.1)
plt.text(x=0,y=0.705,s='CI_y=0.7',va='bottom')
plt.text(x=X_lower,y=0.035,s='lower',va='bottom',ha='right',rotation=90)
plt.text(x=X_point,y=0.035,s='point',va='bottom',ha='right',rotation=90)
plt.text(x=X_upper,y=0.035,s='upper',va='bottom',ha='right',rotation=90)
plt.title('Weibull CDF\nConfidence bounds on time')`
The output that Python gave you -
`---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
in
12 arrow_y = 0.025
13
---> 14 X_lower,X_point,X_upper = fit.distribution.CDF(CI_type='time',CI_y=0.7)
15 plt.arrow(x=0,y=0.7,dx=X_upper,dy=0,color='red',head_width=arrow_y,head_length=arrow_x,length_includes_head=True)
16 plt.arrow(x=X_lower,y=0.7,dx=0,dy=-0.7,color='red',head_width=arrow_x,head_length=arrow_y,length_includes_head=True)
~\Anaconda3\envs\reliability_00\lib\site-packages\reliability\Distributions.py in CDF(self, xvals, xmin, xmax, show_plot, **kwargs)
479 limits = get_axes_limits() # get the previous axes limits
480
--> 481 p = plt.plot(X, cdf, **kwargs)
482 plt.xlabel("x values")
483 plt.ylabel("Fraction failing")
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\pyplot.py in plot(scalex, scaley, data, *args, **kwargs)
2840 return gca().plot(
2841 *args, scalex=scalex, scaley=scaley,
-> 2842 **({"data": data} if data is not None else {}), **kwargs)
2843
2844
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
1741 """
1742 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
-> 1743 lines = [*self._get_lines(*args, data=data, **kwargs)]
1744 for line in lines:
1745 self.add_line(line)
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_base.py in call(self, data, *args, **kwargs)
271 this += args[0],
272 args = args[1:]
--> 273 yield from self._plot_args(this, kwargs)
274
275 def get_next_color(self):
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_base.py in _plot_args(self, tup, kwargs)
417 raise ValueError(f"x has {ncx} columns but y has {ncy} columns")
418 return [func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
--> 419 for j in range(max(ncx, ncy))]
420
421
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_base.py in (.0)
417 raise ValueError(f"x has {ncx} columns but y has {ncy} columns")
418 return [func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
--> 419 for j in range(max(ncx, ncy))]
420
421
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_base.py in _makeline(self, x, y, kw, kwargs)
310 default_dict = self._getdefaults(set(), kw)
311 self._setdefaults(default_dict, kw)
--> 312 seg = mlines.Line2D(x, y, **kw)
313 return seg
314
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\lines.py in init(self, xdata, ydata, linewidth, linestyle, color, marker, markersize, markeredgewidth, markeredgecolor, markerfacecolor, markerfacecoloralt, fillstyle, antialiased, dash_capstyle, solid_capstyle, dash_joinstyle, solid_joinstyle, pickradius, drawstyle, markevery, **kwargs)
388 # update kwargs before updating data to give the caller a
389 # chance to init axes (and hence unit support)
--> 390 self.update(kwargs)
391 self.pickradius = pickradius
392 self.ind_offset = 0
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\artist.py in update(self, props)
994 func = getattr(self, f"set_{k}", None)
995 if not callable(func):
--> 996 raise AttributeError(f"{type(self).name!r} object "
997 f"has no property {k!r}")
998 ret.append(func(v))
AttributeError: 'Line2D' object has no property 'ci_y'`
Expected behavior
was expecting the first graph in the results which is below
Additional context
there are also multiple other errors which I came across similar to this one, I thought its because of the matplotlib may be, the version or something, searched around, there wasn't any solution and then found this to clarify. I can post those other issues too as separate ones later.
Describe the bug
When I try to replicate the result from example 2 in "Fitting all available distributions to data", error is prompted.
To Reproduce
code:
from reliability.Fitters import Fit_Everything
from reliability.Distributions import Weibull_Distribution
from reliability.Other_functions import make_right_censored_data
raw_data = Weibull_Distribution(alpha=12, beta=3).random_samples(100, seed=2) # create some data
data = make_right_censored_data(raw_data, threshold=14) # right censor the data
results = Fit_Everything(failures=data.failures, right_censored=data.right_censored) # fit all the models
print('The best fitting distribution was', results.best_distribution_name, 'which had parameters', results.best_distribution.parameters)
output:
Results from Fit_Everything:
Analysis method: MLE
Failures / Right censored: 86/14 (14.0% right censored)
Distribution Alpha Beta Gamma Alpha 1 Beta 1 Alpha 2 Beta 2 Proportion 1 DS Mu Sigma Lambda Log-likelihood AICc BIC AD optimizer
Weibull_2P 11.2773 3.30301 -241.959 488.041 493.128 44.945 TNC
Normal_2P 10.1194 3.37466 -242.479 489.082 494.169 44.9098 TNC
Gamma_2P 1.42301 7.21417 -243.235 490.594 495.68 45.2817 TNC
Loglogistic_2P 9.86245 4.48433 -243.588 491.301 496.387 45.2002 TNC
Weibull_DS 10.7383 3.57496 0.930423 -241.594 489.437 497.003 44.9447 TNC
Weibull_3P 10.0786 2.85821 1.15092 -241.779 489.807 497.373 44.9927 TNC
Weibull_Mixture 3.59763 113.23 11.4208 3.54075 0.0276899 -237.392 485.421 497.809 44.9283 TNC
Gamma_3P 1.42301 7.21417 0 -243.235 492.72 500.286 45.2817 L-BFGS-B
Lognormal_2P 2.26524 0.406436 -245.785 495.694 500.78 45.6874 TNC
Loglogistic_3P 9.86245 4.48433 0 -243.588 493.427 500.992 45.2002 TNC
Weibull_CR 11.4119 3.30302 30.253 3.30282 -241.959 492.338 502.338 44.945 TNC
Lognormal_3P 0 2.26524 0.406436 -245.785 497.82 505.385 45.6874 TNC
Gumbel_2P 11.5926 2.94944 -248.348 500.819 505.906 45.4624 L-BFGS-B
Exponential_2P 2.82892 0.121884 -267.003 538.129 543.216 51.7852 TNC
Exponential_1P 0.0870024 -295.996 594.034 596.598 56.8662 TNC
Traceback (most recent call last):
File "C:/Users/issac/iCloudDrive/Coding Projects/pythonProject/testing.py", line 7, in <module>
results = Fit_Everything(failures=data.failures, right_censored=data.right_censored) # fit all the models
File "C:\Users\issac\iCloudDrive\Coding Projects\pythonProject\venv\lib\site-packages\reliability\Fitters.py", line 1255, in __init__
Fit_Everything.__histogram_plot(self)
File "C:\Users\issac\iCloudDrive\Coding Projects\pythonProject\venv\lib\site-packages\reliability\Fitters.py", line 1497, in __histogram_plot
self.__Weibull_2P_params.distribution.CDF(CI=False, linestyle=ls)
File "C:\Users\issac\iCloudDrive\Coding Projects\pythonProject\venv\lib\site-packages\reliability\Distributions.py", line 508, in CDF
self, "CDF", xvals, xmin, xmax, show_plot, plot_CI, CI_type, CI, CI_y, CI_x
File "C:\Users\issac\iCloudDrive\Coding Projects\pythonProject\venv\lib\site-packages\reliability\Utils.py", line 7069, in distributions_input_checking
"CI must be between 0 and 1. Default is 0.95 for 95% confidence interval. Only used if the distribution object was created by Fitters."
ValueError: CI must be between 0 and 1. Default is 0.95 for 95% confidence interval. Only used if the distribution object was created by Fitters.
Process finished with exit code 1
Describe the bug
quantile() and inverse_SF() functions work fine with a single numeric input, but error out when provided an array or list
To Reproduce
from reliability.Distributions import Mixture_Model, Weibull_Distribution
one = Weibull_Distribution(alpha=0.04, beta=2.2)
two = Weibull_Distribution(alpha=0.18, beta=1.3)
p = 0.43
mixture = Mixture_Model([one, two], [p, 1-p] )
mixture.quantile([.1, .2])
Returns: ValueError: operands could not be broadcast together with shapes (1000000,) (2,)
Additional context
Here's an example of how I fixed it:
def quantile(self, q):
"""
Quantile calculator
Parameters
----------
q : float, list, array
Quantile to be calculated. Must be between 0 and 1.
Returns
-------
x : float
The inverse of the CDF at q. This is the probability that a random
variable from the distribution is < q
"""
if type(q) in [int, float, np.float64]:
if q < 0 or q > 1:
raise ValueError("Quantile must be between 0 and 1")
else:
q=[q]
elif type(q) in [list, np.ndarray]:
if min(q) < 0 or max(q) > 1:
raise ValueError("Quantile must be between 0 and 1")
else:
raise ValueError("Quantile must be of type float, list, array")
# ppf = self.__xvals_init[np.argmin(abs(self.__cdf_init - q))]
def mixture_ppf(q):
return self.__xvals_init[np.argmin(abs(self.__cdf_init - q))]
mixture_ppf_vec = np.vectorize(mixture_ppf)
ppf = mixture_ppf_vec(q)
return unpack_single_arrays(ppf)
In the tutorial there was only monte-carlo method to simulate the result:
tutorial link
However monte-carlo method might be slow , and the result may not be accurate. So I am wondering if numerical intergration method is available. Thanks for your help!
Describe the bug
A minor problem in 0.8.12
The parameter normed
in numpy.histogram
has been deprecated later than 1.23. So when I run the example code of Chi-squared test, Pycharm raises an "unexpected keyword argument 'normed'" error. Maybe this will happen in newer version of numpy. My version of numpy is 1.25.2 now and 1.24 before. Both wrong.
To Reproduce
The code you executed when you found the bug.
from reliability.Datasets import mileage
from reliability.Distributions import Normal_Distribution
from reliability.Reliability_testing import chi2test
import numpy as np
import matplotlib.pyplot as plt
data = mileage().failures
dist = Normal_Distribution(mu=30011, sigma=10472)
bins = [0, 13417, 18104, 22791, 27478, 32165, 36852, 41539, 46226, np.inf] #it is not necessary to specify the bins and leaving them unspecified is usually best
chi2test(distribution=dist, data=data, bins=bins)
plt.show()
The output that Python gave you.
File "D:\test.py", line 10, in <module>
chi2test(distribution=dist, data=data, bins=bins)
File "D:\Program Files\Python39\lib\site-packages\reliability\Reliability_testing.py", line 1016, in __init__
observed, bin_edges = np.histogram(
TypeError: histogram() got an unexpected keyword argument 'normed'
Expected behavior
normal result and plot.
Screenshots
none.
Additional context
none.
Confidence Interval
I have solved some examples using both Fit_Weibull_2P and Weibull++. While the point estimate is the same, the confidence intervals on probability plots are the same.
Describe the bug
Hi
Trying out the "weibull dist fit 2P - quantile specifications - finding the confidence bounds for the quantiles(Y values)" from the package
To Reproduce
`from reliability.Distributions import Weibull_Distribution
from reliability.Fitters import Fit_Weibull_2P
from reliability.Other_functions import crosshairs
import matplotlib.pyplot as plt
dist = Weibull_Distribution(alpha=500, beta=6)
data = dist.random_samples(50, seed=1) # generate some data
Fit_Weibull_2P(failures=data, quantiles=True, CI=0.8, show_probability_plot=False)
print('----------------------------------------------------------')
output = Fit_Weibull_2P(failures=data, quantiles=[0.05, 0.5, 0.95], CI=0.8)
crosshairs()
plt.show()
lower_estimates = output.quantiles['Lower Estimate'].values
print('Lower estimates:', lower_estimates)
#alternatively, the bounds can be extracted from the distribution object
lower,point,upper = output.distribution.CDF(CI_y=[0.05, 0.5, 0.95], CI=0.8)
print('Upper estimates:', upper)`
The output that Python gave you. -
`Results from Fit_Weibull_2P (80% CI):
Analysis method: Maximum Likelihood Estimation (MLE)
Failures / Right censored: 50/0 (0% right censored)
Parameter Point Estimate Standard Error Lower CI Upper CI
Alpha 489.117 13.9217 471.597 507.288
Beta 5.20799 0.58927 4.50501 6.02067
Goodness of fit Value
Log-likelihood -301.658
AICc 607.571
BIC 611.14
AD 0.482678
Results from Fit_Weibull_2P (80% CI):
Analysis method: Maximum Likelihood Estimation (MLE)
Failures / Right censored: 50/0 (0% right censored)
Parameter Point Estimate Standard Error Lower CI Upper CI
Alpha 489.117 13.9217 471.597 507.288
Beta 5.20799 0.58927 4.50501 6.02067
Goodness of fit Value
Log-likelihood -301.658
AICc 607.571
BIC 611.14
AD 0.482678
AttributeError Traceback (most recent call last)
in
10 print('----------------------------------------------------------')
11 # repeat the process but using specified quantiles.
---> 12 output = Fit_Weibull_2P(failures=data, quantiles=[0.05, 0.5, 0.95], CI=0.8)
13 # these points have been manually annotated on the plot using crosshairs
14 crosshairs()
~\Anaconda3\envs\reliability_00\lib\site-packages\reliability\Fitters.py in init(self, failures, right_censored, show_probability_plot, print_results, CI, percentiles, CI_type, method, optimizer, force_beta, **kwargs)
1794 CI=CI,
1795 CI_type=CI_type,
-> 1796 **kwargs,
1797 )
1798 self.probability_plot = plt.gca()
~\Anaconda3\envs\reliability_00\lib\site-packages\reliability\Probability_plotting.py in Weibull_probability_plot(failures, right_censored, fit_gamma, __fitted_dist_params, a, CI, CI_type, show_fitted_distribution, show_scatter_points, **kwargs)
361 plt.gcf().set_size_inches(9, 9)
362 if show_fitted_distribution is True:
--> 363 wbf.CDF(label=label, **kwargs)
364 plt.legend(loc="upper left")
365 plt.title("Probability plot\nWeibull CDF")
~\Anaconda3\envs\reliability_00\lib\site-packages\reliability\Distributions.py in CDF(self, xvals, xmin, xmax, show_plot, **kwargs)
479 limits = get_axes_limits() # get the previous axes limits
480
--> 481 p = plt.plot(X, cdf, **kwargs)
482 plt.xlabel("x values")
483 plt.ylabel("Fraction failing")
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\pyplot.py in plot(scalex, scaley, data, *args, **kwargs)
2840 return gca().plot(
2841 *args, scalex=scalex, scaley=scaley,
-> 2842 **({"data": data} if data is not None else {}), **kwargs)
2843
2844
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
1741 """
1742 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
-> 1743 lines = [*self._get_lines(*args, data=data, **kwargs)]
1744 for line in lines:
1745 self.add_line(line)
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_base.py in call(self, data, *args, **kwargs)
271 this += args[0],
272 args = args[1:]
--> 273 yield from self._plot_args(this, kwargs)
274
275 def get_next_color(self):
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_base.py in _plot_args(self, tup, kwargs)
417 raise ValueError(f"x has {ncx} columns but y has {ncy} columns")
418 return [func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
--> 419 for j in range(max(ncx, ncy))]
420
421
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_base.py in (.0)
417 raise ValueError(f"x has {ncx} columns but y has {ncy} columns")
418 return [func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
--> 419 for j in range(max(ncx, ncy))]
420
421
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\axes_base.py in _makeline(self, x, y, kw, kwargs)
310 default_dict = self._getdefaults(set(), kw)
311 self._setdefaults(default_dict, kw)
--> 312 seg = mlines.Line2D(x, y, **kw)
313 return seg
314
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\lines.py in init(self, xdata, ydata, linewidth, linestyle, color, marker, markersize, markeredgewidth, markeredgecolor, markerfacecolor, markerfacecoloralt, fillstyle, antialiased, dash_capstyle, solid_capstyle, dash_joinstyle, solid_joinstyle, pickradius, drawstyle, markevery, **kwargs)
388 # update kwargs before updating data to give the caller a
389 # chance to init axes (and hence unit support)
--> 390 self.update(kwargs)
391 self.pickradius = pickradius
392 self.ind_offset = 0
~\Anaconda3\envs\reliability_00\lib\site-packages\matplotlib\artist.py in update(self, props)
994 func = getattr(self, f"set_{k}", None)
995 if not callable(func):
--> 996 raise AttributeError(f"{type(self).name!r} object "
997 f"has no property {k!r}")
998 ret.append(func(v))
AttributeError: 'Line2D' object has no property 'quantiles'`
Expected behavior
expected to reproduce whatever results you've given in that section of the package Doc.
I am running the library on Windows 10 (and 11) and I get an attribute error when I import the library (both on float128 and complex256. Is there a workaround for this? (other than changing the code in the library)
Thanks
Describe the bug
Reliability==0.8.9 gives while running an example:
"ALT_fitters.py IndexError: list index out of range"
Reliability==0.8.8 does not have this problem.
Additionally, there is no requirements.txt for Reliability==0.8.9
To Reproduce
Install reliability==0.8.9 instead of 0.8.8.
The code you executed when you found the bug:
Fitting a dual stress model to ALT data - Example 2
Taken from: ReadTheDocs
The output that Python gave you:
/usr/local/lib/python3.10/dist-packages/reliability/Utils.py:2263: FutureWarning: In a future version of pandas, a length 1 tuple will be returned when iterating over a groupby with a grouper equal to a list of length 1. Don't supply a list with a single grouper to avoid this warning.
for key, items in failure_df_ungrouped.groupby(["failure_stress_pairs"]):
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-3-ae39736ff8e9> in <cell line: 8>()
6 import matplotlib.pyplot as plt
7 data = ALT_temperature_voltage()
----> 8 Fit_Normal_Dual_Exponential(failures=data.failures, failure_stress_1=data.failure_stress_temp, failure_stress_2=data.failure_stress_voltage,use_level_stress=[330,2.5])
9 plt.show()
/usr/local/lib/python3.10/dist-packages/reliability/ALT_fitters.py in __init__(self, failures, failure_stress_1, failure_stress_2, right_censored, right_censored_stress_1, right_censored_stress_2, use_level_stress, CI, optimizer, show_probability_plot, show_life_stress_plot, print_results)
10374 stresses_for_groups_str = []
10375 for stress in stresses_for_groups:
> 10376 new_mus.append(life_func(S1=stress[0], S2=stress[1]))
10377 stresses_for_groups_str.append(
10378 str(
Expected behavior
Some statistics and 2 plots
Additional context
Here are the Google colabs for debugging:
[0.8.9] https://colab.research.google.com/drive/1B7xXzEtTX5Y6LsmZKpBQT0hYr0zC64JM?usp=sharing
[0.8.8] https://colab.research.google.com/drive/1is2SU4TEaXuaaYL6TeF1z9JreMR2AZbP?usp=sharing
There is no requirements.txt for 0.8.9., it still says 0.8.8
Thank you for making this software package. Greetings from another AE.
Hi,
I am using the package to model some failure data for research purposes. I had success with all the modules and they are working great. Except for the Reliability_testing that is returning that its functions are not defined. I tried using both KStest and chi2test and jupyter notebook returns that they are not defined. Also, I looked at the original code, I was able to follow the steps but couldn't tell where is this error coming from. I tried reinstalling the package to fix any error in the previous installation but it didn't work.
Here is a print of the error. All distributions were imported when I ran this piece of code. And the distribution that I used as input was generated with the parameters I found using the Fitter module.
Thanks!
Pedro
This repository has 3 different tags: Setup.py indicates this lib is in version v0.5.4, while github releases has v0.5.1 and PyPi inidicates v0.5.3. Could you update all of those to v0.5.4?
QQ_plot_semiparametric function
It seems QQ_plot_semiparametric requires a parameter called show_scatter_points but this parameter is not defined as input nor created by the code.
To Reproduce
I used example 2 in the manual. Please see the following link: https://reliability.readthedocs.io/en/latest/Quantile-Quantile%20plots.html
'''
from reliability.Probability_plotting import QQ_plot_semiparametric
from reliability.Fitters import Fit_Weibull_2P
from reliability.Distributions import Normal_Distribution
import matplotlib.pyplot as plt
data = Normal_Distribution(mu=50,sigma=12).random_samples(100)
fitted_dist = Fit_Weibull_2P(failures=data,print_results=False,show_probability_plot=False).distribution
QQ_plot_semiparametric(X_data_failures=data,Y_dist=fitted_dist)
plt.show()
'''
The output that Python:
'''
NameError Traceback (most recent call last)
/var/folders/7z/t6b_hwcn3gbfzcmkncysr1dc0000gp/T/ipykernel_57176/446703307.py in
5 data = Normal_Distribution(mu=50,sigma=12).random_samples(100)
6 fitted_dist = Fit_Weibull_2P(failures=data,print_results=False,show_probability_plot=False).distribution
----> 7 QQ_plot_semiparametric(X_data_failures=data,Y_dist=fitted_dist)
8 plt.show()
~/opt/anaconda3/envs/formula2/lib/python3.9/site-packages/reliability/Probability_plotting.py in QQ_plot_semiparametric(X_data_failures, X_data_right_censored, Y_dist, show_fitted_lines, show_diagonal_line, method, downsample_scatterplot, **kwargs)
2647 dist_Y_ISF[dist_Y_ISF == -np.inf] = 0
2648
-> 2649 if show_scatter_points is True:
2650 x_scatter, y_scatter = xy_downsample(
2651 X_data_failures, dist_Y_ISF, downsample_factor=downsample_scatterplot
NameError: name 'show_scatter_points' is not defined
'''
Additional context
Later, I tried example one in the manual on the same page, and I ran into the same error.
Hello,
The scipy.quad function used to calculate the probability of failures miss to compute the interference area.
I have the following code :
stress = Lognormal_Distribution(mu=9.826147748745854,sigma=0.16739388240778247)
strength = Normal_Distribution(mu=189000,sigma=34020)
result = Probability_of_failure(stress=stress, strength=strength, show_distribution_plot=False)
Probability of failure: 1.550966899579015e-77
But when I manually use np.trapz a have :
x=np.arange(0,300e3,10)
interf = stress.PDF(x, show_plot=False) * strength.CDF(x, show_plot=False)
np.trapz(interf,x)
3.171812771218649e-07
I suspect the quad function to evaluate the interval 0 to 1 only on some point and miss the interference.
May be the range of the data I use have an impact on this effect. I don't know. May be I'm wrong.
Can you enlighten this behavior ?
Thank you.
Describe the bug
The lognormal distribution sampling does not return correct values
To Reproduce
I am using reliability.Distributions.Lognormal_Distribution.
Here is my sample code:
from reliability.Distributions import Lognormal_Distribution
a = Lognormal_Distribution(100, 1)
a.random_samples(5)
And here is the output generated.
array([4.48320782e+43, 5.89008499e+42, 6.96988040e+42, 1.80227737e+43, 1.65202491e+43])
Expected behavior
It's expected to produce correct sample values.
My Thanks to the author
I've used your package for the reliability chapter of my master's thesis, and it help me a lot. I hope you can fix this small issue, thankyou!
Describe the bug
Most of the code running the accelerated life experiment module will fail, for example numpy will not use round
To Reproduce
from reliability.ALT_fitters import Fit_Weibull_Power
from reliability.Datasets import ALT_load2
import matplotlib.pyplot as plt
Fit_Weibull_Power(failures=ALT_load2().failures, failure_stress=ALT_load2().failure_stresses,
right_censored=ALT_load2().right_censored, right_censored_stress=ALT_load2().right_censored_stresses,
use_level_stress=60)
plt.show()
Expected behavior
Output the fit parameters and two graphs, as shown in the example in the documentation
Additional context
Similar problems exist with functions related to accelerated life experiments
I observed an error in Probability_plotting.py
. For large failure times in Lognormal_probability_plot
, such as samples from Lognormal_Distribution(50, 10)
, the calculation of xvals
(line 484) raises a TypeError
from np.log10
. This occurs when xmax_log > 10**20
approximately, and of type int
. Conversion to int
type occurs in line 480, and appears to be unneeded, because 10**x
works if x
is a float
. Removing the int
conversion resolves the error.
This error also occurs in line 550, setting the plotting limits, due to the int
conversion in line 549. Removing the int
conversion resolves the error.
Side note: in line 479 and 480, the values of the variables xmin_log
and xmax_log
are powers of 10. When those values are used in line 484, the logarithm of each is used. That is, the code is performing the calculation np.log10(10 ** x)
.
It would be convenient to be able to generate probability plots from a fitted distribution after the fitting has been done once. My specific use case is after using Fit_Everything
. Here's some code that kind of works:
from reliability import Probability_plotting
from reliability.Fitters import Fit_Everything
fe = Fit_Everything(x)
best = fe.best_distribution
plotter = getattr(Probability_plotting, f'{best.name}_probability_plot')
plotter(failures=x)
Not only does that redo the fitting, but it also doesn't work if Fit_Everything
winds up choosing a Weibull_3P
though because we have no way to know to pass fit_gamma=True
to the plotting function without using name2
and a bunch of if
s.
Here's what a possible implementation could look like:
from reliability.Fitters import Fit_Everything
fe = Fit_Everything(x)
best = fe.best_distribution
best.probplot(failures=x)
Describe the bug
Mixture_Model is not an allowable input type for stress and strength - It would be helpful to add it
Loglogistic_Distribution when Beta < 1 raises TypeError
To Reproduce
from reliability.Other_functions import stress_strength
from reliability.Distributions import Loglogistic_Distribution
stress = Loglogistic_Distribution(alpha=20,beta=0.9)
strength = Loglogistic_Distribution(alpha=20,beta=0.9)
stress_strength(stress=stress, strength=strength, warn=False)
TypeError: '>' not supported between instances of 'float' and 'str'
due to the Loglogistic mean definition:
if self.beta > 1:
self.mean = float(
ss.fisk.stats(self.beta, scale=self.alpha, loc=self.gamma, moments="m")
)
else:
self.mean = r"no mean when $\beta \leq 1$"
easiest fix might be to nest the "if stress.mean > strength.mean" inside of "if warn == True:" to allow suppressing the warning/error... or more specific error handling for this specific case.
For the Mixture_Model:
from reliability.Fitters import Fit_Weibull_Mixture
from reliability.Other_functions import stress_strength
from reliability.Distributions import Weibull_Distribution
stress = Weibull_Distribution(alpha=2,beta=3,gamma=1)
strength = Fit_Weibull_Mixture([1,2,3,4], show_probability_plot=False, print_results=False).distribution
stress_strength(stress=stress, strength=strength)
ValueError: Stress and Strength must both be probability distributions. First define the distribution using reliability.Distributions.___
if I add the Mixture_Model to the stress_strength function, then it works fine except for plot and print_results, which returns:
AttributeError: 'Mixture_Model' object has no attribute 'param_title_long'
Could add a generic param_title_long ( 'Mixture_Model') to the Mixture_Model class to be able to use these, otherwise I'm fine with turning plot and print off for now...
Thanks for bringing us Reliability!
Fit_Everything returns mixtures and competing risks despite the documentation stating "This function will fit all available distributions (excluding mixture and competing risks) to the data provided". Did I miss anything?
I tried excluding them, but it seems competing risks are not on the list of excludables.
Thanks for your insights.
Hi , thanks the development of the package . we use the package for study where we need to change the axis legends from time to Kilometer since our data is life estimation over Kilometer.
also we are trying to integrate with the streamlit application, can you please provide the code for MCF calculation to plot graph.
can you please provide the raw data into a storable object.
Describe the bug
When using force_beta
with RRX
in Fit_Weibull_2P
, Beta
returns the inverse of force_beta
.
To Reproduce
from reliability.Fitters import Fit_Weibull_2P
Fit_Weibull_2P(failures=[3600, 4000, 2500, 4800, 5500], method='RRX', force_beta=3)
Python Output:
Results from Fit_Weibull_2P (95% CI):
Analysis method: Least Squares Estimation (RRX)
Failures / Right censored: 5/0 (0% right censored)
Parameter Point Estimate Standard Error Lower CI Upper CI
Alpha 17185 4585.27 10186.7 28991.2
Beta 0.333333 0 0.333333 0.333333
Goodness of fit Value
Log-likelihood -58.072
AICc 119.477
BIC 117.753
AD 3.07411
Describe the bug
Parameters alpha
, beta
, gamma
returned by Fit_Gamma_3P
are not the same of Gamma_Distribution
?
Are maybe alpha
and beta
swapped?
To Reproduce
# imports
import numpy as np
from reliability.Fitters import Fit_Everything
from reliability.Distributions import Gamma_Distribution
import matplotlib.pyplot as plt
# dummy dataset
data = np.array([ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
2.5, 2.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
3.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5,
4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5,
4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5,
4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5,
4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5,
4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5,
4.5, 4.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5,
5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5,
5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5,
5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5,
5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 6.5, 6.5, 6.5,
6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5,
6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 7.5, 7.5, 7.5, 7.5, 7.5,
7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5,
7.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5,
8.5, 8.5, 8.5, 8.5, 8.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5,
9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 10.5, 10.5, 10.5, 10.5,
10.5, 10.5, 10.5, 10.5, 11.5, 11.5, 11.5, 11.5, 11.5, 12.5, 12.5,
12.5, 12.5, 12.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5,
13.5, 13.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 15.5, 15.5,
15.5, 15.5, 15.5, 15.5, 15.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5])
# plot dataset histogram
plt.hist(data, bins=17);
# Fitting with Fit_Everything gives Gamma_3P as best distribution
results = Fit_Everything(data)
# get alpha, beta, gamma parameters from Gamma_3P
results.results.iloc[0]
Distribution Gamma_3P
Alpha 7.65975
Beta 0.570525
Gamma 0.4999
Log-likelihood -1107.83
AICc 2221.71
BIC 2234.14
AD 46.2631
optimizer TNC
# create and plot distribution from estimated parameters
gamma_3P = Gamma_Distribution(
alpha=results.results.iloc[0].Alpha,
beta=results.results.iloc[0].Beta,
gamma=results.results.iloc[0].Gamma,
)
gamma_3P.PDF(xmax=18)
plt.hist(data, bins=18, density=True);
# swapping alpha and beta...
gamma_3P = Gamma_Distribution(
alpha=results.results.iloc[0].Beta,
beta=results.results.iloc[0].Alpha,
gamma=results.results.iloc[0].Gamma,
)
gamma_3P.PDF(xmax=18)
plt.hist(data, bins=18, density=True);
Hello, I'm new to Bug reporting... let me know if the report is not the way it should be. Cheers!
Description:
Lognormal_distribution.CDF returns:
(array(([1, 2, 3, ...]), (array([1, 2, 3, ...]),), array([1, 2, 3, ...])) but should return
(array(([1, 2, 3, ...]), (array([1, 2, 3, ...] ), array([1, 2, 3, ...]))
^
To Reproduce:
Call Lognormal_distribution.CDF function with CI and CI_x values.
In Distribution.py line 2471
cdf_point = (
ss.lognorm.cdf(CI_x, self.sigma, self.gamma, np.exp(self.mu)),
)
should be
cdf_point = ss.lognorm.cdf(CI_x, self.sigma, self.gamma, np.exp(self.mu))
(As is the case e.g., in Normal_Distribution.CDF)
The Mixture_Model raises ValueError("the sum of the proportions must be 1") even when the proportions sum is equal to 1.
For exemple :
ls =[]
for i in range(0, 10):
ls.append(Distributions.Lognormal_Distribution(mu=2, sigma=0.8))
mixture_model = Distributions.Mixture_Model(distributions=ls, proportions=np.full(10, 0.1))
Is the functionality of calculating mean time to fail (MTTF) available?
I intend to work towards the same if that is not available
First of all, congratulations on the awesome work! Up until now I've been using Matlab for similar things, but thanks to this package I've been able to do stuff more easily now!
I'm not sure if this is a bug or a misunderstanding on my part on how the three-parameter Weibull is fitted, but I am getting some strange results with a low number of samples. Here's a minimal working example:
from reliability.Fitters import Fit_Weibull_3P
fit = Fit_Weibull_3P(failures=[500, 600, 700, 800])
I am under the impression that each data point on the plot should be located similarly to how things work with Fit_Weibull_2P()
: each point placed at the failure time, i.e. at 500, 600, 700 and 800 on the horizontal axis in the example above. The first point is, however, located at 1e-4, and this seems to happen whenever there are four or five items in the failures
list. The following points are not located at the values specified by the failures
list either.
Is this a bug or a misunderstanding on my part?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.