You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Data-Science-For-Beginners/translations/hu/1-Introduction/04-stats-and-probability/notebook.ipynb

581 lines
19 KiB

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Bevezetés a valószínűségszámítás és statisztika témakörébe\n",
"Ebben a jegyzetfüzetben néhány korábban megvitatott fogalommal fogunk játszani. A valószínűségszámítás és statisztika sok fogalma jól képviselteti magát a Python adatfeldolgozó nagy könyvtáraiban, mint például a `numpy` és a `pandas`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import random\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Véletlen változók és eloszlások\n",
"Kezdjük egy 30 értékből álló minta húzásával egy 0 és 9 közötti egyenletes eloszlásból. Kiszámoljuk a várható értéket és a varianciát is.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sample = [ random.randint(0,10) for _ in range(30) ]\n",
"print(f\"Sample: {sample}\")\n",
"print(f\"Mean = {np.mean(sample)}\")\n",
"print(f\"Variance = {np.var(sample)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Annak vizuális becsléséhez, hogy hány különböző érték található a mintában, ábrázolhatjuk a **hisztogramot**:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.hist(sample)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Valós adatok elemzése\n",
"\n",
"Az átlag és a szórás nagyon fontosak a valós adatok elemzésekor. Töltsük be az adatokat baseball-játékosokról a [SOCR MLB Height/Weight Data](http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_MLB_HeightsWeights) oldalról.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_csv(\"../../data/SOCR_MLB.tsv\",sep='\\t', header=None, names=['Name','Team','Role','Weight','Height','Age'])\n",
"df\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> Egy olyan csomagot használunk itt, amely a [**Pandas**](https://pandas.pydata.org/) nevet viseli az adatelemzéshez. Ebben a tanfolyamban később még többet fogunk beszélni a Pandas-ról és az adattal való munkáról Pythonban.\n",
"\n",
"Számoljuk ki az életkor, magasság és súly átlagértékeit:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df[['Age','Height','Weight']].mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most összpontosítsunk a magasságra, és számoljuk ki a szórást és a varianciát:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(list(df['Height'])[:20])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mean = df['Height'].mean()\n",
"var = df['Height'].var()\n",
"std = df['Height'].std()\n",
"print(f\"Mean = {mean}\\nVariance = {var}\\nStandard Deviation = {std}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Az átlag mellett érdemes megvizsgálni a mediánt és a kvartiliseket is. Ezeket egy **dobozábra** segítségével lehet megjeleníteni:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(10,2))\n",
"plt.boxplot(df['Height'].ffill(), vert=False, showmeans=True)\n",
"plt.grid(color='gray', linestyle='dotted')\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Készíthetünk dobozdiagramokat az adataink részhalmazairól is, például játékosi szerep szerint csoportosítva.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df.boxplot(column='Height', by='Role', figsize=(10,8))\n",
"plt.xticks(rotation='vertical')\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Megjegyzés**: Ez az ábra azt sugallja, hogy átlagosan a első bázisznál játszók magassága nagyobb, mint a második bázisnál játszóké. Később megtanuljuk, hogyan tudjuk ezt a hipotézist formálisan tesztelni, és hogyan bizonyíthatjuk, hogy adataink statisztikailag szignifikánsak ennek alátámasztására.\n",
"\n",
"Az életkor, a magasság és a testsúly mind folytonos valószínűségi változók. Ön szerint milyen eloszlásuk van? Egy jó módja, hogy kiderítsük, az, ha megrajzoljuk az értékek hisztogramját:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df['Weight'].hist(bins=15, figsize=(10,6))\n",
"plt.suptitle('Weight distribution of MLB Players')\n",
"plt.xlabel('Weight')\n",
"plt.ylabel('Count')\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Normális eloszlás\n",
"\n",
"Hozzunk létre egy mesterséges súlymintát, amely normális eloszlást követ, és ugyanazzal az átlaggal és szórással rendelkezik, mint a valós adataink:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"generated = np.random.normal(mean, std, 1000)\n",
"generated[:20]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(10,6))\n",
"plt.hist(generated, bins=15)\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(10,6))\n",
"plt.hist(np.random.normal(0,1,50000), bins=300)\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Mivel a valós életben a legtöbb érték normál eloszlású, nem szabad egyenletes eloszlású véletlenszám-generátort használnunk mintadatok előállításához. Íme, mi történik, ha megpróbálunk súlyokat generálni egyenletes eloszlással (amit a `np.random.rand` generál):\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"wrong_sample = np.random.rand(1000)*2*std+mean-std\n",
"plt.figure(figsize=(10,6))\n",
"plt.hist(wrong_sample)\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Bizalmi intervallumok\n",
"\n",
"Most számoljuk ki a baseball játékosok súlyára és magasságára vonatkozó bizalmi intervallumokat. A kódot [ebből a stackoverflow beszélgetésből](https://stackoverflow.com/questions/15033511/compute-a-confidence-interval-from-sample-data) fogjuk használni:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import scipy.stats\n",
"\n",
"def mean_confidence_interval(data, confidence=0.95):\n",
" a = 1.0 * np.array(data)\n",
" n = len(a)\n",
" m, se = np.mean(a), scipy.stats.sem(a)\n",
" h = se * scipy.stats.t.ppf((1 + confidence) / 2., n-1)\n",
" return m, h\n",
"\n",
"for p in [0.85, 0.9, 0.95]:\n",
" m, h = mean_confidence_interval(df['Weight'].fillna(method='pad'),p)\n",
" print(f\"p={p:.2f}, mean = {m:.2f} ± {h:.2f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Hipotézisvizsgálat\n",
"\n",
"Vizsgáljuk meg a különböző szerepköröket a baseball játékosok adatállományában:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df.groupby('Role').agg({ 'Weight' : 'mean', 'Height' : 'mean', 'Age' : 'count'}).rename(columns={ 'Age' : 'Count'})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Teszteljük azt a hipotézist, hogy az első bázis játékosok magasabbak, mint a második bázis játékosok. A legegyszerűbb módja ennek a konfidencia intervallumok tesztelése:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for p in [0.85,0.9,0.95]:\n",
" m1, h1 = mean_confidence_interval(df.loc[df['Role']=='First_Baseman',['Height']],p)\n",
" m2, h2 = mean_confidence_interval(df.loc[df['Role']=='Second_Baseman',['Height']],p)\n",
" print(f'Conf={p:.2f}, 1st basemen height: {m1-h1[0]:.2f}..{m1+h1[0]:.2f}, 2nd basemen height: {m2-h2[0]:.2f}..{m2+h2[0]:.2f}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Láthatjuk, hogy az intervallumok nem fedik át egymást.\n",
"\n",
"A hipotézist statisztikailag helyesebben bizonyítani egy **Student-féle t-próbával** lehet:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from scipy.stats import ttest_ind\n",
"\n",
"tval, pval = ttest_ind(df.loc[df['Role']=='First_Baseman',['Height']], df.loc[df['Role']=='Second_Baseman',['Height']],equal_var=False)\n",
"print(f\"T-value = {tval[0]:.2f}\\nP-value: {pval[0]}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A `ttest_ind` függvény által visszaadott két érték a következő:\n",
"* a p-érték tekinthető annak a valószínűségnek, hogy a két eloszlásnak azonos az átlaga. Esetünkben nagyon alacsony, ami azt jelenti, hogy erős bizonyíték van arra, hogy az első alapemberek magasabbak.\n",
"* a t-érték a normalizált átlagkülönbség köztes értéke, amelyet a t-tesztben használnak, és egy adott megbízhatósági értékhez tartozó küszöbértékkel hasonlítanak össze.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Normális eloszlás szimulálása a központi határeloszlás tételével\n",
"\n",
"A Pythonban található pszeudo-véletlenszám generátor egyenletes eloszlást biztosít számunkra. Ha normális eloszlású generátort szeretnénk készíteni, használhatjuk a központi határeloszlás tételét. Egy normális eloszlású értékhez egyszerűen egy egyenletesen generált minta átlagát számoljuk ki.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def normal_random(sample_size=100):\n",
" sample = [random.uniform(0,1) for _ in range(sample_size) ]\n",
" return sum(sample)/sample_size\n",
"\n",
"sample = [normal_random() for _ in range(100)]\n",
"plt.figure(figsize=(10,6))\n",
"plt.hist(sample)\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Korreláció és a Gonosz Baseball Vállalat\n",
"\n",
"A korreláció lehetővé teszi, hogy kapcsolatokat találjunk az adat-sorozatok között. Játékszintű példánkban képzeljük el, hogy létezik egy gonosz baseball vállalat, amely a játékosait a magasságuk szerint fizeti - minél magasabb a játékos, annál több pénzt kap. Tegyük fel, hogy az alapfizetés 1000 dollár, és ehhez jár egy 0-tól 100-ig terjedő bónusz, a magasság függvényében. A valós MLB-játékosokat vesszük alapul, és kiszámoljuk képzeletbeli fizetésüket:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"heights = df['Height'].fillna(method='pad')\n",
"salaries = 1000+(heights-heights.min())/(heights.max()-heights.mean())*100\n",
"print(list(zip(heights, salaries))[:10])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most számoljuk ki ezeknek a sorozatoknak a kovarianciáját és korrelációját. A `np.cov` úgynevezett **kovariancia mátrixot** ad vissza, amely a kovariancia többszörös változóra való kiterjesztése. A kovariancia mátrix $M$ eleme, $M_{ij}$ az $X_i$ és $X_j$ bemeneti változók közötti kovariancia, míg a diagonális értékek, $M_{ii}$, az $X_i$ varianciáját jelentik. Hasonlóan, a `np.corrcoef` a **korrelációs mátrixot** adja vissza.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(f\"Covariance matrix:\\n{np.cov(heights, salaries)}\")\n",
"print(f\"Covariance = {np.cov(heights, salaries)[0,1]}\")\n",
"print(f\"Correlation = {np.corrcoef(heights, salaries)[0,1]}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A korreláció értéke 1 azt jelenti, hogy két változó között erős **lineáris kapcsolat** áll fenn. A lineáris kapcsolatot vizuálisan is láthatjuk, ha az egyik értéket a másikhoz ábrázoljuk:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(10,6))\n",
"plt.scatter(heights,salaries)\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lássuk, mi történik, ha a kapcsolat nem lineáris. Tegyük fel, hogy vállalatunk úgy döntött, elrejti a magasságok és fizetések közötti nyilvánvaló lineáris függőséget, és bevezet némi nemlinearitást a képletbe, például a `sin` függvényt:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"salaries = 1000+np.sin((heights-heights.min())/(heights.max()-heights.mean()))*100\n",
"print(f\"Correlation = {np.corrcoef(heights, salaries)[0,1]}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ebben az esetben a korreláció kissé kisebb, de még mindig meglehetősen magas. Most, hogy a kapcsolat még kevésbé legyen nyilvánvaló, szeretnénk hozzáadni némi extra véletlenszerűséget úgy, hogy egy véletlenszerű változót adunk a fizetéshez. Nézzük, mi történik:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"salaries = 1000+np.sin((heights-heights.min())/(heights.max()-heights.mean()))*100+np.random.random(size=len(heights))*20-10\n",
"print(f\"Correlation = {np.corrcoef(heights, salaries)[0,1]}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(10,6))\n",
"plt.scatter(heights, salaries)\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> Kitalálod, miért rendeződnek a pontok így függőleges vonalakká?\n",
"\n",
"Megfigyeltük a mesterségesen létrehozott fogalom, azaz a fizetés és a megfigyelt változó, a *magasság* közötti összefüggést. Nézzük meg azt is, hogy a két megfigyelt változó, mint például a magasság és a súly, összefügg-e egymással:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].ffill(),df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sajnos nem kaptunk eredményt - csak néhány furcsa `nan` értéket. Ennek oka, hogy a sorozatunk néhány értéke nem definiált, `nan`-ként van ábrázolva, ami az eredmény undefined jellegét is okozza. A mátrixot megnézve láthatjuk, hogy a problémás oszlop a `Weight`, mert a `Height` értékek önkorrelációját számoltuk ki.\n",
"\n",
"> Ez a példa megmutatja az **adat-előkészítés** és a **tisztítás** fontosságát. Megfelelő adatok nélkül nem tudunk semmit kiszámolni.\n",
"\n",
"Használjuk a `fillna` metódust a hiányzó értékek pótlására, és számoljuk ki a korrelációt: \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].fillna(method='pad'), df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Valóban van összefüggés, de nem olyan erős, mint mesterséges példánkban. Valóban, ha megnézzük az egyik érték a másikkal szembeni szórásdiagramját, a kapcsolat sokkal kevésbé lenne nyilvánvaló:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(10,6))\n",
"plt.scatter(df['Weight'],df['Height'])\n",
"plt.xlabel('Weight')\n",
"plt.ylabel('Height')\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Következtetés\n",
"\n",
"Ebben a jegyzetfüzetben megtanultuk, hogyan végezzünk alapműveleteket az adatokon statisztikai függvények kiszámításához. Most már tudjuk, hogyan használjuk a matematika és a statisztika egy megbízható eszköztárát ahhoz, hogy bizonyítsunk egyes hipotéziseket, és hogyan számítsuk ki a megbízhatósági intervallumokat tetszőleges változókra adott adatminta alapján.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Tájékoztatás**:\nEzt a dokumentumot az AI fordító szolgáltatás [Co-op Translator](https://github.com/Azure/co-op-translator) segítségével fordítottuk le. Bár a pontosságra törekszünk, kérjük, vegye figyelembe, hogy az automatikus fordítások hibákat vagy pontatlanságokat tartalmazhatnak. Az eredeti dokumentum anyanyelvén tekintendő hiteles forrásnak. Kritikus információk esetén szakmai emberi fordítást javaslunk. Nem vállalunk felelősséget az ebből eredő félreértésekért vagy téves értelmezésekért.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "86193a1ab0ba47eac1c69c1756090baa3b420b3eea7d4aafab8b85f8b312f0c5"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.6"
},
"coopTranslator": {
"original_hash": "0f899e3c5019f948e7c787b22f3b2304",
"translation_date": "2026-01-16T18:33:18+00:00",
"source_file": "1-Introduction/04-stats-and-probability/notebook.ipynb",
"language_code": "hu"
}
},
"nbformat": 4,
"nbformat_minor": 4
}