2024 szeptember elején a sajtóban több helyen is megjelent az illetékes minisztérium és a szakszervezet közötti nézetkülönbség a kormányhivatalokban és a járási hivatalokban dolgozók bérszintjének megítélése tekintetében. Az egyik fő kérdés, ami nyitott maradt, mert a minisztérium csak átlagbért közölt, az a dolgozók medián bére, vagyis az az érték, ami felett és alatt ugyanannyian keresnek.
Ilyen kérdés esetén jön jól egy kis Python ismeret, mert a szabványos könyvtár random és statistics moduljának eszköztárával megkísérelhetjük a medián bér becslését. Ezt azért is érdemes megtenni, mert most nem egy tankönyvi példát kell megoldani, hanem egy, a napi életben felmerült kérdést. Valós problémákra pedig sokkal motiválóbb programot készíteni.
Ehhez először gyűjtsük össze, hogy milyen kiindulóadatok állnak rendelkezésre a sajtócikkeket olvasva. Ezek a következők:
– Kormányhivatalokban dolgozók összlétszáma: 33 000 fő
– Ebből: kb. 27000 beosztott, kb. 6000 vezető.
– Minimum bruttó bér (garantált bérminimum): 326 000 Ft
– A többség bruttó bére e bérminimum környékén mozog.
– Ennél többet kap az összlétszám 98.7%-a.
– A vezető beosztásúak bruttó fizetése >= kb. 1 millió Ft
– Kormányhivatalokban dolgozók bruttó átlagbére: 510 585 Ft
– A dolgozói és vezetői bérsávhatárokat a 180/2023. (V. 15.) Korm. rendelet tartalmazza, ami alapján az adható maximális bér 2 500 000 Ft.
Ezen adatok alapján kell meghatároznunk a béreloszlás jellemzőit. Ehhez tehát objektív adatként tudjuk a teljes sokaság (populáció) méretét, valamint a bér minimális és maximális értékét. A többi adat a felek nyilatkozata. De ahhoz, hogy számolni tudjunk, fogadjuk el a közölt konkrét statisztikai jellemzőkre vonatkozó értékeket, vagyis az eloszlás átlagát és azt, hogy a minimum fölé a populáció 98.7%-a esik. Abból a kijelentésből pedig, hogy „A többség bruttó bére e bérminimum környékén mozog”, az eloszlás móduszát (ami az eloszlás maximumértéke, a tipikus érték, amely környékén a bérek többsége van) fogjuk becsülni.
Az eloszlás becsléséhez, vagyis az ismert matematikai eloszlások közüli választáshoz, két szempontot kell figyelembe venni. Az egyik abból adódik, hogy a bérek gyakorisága a minimum és maximumértékeik között nem egyenletes, és nem is szimmetrikus, hanem általában a kisebb értékek felé fordul elő többször. Ezért ún. ferde eloszlást, még pontosabban balra ferde eloszlást keresünk, ahol tehát az értékek gyakorisága a szimmetrikushoz képesti bal oldalon (a kisebb értékek felé) nagyobb mint jobb oldalon. A másik választási kritériumot pedig az adja, hogy a bérek egy véges, alsó és felső határral rendelkező intervallumban szórnak.
A Python szabványos könyvtárában, a random modul kínál különböző eloszlású véletlen értékeket előállító függvényeket. Ezek közül a feltételeinknek a beta eloszlás, illetve az ilyen eloszlású, 0 és 1 közötti értékeket kiadó betavariate(alpha, beta) függvény felel meg, ahol az alpha és beta paraméterek pozitív valós számok, amelyek együttesen meghatározzák az eloszlás alakját, ha azt grafikonon ábrázoljuk. E paraméterekkel az eloszlás várható értéke (átlagértéke) és módusza is kifejezhető, illetve fordítva, ha a várható érték és a módusz adott, akkor az alpha és beta értéke kiszámítható, amint az az ábrán látható:

