Laitan tähän joitain parannusehdotuksia.
Ominaisuudet
Tällä hetkellä jako näyttäisi siltä että koodi
- Tekee "hill-plotin"
- Simuloi stokastista suppenemista
- Simuloi jakaumasuppenemista
- Plottaa tuloksia
Ehdotan että lähtisit mielummin liikkeelle tällaisella jaolla:
- Simuloi hill-estimaattorin arvoja
- Plottaa simuloidut arvot
Tuosta ensimmäisestä pointista voisi sitten varsin helposti saada nuo molemmat suppenemismoodit tarkasteltua. Hill-plot sisältyisi mahdollisesti tuohon jälkimmäiseen. Lähde siitä että toteuta skripti mikä vain tuottaa Hill estimaattorin arvoja näiden
vakioiden määrämällä tavalla ja sylkee tuotetut arvot vaikka vaan csv-tiedostoon. Katsotaan tuota plottailua sitten kun se generointijuttu toimii solidisti.
Modulaarisuus (ei tärkeä tässä vaiheessa)
Tällä hetkellä skriptiin on rakennettu sisään kaikenlaista toiminnallisuutta mikä kyllä liittyy läheisesti siihen mikä meitä kiinnostaa. Tämä pitäisi nyt kuitenkin organisoida siten, että skriptin eri vaiheita voisi käyttää toisistaan riippumatta.
Pari esimerkkiä: Tässä vissiin tehdään "hill plot"
|
#Creating everithing necessary for the hill plot. |
|
est = np.array([]) |
|
|
|
K = np.arange(1,int(n/3)) |
|
|
|
# Estimates for different values for k. |
|
for k in K: |
|
est=np.append(est, hill(k, X)) |
|
|
|
|
|
# Line y=b represents the true value for tail index |
|
B = b*np.ones(K.shape) |
toisaalta tässä
|
nest = np.array([]) |
|
nvec = np.arange(10, n+1) |
|
|
|
for i in nvec: |
|
nest = np.append(nest, hill(kf(i), pareto.rvs(b, size=i))) |
tarkastellaan estimaattorin asymptoottisia ominaiisuuksia. Nämä ovat selkeästi erillisiä juttuja emmekä välttämättä halua aina tehdä molempia. Loppuvaiheessa haluamme että simulointia ja plottailua pystyy tekemään erikseen, mikä onnistuu varsin helposti
argparse-kirjastolla.
Funktio hill
|
def hill(k, data): |
|
|
|
|
|
# Data is sorted into descending order. |
|
sorted_data = np.sort(data)[::-1] |
|
# k largest elements. |
|
kdata = sorted_data[:k] |
|
# Elementwise natural logarithm. |
|
logdata = np.log(kdata) |
|
# The smallest element is subtracted from every element of this list. |
|
sumdata = logdata - logdata[-1] |
|
# Sum of elements and normalize with 1/k. |
|
# This is estimate for extreme value index. |
|
estimate = sum(sumdata)/k |
|
# estimate for tail index |
|
return np.power(estimate,-1) |
Voi olla että tässä on jopa virhe (ainakin tässä #1 näyttäisi siltä että yritetään jakaa nollalla). Joka tapauksessa tuossa lienee ihan oikea idea, mutta sen voisi ilmaista simppelimmin, voit kopsata suoraan tämän pätkän mitä käytin jossain muualla
def hill(sample, k):
sample = sorted(sorted(np.array(sample), reverse=True)[:k])
sample = np.log(sample)-np.log(sample[0])
return np.mean(sample[1:])
Tämä nyt tuottaa alfan sijaan gamman, mutta voidaan ajatella että ollaan kiinnostuneita ääriarvoindeksistä eikä häntäindeksistä.
Sisäänrakennetut vakiot
Näistä sisäänrakennetuista vakioista pitäisi päästä kokonaan eroon. Haluttaisiin, että python hillSim.py
muotoisen komennon sijaan simukierros ajettaisiin komennolla python hillSim.py -b 3 -n 10000 -r 5000
, jotta noita vakioita olisi sitten joustavaa säätää halutulla tavalla koskematta itse skriptiin. Tähän soveltuu argparse-kirjasto. Copypasteet tuolta vaan jonkin esimerkin ja muokkaat siitä sellaisen mitä tarvitset tähän tilanteeseen.
Tyyliseikkoja
Kommenteista
|
# Own definition for k, which is a parameter in Hill estimator |
|
# kf(n) is such a function that k-> inf and k/n -> 0 |
|
# k is now quite large because we want to see some bias |
|
# for small k variance is great but bias would be nonexistent. |
# Tämä
on ihan hyvä syntaksi python kommenteille. Tehdään me tällaiset block-commentit kuitenkin näin:
"""
Own definition for k, which is a parameter in Hill estimator
kf(n) is such a function that k-> inf and k/n -> 0
k is now quite large because we want to see some bias
for small k variance is great but bias would be nonexistent.
"""
PEP8
Hyvä tapa pitää huolta koodin luettavuudesta on noudattaa PEP8 standardia. Järkevin tapa pitää huolta siitä että koodi on standarin mukaista on ajaa flake8 hillSim.py
ja tehdä muutoksia niin kauan ettei komento tulosta mitään. On myös olemassa online-työkaluja tähän.