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/sv/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": [
"# Introduktion till sannolikhet och statistik\n",
"I denna anteckningsbok kommer vi att leka med några av de koncept som vi tidigare har diskuterat. Många koncept från sannolikhet och statistik är väl representerade i stora bibliotek för databehandling i Python, såsom `numpy` och `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": [
"## Slumpmässiga variabler och fördelningar\n",
"Låt oss börja med att dra ett stickprov på 30 värden från en uniform fördelning från 0 till 9. Vi kommer också att beräkna medelvärde och varians.\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": [
"För att visuellt uppskatta hur många olika värden som finns i urvalet kan vi rita ett **histogram**:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.hist(sample)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Analysera verkliga data\n",
"\n",
"Medelvärde och varians är mycket viktiga när man analyserar verkliga data. Låt oss ladda data om basebollspelare från [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": [
"> Vi använder ett paket som heter [**Pandas**](https://pandas.pydata.org/) här för dataanalys. Vi kommer att prata mer om Pandas och att arbeta med data i Python senare i den här kursen.\n",
"\n",
"Låt oss beräkna genomsnittsvärden för ålder, längd och vikt:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df[['Age','Height','Weight']].mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Låt oss nu fokusera på höjd och beräkna standardavvikelse och varians:\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": [
"Förutom medelvärdet är det meningsfullt att titta på medianvärdet och kvartilerna. De kan visualiseras med ett **låddiagram**:\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": [
"Vi kan också göra låddiagram av delmängder av vår dataset, till exempel grupperade efter spelarroll.\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": [
"> **Notera**: Detta diagram antyder att första basmän generellt är längre än andra basmän. Senare kommer vi att lära oss hur vi kan testa denna hypotes mer formellt, och hur vi kan visa att våra data är statistiskt signifikanta för att påvisa detta. \n",
"\n",
"Ålder, längd och vikt är alla kontinuerliga stokastiska variabler. Vad tror du att deras fördelning är? Ett bra sätt att ta reda på det är att plotta histogrammet av värdena: \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": [
"## Normalfördelning\n",
"\n",
"Låt oss skapa ett artificiellt urval av vikter som följer en normalfördelning med samma medelvärde och varians som våra verkliga 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": [
"Eftersom de flesta värden i verkliga livet är normalt fördelade, bör vi inte använda en uniform slumptalsgenerator för att generera provdata. Här är vad som händer om vi försöker generera vikter med en uniform fördelning (genererad av `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": [
"## Konfidensintervall\n",
"\n",
"Låt oss nu beräkna konfidensintervall för vikterna och längderna hos basebollspelare. Vi kommer att använda koden [från denna stackoverflow-diskussion](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": [
"## Hypotesprövning\n",
"\n",
"Låt oss utforska olika roller i vår basebollspelar-dataset:\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": [
"Låt oss testa hypotesen att försteklassmän är längre än andraklassmän. Det enklaste sättet att göra detta är att testa konfidensintervallen:\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": [
"Vi kan se att intervallen inte överlappar.\n",
"\n",
"Ett statistiskt mer korrekt sätt att bevisa hypotesen är att använda ett **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": [
"De två värdena som returneras av funktionen `ttest_ind` är:\n",
"* p-värdet kan betraktas som sannolikheten för att två fördelningar har samma medelvärde. I vårt fall är det mycket lågt, vilket betyder att det finns starka bevis som stöder att förstebasmän är längre.\n",
"* t-värdet är det mellanliggande värdet av normaliserad medelskillnad som används i t-testet, och det jämförs med ett tröskelvärde för ett givet konfidensvärde.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Simulera en normalfördelning med centrala gränsvärdessatsen\n",
"\n",
"Den pseudotillfälliga generatorn i Python är utformad för att ge oss en jämn fördelning. Om vi vill skapa en generator för normalfördelning kan vi använda centrala gränsvärdessatsen. För att få ett normalt fördelat värde beräknar vi helt enkelt medelvärdet av ett uniformt genererat urval.\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": [
"## Korrelations- och Evil Baseball Corp\n",
"\n",
"Korrelations möjliggör för oss att hitta relationer mellan datasekvenser. I vårt leksaksexempel, låtsas att det finns ett ondskefullt basebollföretag som betalar sina spelare utifrån deras längd - ju längre spelaren är, desto mer pengar får han/hon. Antag att det finns en grundlön på 1000 dollar, och en extra bonus från 0 till 100 dollar, beroende på längd. Vi tar riktiga spelare från MLB och beräknar deras imaginära löner:\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åt oss nu beräkna kovarians och korrelation för dessa sekvenser. `np.cov` ger oss en så kallad **kovariansmatris**, som är en utvidgning av kovarians till flera variabler. Elementet $M_{ij}$ i kovariansmatrisen $M$ är en korrelation mellan indata variablerna $X_i$ och $X_j$, och diagonala värden $M_{ii}$ är variansen för $X_{i}$. På samma sätt ger `np.corrcoef` oss **korrelationsmatrisen**.\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": [
"En korrelation som är lika med 1 betyder att det finns en stark **linjär relation** mellan två variabler. Vi kan visuellt se den linjära relationen genom att plotta ett värde mot det andra:\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åt oss se vad som händer om relationen inte är linjär. Anta att vårt företag beslutade att dölja det uppenbara linjära sambandet mellan längder och löner, och införde någon icke-linjär funktion i formeln, som till exempel `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": [
"I det här fallet är korrelationen något mindre, men den är fortfarande ganska hög. Nu, för att göra sambandet ännu mindre uppenbart, kanske vi vill lägga till lite extra slumpmässighet genom att lägga till en slumpvariabel till lönen. Låt oss se vad som händer:\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": [
"> Kan du gissa varför prickarna bildar vertikala linjer på detta sätt?\n",
"\n",
"Vi har observerat sambandet mellan ett konstgjort framtaget koncept som lön och den observerade variabeln *längd*. Låt oss även se om de två observerade variablerna, såsom längd och vikt, korrelerar också:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].ffill(),df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tyvärr fick vi inga resultat endast några märkliga `nan`-värden. Detta beror på att några av värdena i vår serie är odefinierade, representerade som `nan`, vilket gör att resultatet av operationen också blir odefinierat. Genom att titta på matrisen kan vi se att `Weight` är den problematiska kolumnen, eftersom självkorrelationen mellan `Height`-värden har beräknats.\n",
"\n",
"> Detta exempel visar vikten av **datapreparering** och **rengöring**. Utan korrekt data kan vi inte beräkna något.\n",
"\n",
"Låt oss använda metoden `fillna` för att fylla i de saknade värdena och beräkna korrelationen:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].fillna(method='pad'), df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Det finns faktiskt en korrelation, men inte en så stark som i vårt artificiella exempel. Om vi tittar på spridningsdiagrammet för ett värde mot det andra, skulle relationen vara mycket mindre uppenbar:\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": [
"## Slutsats\n",
"\n",
"I denna anteckningsbok har vi lärt oss hur man utför grundläggande operationer på data för att beräkna statistiska funktioner. Vi vet nu hur man använder ett gediget verktyg av matematik och statistik för att bevisa några hypoteser, och hur man beräknar konfidensintervall för godtyckliga variabler baserat på ett dataurval.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Ansvarsfriskrivning**:\nDetta dokument har översatts med hjälp av AI-översättningstjänsten [Co-op Translator](https://github.com/Azure/co-op-translator). Även om vi strävar efter noggrannhet, bör du vara medveten om att automatiska översättningar kan innehålla fel eller brister. Det ursprungliga dokumentet på dess ursprungliga språk bör betraktas som den auktoritativa källan. För kritisk information rekommenderas professionell mänsklig översättning. Vi ansvarar inte för några missförstånd eller feltolkningar som uppstår vid användning av denna översättning.\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-16T14:49:49+00:00",
"source_file": "1-Introduction/04-stats-and-probability/notebook.ipynb",
"language_code": "sv"
}
},
"nbformat": 4,
"nbformat_minor": 4
}