Mivel a bérek nem a beta-eloszlás [0,1] intervallumába esnek, ezért ahhoz, hogy a maximális és minimális bérek közötti bérsávhoz kapjuk meg a megfelelő alpha és beta paramétereket, a képletekben az m módusz helyére a (bér módusz – minimum bér)/bérsáv, a mű, azaz a várható érték helyére a (bér várható érték – minimum bér)/bérsáv értékeket kell írni. Az így paraméterezett betavariate(alpha, beta) függvénnyel a kormányhivatalokban dolgozók összlétszámának megfelelő számú értéket állítunk elő. Ezek a [0,1] intervallumba fognak esni, ezért minden egyes értéket a bérsávba kell lineárisan transzformálni; vagyis a betavariate() által kiadott értéket meg kell szorozni a bérsávval és ehhez hozzáadni a bérminimumot.
A bérek móduszának megfelelő becslését is némi megfontolás után tudjuk megtenni. A módusz nem lehet a minimumérték, mert ha 27000 alkalmazott bérminimumot kap és tegyük fel, hogy igaz, hogy 6000 vezető 1 millót, akkor az átlag a közöltnél sokkal kisebb. De a módusznak azért is magasabbnak kell lenni a bérminimumnál, mert a kormányrendelet a beosztottakra is bérsávokat határoz meg beosztás alapján. És mivel feltételezhető, hogy a magasabb bérsávokba is esnek alkalmazottak, a módusz magasabb kell, hogy legyen a bérminimumnál. Az, hogy mennyivel, arra csak egy feltételezést lehet tenni. A módusz ezért egy változó lesz, és úgy kell majd beállítani, hogy az eloszlásmodellben olyan statisztikai jellemző értéke is teljesüljön, amire még van adatunk.
Van adatunk arra, hogy az összlétszám hány százaléka keres többet mint a bérminimum. Ezt úgy ellenőrizzük, hogy megszámoljuk, hogy a bérek halmazában összesen mennyi van e fölött. A véletlen számokkal dolgozó modellünkben szűrési limitnek nem célszerű a bérminimumot adni, hanem egy kicsit felette levő értéket. Legyen ez mondjuk 330eFt. Azt fogjuk vizsgálni tehát, hogy a dolgozók hány százaléka keres legalább ennyit. Ezzel együtt azt is megnézzük, hogy hogyan alakul a vezetők bére. Itt azt fogjuk kideríteni, hogy mennyi az a minimális bér, amit kb. 6000 fő biztosan megkap. Ebből látható lesz, hogy az az 1 millió Ft-hoz közeli vagy sem.
A béradatok várható értékét, mediánját és szórását a statistics modul mean(), median() és psdev() függvényeivel számoljuk.
A móduszt azonban nem a statistics modul mode() függvényével fogjuk számítani, mert most egy folytonos valószínűség-eloszlással modellezünk. Ilyenkor a módusz a sűrűségfüggvény maximuma. Ehhez először meghatározzuk a bérek sűrűségfüggvényét, amit kellően nagy számú intervallumban vett relatív gyakorisággal közelítünk. Ha ez megvan, akkor megkeressük azt a bérértéket, amelyhez a legnagyobb relatív gyakoriság tartozik. Ez lesz az eloszlás módusza. (Mivel véges számú mintával dolgozunk és a sűrűségfüggvényt csak közelítjük, így a kapott érték nem feltétlenül fog megegyezni az elméleti értékkel, de közelíteni fogja.)
A fenti megfontolások alapján készített program kódját mutatjuk alább. Az eddig leírtak és a kommentek alapján a működését nem nehéz megérteni.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
from collections import defaultdict from itertools import pairwise from random import betavariate from statistics import mean, median, pstdev def relative_frequency(values, a, b, n=100, interval_repr_value='left'): """Meghatározza a values iterálható objektum a és b határok közé eső értékeinek relatív gyakoriságát n db intervallumban. Visszatérési értéke egy szótár, amelyben a kulcsok az intervallumokat képviselő számok, amelyek az interval_repr_value beállításától függően lehetnek az alsó, vagy felső határok, vagy a középértékek. A szótár értékei az intervallumba eső relatív gyakoriságok. """ def ivrepval(itv: tuple): """Egy szmértéket ad vissza, amely egy intervallumot képvisel az intervallum alsó vagy felső határával, vagy az intervallum számtani átlagával, az interval_repr_value argumentumtól függően. """ return {'left': itv[0], 'right': itv[1], 'middle': (itv[0] + itv[1]) / 2}[interval_repr_value] dd = defaultdict(int) width = abs(b - a) / n intervals = tuple(pairwise((width * i + a for i in range(n + 1)))) value_count = 1 for value_count, v in enumerate(values, 1): for iv in intervals: if iv[0] <= v < iv[1]: dd[ivrepval(iv)] += 1 break return {k: v / value_count for k, v in sorted(dd.items(), key=lambda t: t[0])} def beta_params(beta_mean, beta_mode) -> tuple[float, float]: """Visszaadja a beta eloszlás alpha és beta paramétereinek értékeit, ha adott az eloszlás várható értéke (beta_mean) és módusza (beta_mode)""" u, v = (1 - beta_mean) / beta_mean, (1 - beta_mode) / beta_mode param_alfa = ((2 * beta_mode - 1) / beta_mode) / (u - v) param_beta = param_alfa * u return param_alfa, param_beta # Alapadatok. total_employees = 33000 min_salary, max_salary = 326, 2500 # ezer forint. salary_range = max_salary - min_salary salary_mean, salary_mode = 510.585, 350 # ezer forint. # A bérek eloszlását beta eloszlással modellezzük. Ennek paraméterei: alpha, beta = beta_params((salary_mean - min_salary) / salary_range, (salary_mode - min_salary) / salary_range) # Az összes dolgozóhoz előállítjuk a béreket a meghatározott alpha és beta paraméterekkel meghívott betavariate() függvénnyel. salary_seq = [bvar * salary_range + min_salary for bvar in (betavariate(alpha, beta) for _ in range(total_employees))] # Kiszámítjuk a bérek relativ gyakoriságát elegendően nagy számú intervallumban. rel_freq_salaries = relative_frequency(salary_seq, min(salary_seq), max(salary_seq), n=100) # A bérek sorozatából meghatározzuk a bérek statisztikai jellemzőit, az átlagot, a mediánt, a móduszt és a szórást. mean_salary = mean(salary_seq) median_salary = median(salary_seq) stdev_salary = pstdev(salary_seq) mode_salary, _ = max(rel_freq_salaries.items(), key=lambda item: item[1]) # Az eredmények kiírása. print('átlagbér = {:.2f} Ft, medián bér = {:.2f} Ft, ' 'módusz = {:.2f} Ft, szórás az átlagtól = {:.2f} Ft'.format(mean_salary, median_salary, mode_salary, stdev_salary)) print('Alkalmazottak aránya, akik bére több, mint') for salary in (min_salary + 4, 450, salary_mean): print('{} eFt : {:.2%}'.format(salary, len([sal for sal in salary_seq if sal >= salary]) / total_employees)) print('Vezetők száma, aki bére több, mint') for salary in (640, 800, 1000): print('{} eFt : {} fő'.format(salary, len([sal for sal in salary_seq if sal >= salary]))) # Eredmények: # átlagbér = 510.25 Ft, medián bér = 467.22 Ft, módusz = 352.43 Ft, szórás az átlagtól = 159.45 Ft # Alkalmazottak aránya, akik bére több, mint # 330 eFt : 98.72% # 450 eFt : 54.90% # 510.585 eFt : 38.89% # Vezetők száma, aki bére több, mint # 640 eFt : 5949 fő # 800 eFt : 1995 fő # 1000 eFt : 457 fő |
Többszöri futtatás után is a fentebb feltüntetettekhez hasonló eredményeket kapunk.
Az alkalmazott modell alapján tehát az jön ki, hogy
– A kormányhivatali dolgozók 510 585 forintos átlagbére mellett a medián bruttó bér 460-470 eFt között lehet. Vagyis e feletti és ez alatti bért ugyanannyian kapnak.
– A bérek 350 eFt körül sűrűsödnek legjobban.
– Az alkalmazottak 98.7%-a legalább 330 eFt-ot keres.
– Feltételezve, hogy a vezetők száma kb. 6000, a bruttó bérük legalább 640 eFt, ami a kormány rendeletben szereplő vezetőkre (osztályvezető és felette) vonatkozó alsó bérsávval összhangban van. Tehát az alkalmazott modellünk nem igazolta vissza a vezetők többségének 1 milliós vagy a feletti bérét.
Mindazonáltal a kapott eredményeket helyükön kell kezelni, mert hangsúlyozottan a rendelkezésre álló, és igaznak elfogadott adatok, valamint az alkalmazott modell alapján jöttek ki, ezért nem feltétlenül egyeznek a tényleges valós helyzettel.
A Python tudásépítés lépésről lépésre című e-könyvben a véletlen számokról és a statisztikai függvényekről a „Készétel fogyasztás – a szabványos könyvtár moduljainak használata” fejezeten belül a „Matematikai számítások támogatása” alfejezet „A véletlen használatba vétele” és a „Statisztikai eszköztár” című részei foglalkoznak.