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

581 lines
20 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": [
"# הקדמה להסתברות וסטטיסטיקה\n",
"במחברת זו, נשחק עם כמה מהקונספטים שדנו בהם בעבר. רבים מהקונספטים של הסתברות וסטטיסטיקה מיוצגים היטב בספריות מרכזיות לעיבוד נתונים בפייתון, כגון `numpy` ו-`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",
"נתחיל בשרטוט דגימה של 30 ערכים מהתפלגות אחידה מ-0 עד 9. נחשב גם ממוצע ושונות.\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": [
"כדי להעריך ויזואלית כמה ערכים שונים יש בדגימה, אנחנו יכולים לשרטט את ה**היסטוגרמה**:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.hist(sample)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## ניתוח נתונים אמיתיים\n",
"\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": [
"> אנו משתמשים בחבילה בשם [**Pandas**](https://pandas.pydata.org/) כאן לניתוח נתונים. נדבר יותר על Pandas ועל עבודה עם נתונים בפייתון בהמשך הקורס הזה.\n",
"\n",
"בואו נחשב ערכי ממוצע לגיל, גובה ומשקל:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df[['Age','Height','Weight']].mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"עכשיו נתמקד בגובה, ונחשב סטיית תקן ושונות:\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": [
"בנוסף לממוצע, יש הגיון לבחון את הערך החציוני והרבעונים. ניתן להמחיש אותם באמצעות **תרשים תיבתית**:\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": [
"אנחנו יכולים גם להכין דיאגרמת קופסאות של תת-קבוצות ממערכת הנתונים שלנו, למשל, מקובצות לפי תפקיד השחקן.\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": [
"> **הערה**: דיאגרמה זו מציעה כי בממוצע, הגבהים של שחקני הבסיס הראשון גבוהים יותר מהגובה של שחקני הבסיס השני. בהמשך נלמד כיצד ניתן לבדוק השערה זו באופן פורמלי יותר, וכיצד להראות שהנתונים שלנו משמעותיים סטטיסטית כדי להוכיח זאת. \n",
"\n",
"הגיל, הגובה והמשקל הם כולם משתנים אקראיים רציפים. מה אתם חושבים לגבי התפלגותם? דרך טובה לגלות זאת היא על ידי הצגת היסטוגרמת הערכים: \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": [
"## התפלגות נורמלית\n",
"\n",
"בואו ליצור דגימה מלאכותית של משקלים שעוקבת אחרי התפלגות נורמלית עם אותו ממוצע ושונות כמו הנתונים האמיתיים שלנו:\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": [
"מכיוון שרוב הערכים בחיים האמיתיים מתפלגים באופן נורמלי, אין להשתמש במחולל מספרים אקראיים אחיד כדי ליצור נתוני דוגמה. הנה מה שקורה אם ננסה לייצר משקלים עם התפלגות אחידה (שהופקה על ידי `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": [
"## מרווחי אמון\n",
"\n",
"עכשיו נחשב מרווחי אמון למשקלים והגדלים של שחקני בייסבול. נשתמש בקוד [מהדיון ב-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": [
"## בדיקת השערות\n",
"\n",
"בואו נחקור תפקידים שונים במאגר השחקנים שלנו בבייסבול:\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": [
"בוא נבחן את ההשערה ששחקני ה-First Basemen גבוהים יותר משחקני ה-Second Basemen. הדרך הפשוטה ביותר לעשות זאת היא לבחון את מרווחי הביטחון:\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": [
"אנו יכולים לראות שהמרווחים אינם חופפים.\n",
"\n",
"דרך סטטיסטית נכונה יותר להוכחת ההשערה היא להשתמש ב**מבחן t של סטודנט**:\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": [
"שני הערכים שמוחזרים על ידי הפונקציה `ttest_ind` הם:\n",
"* ערך p ניתן להתייחס אליו כהסתברות ששתי ההתפלגויות הן בעלות ממוצע זהה. במקרה שלנו, הוא נמוך מאוד, מה שאומר שיש ראיות חזקות התומכות בכך שהבייסמנים הראשונים גבוהים יותר.\n",
"* ערך t הוא הערך הביניים של ההבדל הממוצע המנורמל שנעשה בו שימוש במבחן t, והוא מושווה לערך סף עבור ערך בטחון נתון.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## סימולציה של התפלגות נורמלית עם משפט הגבול המרכזי\n",
"\n",
"הגנרטור הפסאודו-אקראי בפייתון מיועד לספק לנו התפלגות אחידה. אם נרצה ליצור גנרטור להתפלגות נורמלית, נוכל להשתמש במשפט הגבול המרכזי. כדי לקבל ערך שמתפלג באופן נורמלי פשוט נחשב את הממוצע של דגימה שנוצרה באופן אחיד.\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": [
"## קורלציה ו-Evil Baseball Corp\n",
"\n",
"קורלציה מאפשרת לנו למצוא קשרים בין רצפי נתונים. בדוגמת הצעצוע שלנו, נניח שיש תאגיד בייסבול מרושע שמשלם לשחקנים שלו בהתאם לגובהם - ככל שהשחקן גבוה יותר, הוא מקבל יותר כסף. נניח שיש שכר בסיס של 1000$, ובונוס נוסף מ-0$ עד 100$, תלוי בגובה. ניקח את השחקנים האמיתיים מ-MLB, ונחשב את המשכורות הדמיוניות שלהם:\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": [
"כעת נחשב את הקווריאנס והמתאם של הרצפים הללו. `np.cov` ייתן לנו את ה\"matrix הקווריאנס\", שהוא הרחבה של הקווריאנס למספר משתנים. האלמנט $M_{ij}$ במטריצת הקווריאנס $M$ הוא הקורלציה בין המשתנים $X_i$ ו-$X_j$, והערכים האלכסוניים $M_{ii}$ הם השונות של $X_{i}$. בדומה לכך, `np.corrcoef` תיתן לנו את מטריצת המתאם.\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": [
"קורלציה השווה ל-1 משמעותה שיש קשר **קוֹווי חָזָק** בין שני משתנים. ניתן לראות את הקשר הקווי באופן חזותי על ידי גרירת ערך אחד נגד השני:\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": [
"בוא נראה מה קורה אם הקשר לא יהיה ליניארי. נניח שהחברה שלנו החליטה להסתיר את התלות הליניארית הברורה בין גבהים למשכורות, והכניסה אלמנט של אי-ליניאריות לנוסחה, כמו `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": [
"במקרה זה, המתאם קטן במעט, אך הוא עדיין גבוה למדי. עכשיו, כדי להפוך את הקשר לפחות ברור, אנו עשויים לרצות להוסיף קצת אקראיות נוספת על ידי הוספת משתנה אקראי לשכר. בואו נראה מה קורה:\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": [
"> האם אתה יכול לנחש מדוע הנקודות מסתדרות לקווים אנכיים כאלו?\n",
"\n",
"צפינו בקורלציה בין מושג מהונדס מלאכותית כמו שכר והמשתנה הנצפה *גובה*. בואו נראה גם אם שני המשתנים הנצפים, כמו גובה ומשקל, מתאמים גם כן:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].ffill(),df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"למרבה הצער, לא קיבלנו שום תוצאות - רק ערכי `nan` מוזרים. זה נובע מכך שחלק מהערכים בסדרה שלנו אינם מוגדרים, מיוצגים כ-`nan`, מה שגורם לתוצאה של הפעולה להיות גם היא בלתי מוגדרת. על ידי מבט במטריצה ניתן לראות ש`Weight` הוא העמודה הבעייתית, כי חושבה קורלציה עצמית בין ערכי `Height`.\n",
"\n",
"> דוגמה זו מדגימה את חשיבות **הכנת הנתונים** ו**ניקויים**. ללא נתונים מתאימים לא נוכל לחשב כלום.\n",
"\n",
"בואו נשתמש בשיטה `fillna` למילוי הערכים החסרים, ונחשב את הקורלציה:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].fillna(method='pad'), df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"קיימת אכן מתאם, אך לא כזה חזק כמו בדוגמה המלאכותית שלנו. אכן, אם נסתכל על תרשים פיזור של ערך אחד כנגד השני, הקשר יהיה הרבה פחות ברור:\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": [
"## סיכום\n",
"\n",
"במחברת זו למדנו כיצד לבצע פעולות בסיסיות על נתונים כדי לחשב פונקציות סטטיסטיות. אנו כעת יודעים כיצד להשתמש במערכת מתמטית וסטטיסטית חזקה על מנת להוכיח השערות מסוימות, וכיצד לחשב אינטרוולים של ביטחון עבור משתנים אקראיים בהתבסס על מדגם נתונים.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**הצהרת אי-אחריות**: \nמסמך זה תורגם באמצעות שירות תרגום מבוסס בינה מלאכותית [Co-op Translator](https://github.com/Azure/co-op-translator). למרות שאנו שואפים לדיוק, יש לקחת בחשבון שתרגומים אוטומטיים עשויים להכיל שגיאות או אי-דיוקים. המסמך המקורי בשפת המקור שלו נחשב למקור הסמכותי. למידע קריטי מומלץ להשתמש בתרגום מקצועי של מתרגם אנושי. אנו לא נישא באחריות על הבנות שגויות או פרשנויות מוטעות הנובעות משימוש בתרגום זה.\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-16T16:44:10+00:00",
"source_file": "1-Introduction/04-stats-and-probability/notebook.ipynb",
"language_code": "he"
}
},
"nbformat": 4,
"nbformat_minor": 4
}