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/et/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": [
"# Sissejuhatus tõenäosusteooriasse ja statistikasse\n",
"Selles märkmikus mängime mõningate varasemalt käsitletud mõistetega. Paljud tõenäosuse ja statistika kontseptsioonid on hästi esindatud suurtes Python'i andmetöötlusteekides, nagu `numpy` ja `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": [
"## Juhuslikud muutujad ja jaotused\n",
"Alustame 30 väärtuse proovivõtmisega ühtlasest jaotusest 0 kuni 9. Samuti arvutame keskmise ja dispersiooni.\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": [
"Selleks, et visuaalselt hinnata, kui palju erinevaid väärtusi proovis on, saame joonistada **histogrammi**:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.hist(sample)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tõelise andmete analüüs\n",
"\n",
"Keskmine ja dispersioon on tõeliste andmete analüüsimisel väga olulised. Laadime andmed pesapallurite kohta saidilt [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": [
"> Me kasutame siin andmete analüüsimiseks paketti [**Pandas**](https://pandas.pydata.org/). Me räägime pandast ja andmetega töötamisest Pythonis selle kursuse edasistes osades rohkem.\n",
"\n",
"Arvutame keskmised väärtused vanuse, pikkuse ja kaalu jaoks:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df[['Age','Height','Weight']].mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nüüd keskendume pikkusele ja arvutame standardhälbe ning dispersiooni:\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": [
"Keskmise kõrval on mõistlik vaadata ka mediaani väärtust ja kvartiile. Neid saab visualiseerida kasutades **kastdiagrammi**:\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": [
"Me saame teha ka kastdiagramme meie andmekogu alamhulkadest, näiteks mängijate rolli järgi rühmitatult.\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": [
"> **Märkus**: See diagramm näitab, et keskmiselt on esimesed esimesed põhitõkkepedjad pikemad kui teised põhitõkkepedjad. Hiljem õpime, kuidas seda hüpoteesi formaalsemalt testida ja kuidas tõestada, et meie andmed on statistiliselt olulised selle näitamiseks. \n",
"\n",
"Vanus, pikkus ja kaal on kõik pidevad juhuslikud muutujad. Mida sa arvad, milline on nende jaotus? Hea viis selle väljaselgitamiseks on joonistada väärtuste histogramm: \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": [
"## Normaaljaotus\n",
"\n",
"Loon kunstliku masside valimi, mis järgib normaaljaotust sama keskmise ja dispersiooniga kui meie tegelikud andmed:\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": [
"Kuna enamik elus olevatest väärtustest on normaalselt jaotunud, ei tohiks me kasutada ühtlast juhuslike arvude generaatorit proovandmete genereerimiseks. Siin on see, mis juhtub, kui proovime kaalusid genereerida ühtlase jaotusega (genereeritud `np.random.rand` abil):\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": [
"## Usaldusvahemikud\n",
"\n",
"Arvutame nüüd pesapallimängijate kehakaalu ja pikkuse usaldusvahemikud. Kasutame koodi [selles stackoverflow arutelus](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": [
"## Hüpoteesi testimine\n",
"\n",
"Uurime erinevaid rolle meie pesapallimängijate andmestikus:\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": [
"Testime hüpoteesi, et esimesed pesamehed on teistest pesameestest pikemad. Kõige lihtsam viis selleks on testida usaldusvahemikke:\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": [
"Saame näha, et intervallid ei kattu.\n",
"\n",
"Statistiliselt korreksem viis hüpoteesi tõestamiseks on kasutada **Studenti t-testi**:\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": [
"Funktsiooni `ttest_ind` tagastatud kaks väärtust on:\n",
"* p-väärtust võib pidada tõenäosuseks, et kaks jaotust omavad sama keskmist väärtust. Meie puhul on see väga madal, mis tähendab, et on tugevad tõendid selle kohta, et esimestel pesuritel on suurem pikkus.\n",
"* t-väärtus on normeeritud keskmise erinevuse vaheväratlus, mida kasutatakse t-testis, ja seda võrreldakse antud usaldusväärtuse künnisega.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Normaalse jaotuse simuleerimine keskväärtusteooreemi abil\n",
"\n",
"Juhuslike arvude generaator Pythonis on loodud tagama ühtlase jaotuse. Kui soovime luua normaaljaotusega generaatori, võime kasutada keskväärtusteooreemi. Normaaljaotusega väärtuse saamiseks arvutame lihtsalt ühtlaselt genereeritud valimi aritmeetilise keskmise.\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": [
"## Korrelatsioon ja Evil Baseball Corp\n",
"\n",
"Korrelatsioon võimaldab meil leida seoseid andmesarjade vahel. Meie mängulises näites kujutame ette, et on kuri pesapallifirma, kes maksab oma mängijatele vastavalt nende pikkusele mida pikem on mängija, seda rohkem raha ta saab. Oletame, et algpalk on 1000 dollarit ning lisaks saab kõrgusest sõltuva boonuse 0 kuni 100 dollarit. Võtame MLB mängijad ja arvutame nende kujuteldavad palgad:\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": [
"Lähme nüüd arvutama nende järjestuste kovariantsust ja korrelatsiooni. Funktsioon `np.cov` annab meile nn **kovariantsusmaatriksi**, mis on kovariantsuse laiendus mitmele muutujaile. Kovariantsusmaatriksi $M$ element $M_{ij}$ on sisendmuutujate $X_i$ ja $X_j$ omavaheline korrelatsioon ning diagonaalväärtused $M_{ii}$ on $X_i$ dispersioon. Samamoodi annab `np.corrcoef` meile **korrelatsioonimaatriksi**.\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": [
"Seos, mis on võrdne 1-ga, tähendab, et kahe muutuja vahel on tugev **lineaarne seos**. Lineaarse seose saab visuaalselt näha, kui ühe väärtuse teise vastu joonistada:\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": [
"Vaatame, mis juhtub, kui seos ei ole lineaarne. Oletame, et meie ettevõte otsustas peita ilmset lineaarset sõltuvust pikkuste ja palkade vahel ning lisas valemisse mõningase mittelineaarsuse, näiteks `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": [
"Selles olukorras on korrelatsioon veidi väiksem, kuid siiski üsna kõrge. Nüüd, et seost veel vähem ilmseks teha, võime soovida palgale lisada natuke juhuslikkust, lisades mõne juhusliku muutuja. Vaatame, mis juhtub:\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": [
"> Kas suudad ära arvata, miks täpid reas ritta vertikaalseteks joonteks moodustuvad?\n",
"\n",
"Oleme täheldanud korrelatsiooni kunstlikult loodud mõiste nagu palk ja täheldatud muutujate *pikkus* vahel. Vaatame ka, kas kaks täheldatud muutujat, nagu pikkus ja kaal, korreleeruvad:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].ffill(),df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Kahjuks me ei saanud ühtegi tulemust ainult mõned kummalised `nan` väärtused. See on tingitud sellest, et mõned meie seeria väärtused on määramata, mida tähistatakse kui `nan`, mis põhjustab operatsiooni tulemuse samuti määramatuks olemise. Vaadates maatriksit näeme, et probleemne veerg on `Weight`, kuna kõrguse väärtuste omakorpus on arvutatud.\n",
"\n",
"> See näide näitab **andmete ettevalmistamise** ja **puhastamise** tähtsust. Ilma korralike andmeteta ei saa me midagi arvutada.\n",
"\n",
"Kasutame `fillna` meetodit, et täita puuduvad väärtused ja arvutame korrelatsiooni:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].fillna(method='pad'), df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tõepoolest on olemas korrelatsioon, kuid mitte nii tugev kui meie kunstlikus näites. Kui vaadata ühte väärtust teise vastu hajuvusdiagrammil, oleks seos palju vähem ilmne:\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": [
"## Kokkuvõte\n",
"\n",
"Selles märkmikus oleme õppinud, kuidas andmetel põhitoiminguid teha, et arvutada statistilisi funktsioone. Nüüd teame, kuidas kasutada matemaatika ja statistika põhjalikku aparatuuri, et mõningaid hüpoteese tõestada ning kuidas arvutada usaldusvahemikke suvalistele muutujatele, kui on olemas andmete valim.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Vastutusest loobumine**: \nSee dokument on tõlgitud tehisintellekti tõlketeenuse [Co-op Translator](https://github.com/Azure/co-op-translator) abil. Kuigi me püüdleme täpsuse poole, palun arvestage, et automaatsed tõlked võivad sisaldada vigu või ebatäpsusi. Originaaldokument tema emakeeles peaks olema autoriteetne allikas. Tähtsate andmete puhul soovitatakse kasutada professionaalset inimtõlget. Me ei vastuta selle tõlke kasutamisest tekkida võivate arusaamatuste või valesti mõistmiste eest.\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-16T22:19:03+00:00",
"source_file": "1-Introduction/04-stats-and-probability/notebook.ipynb",
"language_code": "et"
}
},
"nbformat": 4,
"nbformat_minor": 4
}