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/lt/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": [
"# Įvadas į tikimybių teoriją ir statistiką\n",
"Šiame užrašų knygelėje žaisime su kai kuriomis anksčiau aptartomis sąvokomis. Daugelis tikimybių ir statistikos sąvokų yra gerai atspindėtos pagrindinėse duomenų apdorojimo bibliotekose Python kalboje, tokiose kaip `numpy` ir `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": [
"## Atsitiktiniai dydžiai ir pasiskirstymai\n",
"Pradėkime nuo 30 reikšmių mėginio paėmimo iš tolydaus pasiskirstymo nuo 0 iki 9. Taip pat apskaičiuosime vidurkį ir dispersiją.\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": [
"Norėdami vizualiai įvertinti, kiek skirtingų reikšmių yra mėginyje, galime nubrėžti **histogramą**:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.hist(sample)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Realių duomenų analizė\n",
"\n",
"Vidurkis ir dispersija yra labai svarbūs analizuojant realius duomenis. Įkelkime duomenis apie beisbolo žaidėjus iš [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": [
"> Čia mes naudojame paketą, vadinamą [**Pandas**](https://pandas.pydata.org/), duomenų analizei. Vėliau šiame kurse daugiau kalbėsime apie Pandas ir darbą su duomenimis Python kalboje.\n",
"\n",
"Apskaičiuokime vidutines amžiaus, ūgio ir svorio reikšmes:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df[['Age','Height','Weight']].mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dabar susitelkime į ūgį ir apskaičiuokime standartinį nuokrypį bei dispersiją:\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": [
"Be vidurkio, prasminga pažvelgti į medianą ir kvantilius. Juos galima vizualizuoti naudojant **dėžės diagramą**:\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": [
"Taip pat galime sudaryti dėžutės diagramas mūsų duomenų rinkinio dalims, pavyzdžiui, suskirstytoms pagal žaidėjo vaidmenį.\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": [
"> **Pastaba**: Ši diagrama rodo, kad vidutiniškai pirmųjų bazės žaidėjų ūgiai yra didesni už antrųjų bazės žaidėjų ūgius. Vėliau sužinosime, kaip galime formaliau patikrinti šią hipotezę ir kaip parodyti, kad mūsų duomenys statistiškai reikšmingi tai parodyti. \n",
"\n",
"Amžius, ūgis ir svoris yra tęstiniai atsitiktiniai kintamieji. Kokia, jūsų manymu, yra jų pasiskirstymo forma? Geras būdas sužinoti nubraižyti reikšmių histogramą: \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": [
"## Normalus pasiskirstymas\n",
"\n",
"Sukursime dirbtinį svorių pavyzdį, kuris seka normalų pasiskirstymą su tokiu pačiu vidurkiu ir dispersija kaip mūsų realūs duomenys:\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": [
"Kadangi dauguma tikrų gyvenimo reikšmių yra normaliai pasiskirsčiusios, neturėtume naudoti tolydaus atsitiktinių skaičių generatoriaus imčių duomenims generuoti. Štai kas nutinka, jei bandysime generuoti svorius naudojant tolydų pasiskirstymą (generuotą su `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": [
"## Pasitikėjimo intervalai\n",
"\n",
"Dabar apskaičiuokime pasitikėjimo intervalus beisbolo žaidėjų svoriams ir ūgiams. Naudosime kodą [iš šios stackoverflow diskusijos](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": [
"## Hipotezių tikrinimas\n",
"\n",
"Pažvelkime į skirtingas roles mūsų beisbolo žaidėjų duomenų rinkinyje:\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": [
"Patikrinkime hipotezę, kad pirmieji bazės žaidėjai yra aukštesni už antruosius bazės žaidėjus. Paprasčiausias būdas tai padaryti yra patikrinti pasitikėjimo intervalus:\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": [
"Matome, kad intervalai nesikerta.\n",
"\n",
"Statistiškai teisingesnis būdas patvirtinti hipotezę yra naudoti **Student t-testą**:\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": [
"Funkcijos `ttest_ind` grąžinamos dvi reikšmės yra:\n",
"* p-reikšmė gali būti laikoma dviejų pasiskirstymų turinčių tokį pat vidurkį tikimybe. Mūsų atveju ji yra labai maža, reiškianti, kad yra stiprūs įrodymai, kad pirmieji žaidėjai yra aukštesni.\n",
"* t-reikšmė yra normalizuoto vidurkio skirtumo tarpinių reikšmių vertė, naudojama t-teste, ir ji lyginama su tam tikra slenkstine verte atitinkamam patikimumo lygiui.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Normalaus pasiskirstymo simuliacija naudojant centrinę ribinę teoremą\n",
"\n",
"Pseudoatsitiktinių skaičių generatorius Python sukurtas taip, kad duotų tolydžią pasiskirstymo funkciją. Jeigu norime sukurti normaliai pasiskirsčiusį generatorių, galime naudoti centrinę ribinę teoremą. Norėdami gauti normaliai pasiskirsčiusį reikšmę, tiesiog apskaičiuosime tolydžiai sugeneruoto imties vidurkį.\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": [
"## Koreliacija ir Blogoji Beisbolo Korporacija\n",
"\n",
"Koreliacija leidžia rasti ryšius tarp duomenų sekų. Mūsų žaisliniame pavyzdyje įsivaizduokime, kad yra blogoji beisbolo korporacija, kuri žaidėjams moka pagal jų ūgį kuo aukštesnis žaidėjas, tuo daugiau pinigų jis gauna. Tarkime, kad bazinis atlyginimas yra 1000 USD, o papildomas premijinis nuo 0 iki 100 USD priklauso nuo ūgio. Paimsime tikrus MLB žaidėjus ir apskaičiuosime jų įsivaizduojamus atlyginimus:\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": [
"Dabar apskaičiuokime tų sekų kovariaciją ir koreliaciją. `np.cov` suteiks mums taip vadinamą **kovariacinę matricą**, kuri yra kovariacijos išplėtimas keliems kintamiesiems. Kovariacinės matricos $M$ elementas $M_{ij}$ yra koreliacija tarp įvesties kintamųjų $X_i$ ir $X_j$, o įstrižainės reikšmės $M_{ii}$ yra $X_{i}$ dispersija. Panašiai, `np.corrcoef` suteiks mums **koreliacijos matricą**.\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": [
"Koreliacija, lygi 1, reiškia, kad tarp dviejų kintamųjų yra stiprus **linijinis ryšys**. Linijinį ryšį galime vizualiai pamatyti pavaizdavę vieną reikšmę prieš kitą:\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": [
"Pažiūrėkime, kas nutiks, jei ryšys nebus linijinis. Tarkime, kad mūsų korporacija nusprendė paslėpti akivaizdžią linijinę priklausomybę tarp ūgio ir atlyginimų, ir į formulę įtraukė tam tikrą nelinearumo elementą, pavyzdžiui, `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": [
"Šiuo atveju koreliacija yra šiek tiek mažesnė, tačiau vis tiek gana didelė. Dabar, norėdami santykį padaryti dar mažiau akivaizdų, galime pridėti papildomo atsitiktinumo, pridėdami tam tikrą atsitiktinį kintamąjį prie atlyginimo. Pažiūrėkime, kas nutiks:\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": [
"> Ar galite atspėti, kodėl taškai išsirikiuoja į vertikalias linijas?\n",
"\n",
"Mes pastebėjome koreliaciją tarp dirbtinai sukurto koncepto, kaip atlyginimas, ir stebimos kintamosios *ūgio*. Pažiūrėkime taip pat, ar dvi stebimos kintamosios, tokios kaip ūgis ir svoris, taip pat koreliuoja:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].ffill(),df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deja, nepavyko gauti jokių rezultatų tik keletą keistų `nan` reikšmių. Taip nutinka todėl, kad kai kurios mūsų serijos reikšmės nėra apibrėžtos, jas atitinka `nan`, o tai sukelia ir operacijos rezultatą būti neapibrėžtu. Pažvelgę į matricą matome, kad probleminis stulpelis yra `Weight`, nes atlikta savikoreliacija tarp `Height` reikšmių.\n",
"\n",
"> Šis pavyzdys parodo **duomenų paruošimo** ir **valymo** svarbą. Be tinkamų duomenų negalime apskaičiuoti nieko.\n",
"\n",
"Naudosime `fillna` metodą, kad užpildytume trūkstamas reikšmes, ir apskaičiuosime koreliaciją:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].fillna(method='pad'), df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Iš tiesų egzistuoja koreliacija, tačiau ji nėra tokia stipri kaip mūsų dirbtiniame pavyzdyje. Iš tiesų, jei pažvelgsime į taškų diagramą, kurioje vienas reikšmė lyginama su kita, ryšys būtų daug mažiau akivaizdus:\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": [
"## Išvada\n",
"\n",
"Šiame užrašų knygelėje mes išmokome, kaip atlikti pagrindines operacijas su duomenimis, kad apskaičiuotume statistines funkcijas. Dabar žinome, kaip naudoti tvirtą matematikos ir statistikos aparatūrą, kad įrodytume kai kurias hipotezes, ir kaip apskaičiuoti pasitikėjimo intervalus bet kokiems kintamiesiems, turint duomenų imtį.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Atsakomybės limitas**: \nŠis dokumentas buvo išverstas naudojant dirbtinio intelekto vertimo paslaugą [Co-op Translator](https://github.com/Azure/co-op-translator). Nors siekiame tikslumo, prašome atkreipti dėmesį, kad automatizuoti vertimai gali turėti klaidų ar netikslumų. Originalus dokumentas gimtąja kalba laikomas autoritetingu šaltiniu. Kritinei informacijai rekomenduojamas profesionalus žmogaus atliktas vertimas. Mes neatsakome už jokią painiavą ar klaidingą interpretaciją, kylančią dėl šio vertimo naudojimo.\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-16T21:25:44+00:00",
"source_file": "1-Introduction/04-stats-and-probability/notebook.ipynb",
"language_code": "lt"
}
},
"nbformat": 4,
"nbformat_minor": 4
}