La distribution de Weibull et les données dans la même figure (avec numpy et scipy) [fermé]

Voici mes données: https://www.dropbox.com/s/xx02015pbr484es/Book2.xlsx

C'est ma sortie: enter image description here

Et c'est la sortie désirée: enter image description here

comme vous pouvez le voir,je veux" les données "et la" distribution de Weibull " ensemble, (dans la même figure).

C'est mon code:

(loc, scale) = s.exponweib.fit_loc_scale(mydata, 0.5, 0.5)
print loc, scale
x = np.linspace(mydata.min(), mydata.max(), 1000)
plt.plot(mydata, weib(mydata, loc, scale))
plt.hist(mydata, mydata.max(), normed=True)
plt.show()
0
demandé sur Andre Silva 2013-11-24 08:22:08

1 réponses

tout d'abord, je pense que vous voulez corriger location mais pas scale . (Ainsi scale et shape peuvent changer). Deuxièmement, je pense (pas sûr à 100%) que vous ne pouvez pas avoir 0 dans vos données pour Weibull (sauf si vous codez une classe Weibull vous-même), donc j'ai changé votre 0 à une petite valeur 1e-8 .

>>> xdata=array([1e-8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,5,4,4,5,5,6,6,6,6,7,7,8,8,8,9,9,10,11,12,13,13,14,14,13,17,14,15,17,18,18,19,22,23,22,23,24,26,28,32,33,32,31,33,34,37,36,40,40,41,44,41,44,45,47,52,53,51,52,52,53,55,56,59,61,62,65,63,68,69,80,71,71,72,71,69,70,70,71,72,73,75,74,74,75,76,74,79,77,77,77,84,92,88,79,81,81,83,84,88,87,84,84,85,85,85,94,95,91,89,90,87,89,89,90,93,92,93,96,95,98,99,100,99,100,98,94,89,87,86,85,85,84,85,83,83,84,83,81,85,83,83,81,84,93,91,78,79,80,80,80,80,80,78,79,78,79,80,78,78,78,78,79,77,77,77,78,80,82,83,82,80,82,82,83,87,82,82,80,80,79,77,77,77,77,75,75,73,71,73,73,70,72,69,70,70,78,81,69,68,68,68,65,64,66,65,64,62,62,62,62,67,65,61,61,59,58,59,59,59,59,59,59,59,59,59,59,59,58,56,55,52,50,50,48,48,47,46,46,45,44,44,43,43,43,41,41,41,46,47,40,39,39,38,37,37,38,36,35,35,35,35,36,35,33,33,32,31,31,31,29,29,28,28,28,28,30,30,30,28,27,26,25,23,22,23,22,21,20,19,19,18,18,18,17,17,17,14,14,13,13,14,13,12,12,11,11,10,10,9,9,9,8,8,8,8,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2])
>>> stats.exponweib.fit(xdata, floc=0, f0=1)
(1, 0.87120924706137459, 0, 35.884593247790207)
>>> stats.weibull_min.fit(xdata, floc=0)
(0.87120924706137459, 0, 35.884593247790036)
>>> p0, p1, p2=stats.weibull_min.fit(xdata, floc=0)
>>> ydata=stats.weibull_min.pdf(linspace(0, 120, 100), p0, p1, p2)
>>> plt.hist(xdata, 25, normed=True)
>>> plt.plot(linspace(0, 120, 100), ydata, '-')

enter image description here

L'ajustement est fait corriger. Il semble laid mais il est dû une grande partie de vos données est petit.

enfin, je soupçonne que vos données originales sont déjà des données de fréquence et non des données brutes, est-ce le cas? (Supposons que vos données ne soient pas censurées par intervalle, ce qui nécessitera un peu de hardcode)

>>> import itertools
>>> x2data=list(itertools.chain(*[[i,]*val for i, val in enumerate(xdata)]))
>>> p0, p1, p2=stats.weibull_min.fit(x2data, floc=0)
>>> y2data=stats.weibull_min.pdf(linspace(0, 500, 100), p0, p1, p2)
>>> plt.plot(linspace(0, 500, 100), y2data, '-')
[<matplotlib.lines.Line2D object at 0x0360B6B0>]
>>> r1,r2,r3=plt.hist(x2data, bins=60, normed=True)

enter image description here Maintenant, le résultat semble beaucoup plus raisonnable. Bien qu'il ne semble pas encore être très distribué Weibull. Plus comme http://en.wikipedia.org/wiki/Shifted_Gompertz_distribution .

mise à Jour: oui, si vous avez 0 dans vos données, vous serez quand vous appelez fit méthodes ( scipy 0.12.0):

Warning (from warnings module):
  File "C:\Python27\lib\site-packages\scipy\optimize\optimize.py", line 438
     and numpy.max(numpy.abs(fsim[0] - fsim[1:])) <= ftol):
RuntimeWarning: invalid value encountered in subtract
2
répondu CT Zhu 2013-11-24 17:22:17