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/cs/1-Introduction/04-stats-and-probability/notebook.ipynb

581 lines
18 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Úvod do pravděpodobnosti a statistiky\n",
"V tomto zápisníku si budeme hrát s některými koncepty, které jsme dříve probírali. Mnoho konceptů z pravděpodobnosti a statistiky je dobře zastoupeno v hlavních knihovnách pro zpracování dat v Pythonu, jako jsou `numpy` 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": [
"## Náhodné proměnné a rozdělení\n",
"Začněme výběrem vzorku 30 hodnot z rovnoměrného rozdělení od 0 do 9. Také vypočítáme průměr a rozptyl.\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": [
"Pro vizuální odhad, kolik různých hodnot se ve vzorku vyskytuje, můžeme nakreslit **histogram**:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.hist(sample)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Analýza reálných dat\n",
"\n",
"Průměr a rozptyl jsou velmi důležité při analýze reálných dat. Načtěme data o baseballových hráčích z [SOCR MLB Height/Weight Data](http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_MLB_HeightsWeights)\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": [
"> Používáme balíček zvaný [**Pandas**](https://pandas.pydata.org/) pro analýzu dat. O knihovně Pandas a práci s daty v Pythonu budeme mluvit později v tomto kurzu.\n",
"\n",
"Spočítejme průměrné hodnoty pro věk, výšku a váhu:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df[['Age','Height','Weight']].mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nyní se zaměřme na výšku a vypočítejme směrodatnou odchylku a rozptyl:\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": [
"Kromě průměru dává smysl podívat se na medián a kvartily. Ty lze vizualizovat pomocí **krabicového grafu**:\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": [
"Můžeme také vytvořit krabicové grafy podmnožin našeho datasetu, například seskupené podle role hráče.\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": [
"> **Poznámka**: Tento diagram naznačuje, že průměrná výška prvních basemanů je vyšší než výška druhých basemanů. Později se naučíme, jak tuto hypotézu formálněji otestovat a jak ukázat, že naše data jsou statisticky významná k jejímu prokázání.\n",
"\n",
"Věk, výška a váha jsou všechny spojité náhodné proměnné. Jaká myslíte, že je jejich distribuce? Dobrou metodou, jak to zjistit, je vykreslit histogram hodnot:\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ální rozdělení\n",
"\n",
"Vytvořme umělý vzorek váh, který následuje normální rozdělení se stejným průměrem a rozptylem jako naše skutečná data:\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": [
"Protože většina hodnot v reálném životě má normální rozdělení, neměli bychom používat uniformní generátor náhodných čísel pro generování vzorových dat. Zde je, co se stane, pokud se pokusíme vygenerovat hmotnosti s uniformním rozdělením (vygenerované pomocí `np.random.rand`):\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": [
"## Intervaly spolehlivosti\n",
"\n",
"Nyní vypočítáme intervaly spolehlivosti pro váhy a výšky baseballových hráčů. Použijeme kód [z této diskuse na stackoverflow](https://stackoverflow.com/questions/15033511/compute-a-confidence-interval-from-sample-data):\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": [
"## Testování hypotéz\n",
"\n",
"Pojďme prozkoumat různé role v našem datasetu baseballových hráčů:\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": [
"Ověřme hypotézu, že první metaři jsou vyšší než druzí metaři. Nejjednodušší způsob, jak to udělat, je otestovat intervaly spolehlivosti:\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": [
"Vidíme, že intervaly se nepřekrývají.\n",
"\n",
"Statisticky správnějším způsobem, jak dokázat hypotézu, je použití **Studentova t-testu**:\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": [
"Dvě hodnoty vrácené funkcí `ttest_ind` jsou:\n",
"* p-hodnota může být považována za pravděpodobnost, že dvě rozdělení mají stejný průměr. V našem případě je velmi nízká, což znamená, že existuje silný důkaz podporující, že první metaři jsou vyšší.\n",
"* t-hodnota je mezihodnota normalizovaného rozdílu průměrů, která se používá v t-testu, a porovnává se s mezní hodnotou pro danou hladinu spolehlivosti.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Simulace normálního rozdělení s centrální limitní větou\n",
"\n",
"Generátor pseudonáhodných čísel v Pythonu je navržen tak, aby nám poskytoval rovnoměrné rozdělení. Pokud chceme vytvořit generátor pro normální rozdělení, můžeme použít centrální limitní větu. Pro získání hodnoty s normálním rozdělením jednoduše spočítáme průměr vzorku vygenerovaného rovnoměrným rozdělením.\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": [
"## Korelace a Evil Baseball Corp\n",
"\n",
"Korelace nám umožňuje nalézt vztahy mezi sekvencemi dat. V našem ukázkovém příkladu si představme, že existuje zlý baseballový korporát, který platí svým hráčům podle jejich výšky čím vyšší hráč je, tím více peněz dostane. Předpokládejme základní plat 1000 dolarů a dodatečný bonus od 0 do 100 dolarů, v závislosti na výšce. Vezmeme skutečné hráče z MLB a vypočítáme jejich imaginární platy:\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": [
"Nyní spočítejme kovarianci a korelaci těchto sekvencí. `np.cov` nám poskytne takzvanou **kovarianční matici**, což je rozšíření kovariance na více proměnných. Prvek $M_{ij}$ kovarianční matice $M$ je korelace mezi vstupními proměnnými $X_i$ a $X_j$, a hodnoty na diagonále $M_{ii}$ jsou rozptyly $X_{i}$. Podobně `np.corrcoef` nám poskytne **korelační matici**.\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": [
"Korelace rovná 1 znamená, že mezi dvěma proměnnými existuje silný **lineární vztah**. Lineární vztah můžeme vizuálně vidět tak, že zakreslíme jednu hodnotu proti druhé:\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": [
"Podívejme se, co se stane, pokud vztah není lineární. Předpokládejme, že naše společnost se rozhodla skrýt zřejmou lineární závislost mezi výškami a platy a do vzorce zavedla nějakou nelinearitu, například `sin`:\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": [
"V tomto případě je korelace o něco menší, ale stále je docela vysoká. Nyní, aby byla vazba ještě méně zřejmá, můžeme přidat nějakou dodatečnou náhodnost přidáním náhodné proměnné k platu. Podívejme se, co se stane:\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": [
"> Dokážete uhodnout, proč se tečky takto srovnají do svislých linií?\n",
"\n",
"Pozorovali jsme korelaci mezi uměle vytvořeným konceptem, jako je plat, a pozorovanou proměnnou *výška*. Podívejme se také, zda spolu korelují dvě pozorované proměnné, jako je výška a váha:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].ffill(),df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Bohužel jsme nedostali žádné výsledky pouze nějaké podivné hodnoty `nan`. Je to způsobeno tím, že některé hodnoty v naší sérii nejsou definované, jsou reprezentovány jako `nan`, což způsobuje, že výsledek operace je rovněž nedefinovaný. Pohledem na matici vidíme, že problematickým sloupcem je `Weight`, protože byla spočítána samokorelace mezi hodnotami `Height`.\n",
"\n",
"> Tento příklad ukazuje důležitost **přípravy dat** a **čištění**. Bez správných dat nemůžeme nic spočítat.\n",
"\n",
"Použijme metodu `fillna` pro doplnění chybějících hodnot a spočítejme korelaci: \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].fillna(method='pad'), df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Existuje skutečně korelace, ale není tak silná jako v našem umělém příkladu. Pokud se podíváme na bodový graf jedné hodnoty vůči druhé, vztah by byl mnohem méně zřejmý:\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": [
"## Závěr\n",
"\n",
"V tomto sešitě jsme se naučili, jak provádět základní operace s daty pro výpočet statistických funkcí. Nyní víme, jak používat pevný aparát matematiky a statistiky k ověření některých hypotéz a jak vypočítat intervaly spolehlivosti pro libovolné proměnné na základě datového vzorku.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Zřeknutí se odpovědnosti**: \nTento dokument byl přeložen pomocí AI překladatelské služby [Co-op Translator](https://github.com/Azure/co-op-translator). I když usilujeme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Originální dokument v jeho mateřském jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Nejsme odpovědní za jakákoliv nedorozumění nebo mylné výklady vyplývající z použití tohoto překladu.\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:34:38+00:00",
"source_file": "1-Introduction/04-stats-and-probability/notebook.ipynb",
"language_code": "cs"
}
},
"nbformat": 4,
"nbformat_minor": 4
}