Подгонка распределения Вейбулла в Python с помощью stats.exponweib.fit

Я пытался подогнать распределение Вейбулла с помощью stats.exponweib.fit - в Scipy не подходит только для Weibull, поэтому нужно использовать подгонку для экспоненциального Вейбулла и установить первый параметр формы равным 1. Однако когда в функцию stats.exponweib.fit загружаются данные из распределения Вейбулла с известными параметрами формы - подгонка возвращает другой набор параметров формы. Вот пример кода для отображения этого поведения:

from numpy import random, exp, log
import matplotlib.pyplot as plt
from scipy import stats
import csv

# Expoential Weibull PDF 
def expweibPDF(x, k, lam, alpha):
    return (alpha * (k/lam) *
            ((x/lam)**(k-1))  *
            ((1 - exp(-(x/lam)**k))**(alpha-1)) *
            exp(-(x/lam)**k))

# Expoential Weibull CDF
def exp_cdf(x, k, lam, alpha):
    return (1 - exp(-(x / lam)**k))**alpha

# Expoential Weibull Inverse CDF
def exp_inv_cdf(p, k, lam, alpha):
    return lam * ( - log( (1 - p)**(1/alpha) ))**(1/k)

# parameters for the fit - alpha = 1.0 reduces to normal Webull
# the shape parameters k = 5.0 and lam = 1.0 are demonstrated on Wikipedia:
# https://en.wikipedia.org/wiki/Weibull_distribution

alpha = 1.0
k0 = 5.0
lam0 = 1.0
x = []
y = []

# create a Weibull distribution
random.seed(123)
n = 1000  
for i in range(1,n) :
    p = random.random()
    x0 = exp_inv_cdf(p,k0,lam0,alpha)
    x += [ x0 ]
    y += [ expweibPDF(x0,k0,lam0,alpha) ]


# now fit the Weibull using python library
# setting f0=1 should set alpha = 1.0
# so, shape parameters should be the k0 = 5.0 and lam = 1.0

(exp1, k1, loc1, lam1)  = stats.exponweib.fit(y,floc=0, f0=1)

print (exp1, k1, loc1, lam1)

Вот результат:

(1, 2.8146777019890856, 0, 1.4974049126907345)

Я ожидал:

(1, 5.0, 0, 1.0)

Когда мы строим кривые:

# plotting the two curves
fig, ax = plt.subplots(2, 1)
ax[0].plot(x,y, 'ro', lw=2)
ax[1].plot(x,stats.exponweib.pdf(x,exp1,k1,loc1,lam1), 'ro', lw=2)
plt.show()

Мы получаем следующие кривые, показывающие входные данные из известного распределения Вейбулла с коэффициентами формы k = 5 и лямбда = 1 и выходные данные из exponweib.fit с различными коэффициентами формы.

Ввод данных Weibull и вывод из exponweib.fit

Первый пост о stackoverflow - так что, надеюсь, изложенное выше - правильный способ задать вопрос. Приветствуем любые идеи по вышеизложенному и любые указатели на публикацию :)


person TurboToad    schedule 23.02.2016    source источник
comment
Проверьте ответ на этот (повторяющийся?) Вопрос: Как чтобы подогнать распределение Вейбулла к данным с помощью Python. В вашем случае ваша переменная x содержит случайную выборку значений из исходного распределения, поэтому это то, что вы должны передать в stats.exponweib.fit   -  person Pablo Arnalte-Mur    schedule 23.02.2016
comment
Спасибо Пабло за быстрый ответ. Совершенно верно - я вставлял PDF вместо образцов. И да, аналогичная проблема рассматривается в предыдущем вопросе: Как подогнать распределение Вейбулла к данным с помощью Python   -  person TurboToad    schedule 23.02.2016
comment
Возможный дубликат Как согласовать распределение Вейбулла с данными, используя питон?   -  person Him    schedule 08.08.2018


Ответы (2)


В своем блокноте я попробовал WeibullMaxFactory из OpenTURNS, чтобы установить дистрибутив Weibull на вашем x

import openturns as ot
from openturns.viewer import View
sample = ot.Sample(x, 1) # formats your x into a 'Sample' of dimension = 1
distribution = ot.WeibullMaxFactory().build(sample) # fits a Weibull to your data 
graph = distribution.drawPDF() # build the PDF
graph.setLegends(['Weibull'])
View(graph)

введите описание изображения здесь

Чтобы получить параметры Вейбулла:

print(distribution)
>>> WeibullMax(beta = 0.618739, alpha = 2.85518, gamma = 1.48269)
person Jean A.    schedule 28.10.2020

Scipy предлагает стандартный дистрибутив Weibull, который вы найдете в Википедии. Для этого вам следует использовать функцию scipy.stats. weibull_min

Реализация Weibull в Scipy может немного сбивать с толку, а ее способность соответствовать трехпараметрическому распределению Вейбулла иногда дает дикие результаты. Вы также не можете разместить цензурированные данные с помощью Scipy. Предлагаю вам ознакомиться с Библиотека надежности Python, которая делает процесс создания, подгонки и использования распределений вероятностей довольно простым по сравнению с Scipy.

person Matthew Reid    schedule 04.11.2020