I've been trying to fit a Weibull distribution with stats.exponweib.fit - there is not a fit in Scipy for just Weibull, so, one needs to utilize the fit for exponential Weibull and set the first shape parameter to 1. However, when the stats.exponweib.fit function is fed with data from a Weibull distribution with known shape parameters - the fit returns a different set of shape parameters. Some example code to display this behavior would be:
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)
The output here is:
(1, 2.8146777019890856, 0, 1.4974049126907345)
I would have expected:
(1, 5.0, 0, 1.0)
When we plot the curves:
# 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()
We get the following curves showing the input data from a known Weibull distribution with shape factors k=5 and lambda=1 and output from the exponweib.fit with different shape factors.
Input Weibull data and output from exponweib.fit
First post on stackoverflow - so, hopefully the above is the right way to frame a question. Welcome any ideas on the above and any pointers on posting :)