Giter Site home page Giter Site logo

matthewreid854 / reliability Goto Github PK

View Code? Open in Web Editor NEW
304.0 19.0 69.0 25.36 MB

Reliability engineering toolkit for Python - https://reliability.readthedocs.io/en/latest/

License: GNU Lesser General Public License v3.0

Python 100.00%
python statistics modeling simulation data-science maximum-likelihood-estimation weibull-analysis reliability-engineering survival-analysis

reliability's People

Contributors

matthewreid854 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reliability's Issues

RankAdjustment

Hi,

I think there is an issue with RankAdjustment.
It forgets sorting the data before calculating the Rank Adjustment Estimates.
RankAdjustment

Kind regards,
Tom

How to use reliability package to answer if test time can be reduced or should be augmented

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
image

image

Was trying to use:

from reliability.Fitters import Fit_Weibull_Mixture
fit = Fit_Weibull_Mixture(failures=failures,show_probability_plot=True,print_results=True)

image

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:

  1. What could be the steady point in test time where the failure rate became constant?
    1. This point could be less than actual test time or could be bigger than actual test time
    2. Assume here the hazard function could be of help?
  2. If I cut test time and having reliability of 80%, then could I should be able to know how many failures am going to stop detecting?

Appreciate reference material to read on this topic as well.

image

[BUG] - Stress - Strength Interference Erroneous Result

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 %

image

Expected behavior
Probability of failure should be ~44%
image

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')

image

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)

Stress - Strength fill regions reversed:
image

Should be:
image

[BUG] - Problem with matplotlib-3.7.0

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()

plot0

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()

plot1

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

Extract confidence bounds

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 ?

FitEverything example error

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']

Better estimation of gamma parameter for location shifted distributions

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.

Fit_Weibull_2P_grouped show_probability_plot issue

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.

[BUG] - Quite different results to lifelines with real data

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.

Random Sampling with numpy.random instead of scipy.stats

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.

Fit a three parameter reversed Weibull distribution.

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?

image

[BUG] - AttributeError: 'Line2D' object has no property 'ci_y'

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

Screenshots
image

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.

[BUG] - Cannot replicate the results from example - Fitting all available distributions to data

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


[BUG] - Complex Distributions (Mixture, Competing Risks, DSZI) quantile and inverse_SF functions error when input is array-like

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:

  • if q is a number, convert to list to avoid unpack_single_arrays() error
  • Vectorize the ppf function
    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)

[BUG] - A minor problem in Reliability_testing.chi2test related to numpy.histogram

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.

[BUG] - description here

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.

[BUG] - AttributeError: 'Line2D' object has no property 'quantiles'

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

this will produce the large table of quantiles below the first table of results

Fit_Weibull_2P(failures=data, quantiles=True, CI=0.8, show_probability_plot=False)
print('----------------------------------------------------------')

repeat the process but using specified quantiles.

output = Fit_Weibull_2P(failures=data, quantiles=[0.05, 0.5, 0.95], CI=0.8)

these points have been manually annotated on the plot using crosshairs

crosshairs()
plt.show()

the values from the quantiles dataframe can be extracted using pandas:

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'`

image

Expected behavior
expected to reproduce whatever results you've given in that section of the package Doc.

[BUG] - float128 and complex256

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

[BUG] - ALT_fitters.py IndexError: list index out of range

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:

  1. Fitting a dual stress model to ALT data - Example 1
    Taken from: ReadTheDocs

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

  1. 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

  2. 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.

Reliability_testing returns that its functions are not defined

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.

image

Thanks!
Pedro

[BUG] - description here

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.

Possible issue with the quad function for interference calculation

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.

[BUG] - Lognormal_Distribution.random_samples give wrong values

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!

BUG about accelerated life experiment module

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

Screenshots
image

Additional context
Similar problems exist with functions related to accelerated life experiments

Lognormal_probability_plot fails for sufficiently large failure times

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).

Make probability plots accessible from distribution objects?

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 ifs.

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)

[BUG] - Stress-Strength Mixture_Model and Loglogistic errors

Describe the bug

  1. Mixture_Model is not an allowable input type for stress and strength - It would be helpful to add it

  2. 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...

Fit_Everything unexpectedly returns mixtures and competing risks

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.

MCF Parametric graph feature addition like legends and titles on axis

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.

[BUG] - force_beta is inversed when using RRX in Fit_Weibull_2P

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 

image

[BUG] - parameters alpha, beta, gamma returned in Fit_Gamma_3P are not the same of Gamma_Distribution?

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);

gamma_hist

# 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);

gamma_error

# 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);

gamma_boh

Lognormal_Distribution.CDF does not return tuple

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)

[BUG] - Proportions sum to 1 Mixture_model

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))

Strage results from `Fit_Weibull_3P`

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.

Output from the code above:
Screenshot 2021-12-17 at 15 03 34

Is this a bug or a misunderstanding on my part?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.