akshayka commited on
Commit
7dbab16
·
unverified ·
2 Parent(s): fbf7945 be869a0

Merge pull request #35 from marimo-team/haleshot/05_independence

Browse files
Files changed (1) hide show
  1. probability/05_independence.py +440 -0
probability/05_independence.py ADDED
@@ -0,0 +1,440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # /// script
2
+ # requires-python = ">=3.10"
3
+ # dependencies = [
4
+ # "marimo",
5
+ # ]
6
+ # ///
7
+
8
+ import marimo
9
+
10
+ __generated_with = "0.11.4"
11
+ app = marimo.App()
12
+
13
+
14
+ @app.cell
15
+ def _():
16
+ import marimo as mo
17
+ return (mo,)
18
+
19
+
20
+ @app.cell(hide_code=True)
21
+ def _(mo):
22
+ mo.md(
23
+ """
24
+ # Independence in Probability Theory
25
+
26
+ _This notebook is a computational companion to the book ["Probability for Computer Scientists"](https://chrispiech.github.io/probabilityForComputerScientists/en/part1/independence/), by Stanford professor Chris Piech._
27
+
28
+ In probability theory, independence is a fundamental concept that helps us understand
29
+ when events don't influence each other. Two events are independent if knowing the
30
+ outcome of one event doesn't change our belief about the other event occurring.
31
+
32
+ ## Definition of Independence
33
+
34
+ Two events $E$ and $F$ are independent if:
35
+
36
+ $$P(E|F) = P(E)$$
37
+
38
+ This means that knowing $F$ occurred doesn't change the probability of $E$ occurring.
39
+
40
+ ### _Alternative Definition_
41
+
42
+ Using the chain rule, we can derive another equivalent definition:
43
+
44
+ $$P(E \cap F) = P(E) \cdot P(F)$$
45
+ """
46
+ )
47
+ return
48
+
49
+
50
+ @app.cell(hide_code=True)
51
+ def _(mo):
52
+ mo.md(
53
+ r"""
54
+ ## Independence is Symmetric
55
+
56
+ This property is symmetric: if $E$ is independent of $F$, then $F$ is independent of $E$.
57
+ We can prove this using Bayes' Theorem:
58
+
59
+ \[P(E|F) = \frac{P(F|E)P(E)}{P(F)}\]
60
+
61
+ \[= \frac{P(F)P(E)}{P(F)}\]
62
+
63
+ \[= P(E)\]
64
+
65
+ ## Independence and Complements
66
+
67
+ Given independent events $A$ and $B$, we can prove that $A$ and $B^C$ are also independent:
68
+
69
+
70
+ \[P(AB^C) = P(A) - P(AB)\]
71
+
72
+ \[= P(A) - P(A)P(B)\]
73
+
74
+ \[= P(A)(1 - P(B))\]
75
+
76
+ \[= P(A)P(B^C)\]
77
+
78
+ ## Generalized Independence
79
+
80
+ Events $E_1, E_2, \ldots, E_n$ are independent if for every subset with $r$ elements (where $r \leq n$):
81
+
82
+ \[P(E_1, E_2, \ldots, E_r) = \prod_{i=1}^r P(E_i)\]
83
+
84
+ For example, consider getting 5 heads on 5 coin flips. Let $H_i$ be the event that the $i$th flip is heads:
85
+
86
+
87
+ \[P(H_1, H_2, H_3, H_4, H_5) = P(H_1)P(H_2)P(H_3)P(H_4)P(H_5)\]
88
+
89
+ \[= \prod_{i=1}^5 P(H_i)\]
90
+
91
+ \[= \left(\frac{1}{2}\right)^5 = 0.03125\]
92
+
93
+ ## Conditional Independence
94
+
95
+ Events $E_1, E_2, E_3$ are conditionally independent given event $F$ if:
96
+
97
+ \[P(E_1, E_2, E_3 | F) = P(E_1|F)P(E_2|F)P(E_3|F)\]
98
+
99
+ This can be written more succinctly using product notation:
100
+
101
+ \[P(E_1, E_2, E_3 | F) = \prod_{i=1}^3 P(E_i|F)\]
102
+ """
103
+ )
104
+ return
105
+
106
+
107
+ @app.cell(hide_code=True)
108
+ def _(mo):
109
+ callout_text = mo.md(r"""While the rules of probability stay the same when conditioning on an event, the independence
110
+ property between events might change. Events that were dependent can become independent when
111
+ conditioning on an event. Events that were independent can become dependent.
112
+
113
+ For example, if events $E_1, E_2, E_3$ are conditionally independent given event $F$,
114
+ it is not necessarily true that:
115
+
116
+ $$P(E_1,E_2,E_3) = \prod_{i=1}^3 P(E_i)$$
117
+
118
+ as we are no longer conditioning on $F$.
119
+ """)
120
+ mo.callout(
121
+ callout_text,
122
+ kind="warn"
123
+ )
124
+ return (callout_text,)
125
+
126
+
127
+ @app.cell
128
+ def _():
129
+ def check_independence(p_e, p_f, p_intersection):
130
+ expected = p_e * p_f
131
+ tolerance = 1e-5 # Stricter tolerance for comparison
132
+
133
+ return abs(p_intersection - expected) < tolerance
134
+ return (check_independence,)
135
+
136
+
137
+ @app.cell
138
+ def _(check_independence, mo):
139
+ # Example 1: Rolling dice
140
+ p_first_even = 0.5 # P(First die is even)
141
+ p_second_six = 1/6 # P(Second die is 6)
142
+ p_both = 1/12 # P(First even AND second is 6)
143
+ dice_independent = check_independence(p_first_even, p_second_six, p_both)
144
+ example1 = f"""
145
+ #### 1. Rolling Two Dice 🎲
146
+
147
+ - P(First die is even) = {p_first_even:.3f}
148
+ - P(Second die shows 6) = {p_second_six:.3f}
149
+ - P(Both events occur) = {p_both:.3f}
150
+
151
+ **Result**: Events are {'independent' if dice_independent else 'dependent'}
152
+
153
+ <details>
154
+ <summary>Why?</summary>
155
+ Rolling dice are independent events because the outcome of one die doesn't affect the other.
156
+ The probability of getting a 6 on the second die (1/6) remains the same regardless of what shows on the first die. This is why P(Both) = 1/12, which equals P(First even) * P(Second is 6) = 0.5 * 1/6.
157
+ </details>
158
+ """
159
+ mo.md(example1)
160
+ return dice_independent, example1, p_both, p_first_even, p_second_six
161
+
162
+
163
+ @app.cell
164
+ def _(check_independence, mo):
165
+ # Example 2: Drawing cards (dependent events)
166
+ p_first_heart = 13/52 # P(First card is heart)
167
+ p_second_heart = 12/51 # P(Second card is heart | First was heart)
168
+
169
+ # For dependent events, P(A∩B) = P(A) * P(B|A)
170
+ p_both_hearts = (13/52) * (12/51) # Joint probability = 0.059
171
+
172
+ # If events were independent, we'd expect:
173
+ theoretical_if_independent = (13/52) * (13/52) # = 0.0625
174
+
175
+ # Test independence by comparing actual joint probability with theoretical independent probability
176
+ cards_independent = check_independence(13/52, 13/52, p_both_hearts)
177
+
178
+ example2 = f"""
179
+ #### 2. Drawing Cards Without Replacement ♥️
180
+ - P(First card is heart) = {p_first_heart:.3f}
181
+ - P(Second card is heart | First was heart) = {p_second_heart:.3f}
182
+ - P(Both cards are hearts) = {p_both_hearts:.3f}
183
+ - If independent, P(Both hearts) would be = {theoretical_if_independent:.3f}
184
+
185
+ **Result**: Events are {'independent' if cards_independent else 'dependent'}
186
+
187
+ <details>
188
+ <summary>Why?</summary>
189
+ Drawing cards without replacement makes events dependent. The probability of getting
190
+ a second heart (12/51 ≈ 0.235) is less than the first (13/52 = 0.25) because there's one fewer heart available. This makes the actual probability of both hearts (0.059) less than what we'd
191
+ expect if the events were independent (0.063).
192
+ </details>
193
+ """
194
+ mo.md(example2)
195
+ return (
196
+ cards_independent,
197
+ example2,
198
+ p_both_hearts,
199
+ p_first_heart,
200
+ p_second_heart,
201
+ theoretical_if_independent,
202
+ )
203
+
204
+
205
+ @app.cell
206
+ def _(check_independence, mo):
207
+ # Example 3: Computer system
208
+ p_hardware = 0.02 # P(Hardware failure)
209
+ p_software = 0.03 # P(Software crash)
210
+ p_both_failure = 0.0006 # P(Both failures)
211
+ system_independent = check_independence(p_hardware, p_software, p_both_failure)
212
+ example3 = f"""
213
+ #### 3. Computer System Failures 💻
214
+
215
+ - P(Hardware failure) = {p_hardware:.3f}
216
+ - P(Software crash) = {p_software:.3f}
217
+ - P(Both failures occur) = {p_both_failure:.3f}
218
+
219
+ **Result**: Events are {'independent' if system_independent else 'dependent'}
220
+
221
+ <details>
222
+ <summary>Why?</summary>
223
+ Computer hardware and software failures are typically independent because they often have different root causes. Hardware failures might be due to physical issues (heat, power), while software crashes come from programming bugs. This is why P(Both) = 0.0006, which equals P(Hardware) * P(Software) = 0.02 * 0.03.
224
+ </details>
225
+ """
226
+ mo.md(example3)
227
+ return (
228
+ example3,
229
+ p_both_failure,
230
+ p_hardware,
231
+ p_software,
232
+ system_independent,
233
+ )
234
+
235
+
236
+ @app.cell(hide_code=True)
237
+ def _(mo):
238
+ mo.md(
239
+ """
240
+ ## Establishing Independence
241
+
242
+ In practice, we can establish independence through:
243
+
244
+ 1. **Mathematical Verification**: Show that P(E∩F) = P(E)P(F)
245
+ 2. **Empirical Testing**: Analyze data to check if events appear independent
246
+ 3. **Domain Knowledge**: Use understanding of the system to justify independence
247
+
248
+ > **Note**: Perfect independence is rare in real data. We often make independence assumptions
249
+ when dependencies are negligible and the simplification is useful.
250
+
251
+ ## Backup Systems in Space Missions
252
+
253
+ Consider a space mission with two backup life support systems:
254
+
255
+ $$P(\text{Primary fails}) = p_1$$
256
+
257
+ $$P(\text{Secondary fails}) = p_2$$
258
+
259
+ If the systems are truly independent (different power sources, separate locations, distinct technologies):
260
+
261
+ $$P(\text{Life support fails}) = p_1p_2$$
262
+
263
+ For example:
264
+
265
+ - If $p_1 = 0.01$ and $p_2 = 0.02$ (99% and 98% reliable)
266
+ - Then $P(\text{Total failure}) = 0.0002$ (99.98% reliable)
267
+
268
+ However, if both systems share vulnerabilities (same radiation exposure, temperature extremes):
269
+
270
+ $$P(\text{Life support fails}) > p_1p_2$$
271
+
272
+ This example shows why space agencies invest heavily in ensuring true independence of backup systems.
273
+ """
274
+ )
275
+ return
276
+
277
+
278
+ @app.cell(hide_code=True)
279
+ def _(mo):
280
+ mo.md(r"""## Interactive Example""")
281
+ return
282
+
283
+
284
+ @app.cell
285
+ def _(flip_button, mo, reset_button):
286
+ mo.hstack([flip_button, reset_button], justify='center')
287
+ return
288
+
289
+
290
+ @app.cell(hide_code=True)
291
+ def _(mo):
292
+ flip_button = mo.ui.run_button(label="Flip Coins!", kind="info")
293
+ reset_button = mo.ui.run_button(label="Reset", kind="danger")
294
+ stats_display = mo.md("*Click 'Flip Coins!' to start simulation*")
295
+ return flip_button, reset_button, stats_display
296
+
297
+
298
+ @app.cell(hide_code=True)
299
+ def _(flip_button, mo, np, reset_button):
300
+ if reset_button.value or not flip_button.value:
301
+ mo.md("*Click 'Flip Coins!' to start simulation*")
302
+ if flip_button.value:
303
+ coin1 = "H" if np.random.random() < 0.5 else "T"
304
+ coin2 = "H" if np.random.random() < 0.5 else "T"
305
+
306
+ # Calculate probabilities for this flip
307
+ p_h1 = 1 if coin1 == "H" else 0
308
+ p_h2 = 1 if coin2 == "H" else 0
309
+ p_both_h = 1 if (coin1 == "H" and coin2 == "H") else 0
310
+ p_product = p_h1 * p_h2
311
+
312
+ stats = f"""
313
+ # Current Flip Results
314
+
315
+ **Individual Probabilities:**
316
+
317
+ - P(Heads on Coin 1) = {p_h1:.3f}
318
+ - P(Heads on Coin 2) = {p_h2:.3f}
319
+
320
+ **Testing Independence:**
321
+
322
+ - P(Both Heads) = {p_both_h:.3f}
323
+ - P(H₁)P(H₂) = {p_product:.3f}
324
+
325
+ **Are they independent?**
326
+ The events appear {'independent' if abs(p_both_h - p_product) < 0.1 else 'dependent'}
327
+ (difference: {abs(p_both_h - p_product):.3f})
328
+
329
+ **Current Flip:**
330
+
331
+ | Coin 1 | Coin 2 |
332
+ |--------|--------|
333
+ | {coin1} | {coin2} |
334
+ """
335
+ else:
336
+ stats = "*Click 'Flip Coins!' to start simulation*"
337
+
338
+ new_stats_display = mo.md(stats)
339
+ new_stats_display
340
+ return (
341
+ coin1,
342
+ coin2,
343
+ new_stats_display,
344
+ p_both_h,
345
+ p_h1,
346
+ p_h2,
347
+ p_product,
348
+ stats,
349
+ )
350
+
351
+
352
+ @app.cell(hide_code=True)
353
+ def _(mo):
354
+ mo.md(
355
+ """
356
+ ## Understanding the Simulation
357
+
358
+ This simulation demonstrates independence using coin flips, where each coin's outcome is unaffected by the other.
359
+
360
+ ### Reading the Results
361
+
362
+ 1. **Individual Probabilities:**
363
+
364
+ - P(H₁): 1 if heads, 0 if tails on first coin
365
+ - P(H₂): 1 if heads, 0 if tails on second coin
366
+
367
+ 2. **Testing Independence:**
368
+
369
+ - P(Both Heads): 1 if both show heads, 0 otherwise
370
+ - P(H₁)P(H₂): Product of individual results
371
+
372
+ > **Note**: Each click performs a new independent trial. While a single flip shows binary outcomes (0 or 1),
373
+ the theoretical probability is 0.5 for each coin and 0.25 for both heads.
374
+ """
375
+ )
376
+ return
377
+
378
+
379
+ @app.cell(hide_code=True)
380
+ def _(mo):
381
+ mo.md(
382
+ r"""
383
+ ## 🤔 Test Your Understanding
384
+
385
+ Which of these statements about independence are true?
386
+
387
+ <details>
388
+ <summary>If P(E|F) = P(E), then E and F are independent</summary>
389
+ ✅ True! This is one definition of independence - knowing F occurred doesn't change the probability of E.
390
+ </details>
391
+
392
+ <details>
393
+ <summary>Independent events cannot occur simultaneously</summary>
394
+ ❌ False! Independent events can and do occur together - their joint probability is just the product of their individual probabilities.
395
+ </details>
396
+
397
+ <details>
398
+ <summary>If P(E∩F) = P(E)P(F), then E and F are independent</summary>
399
+ ✅ True! This is the multiplicative definition of independence.
400
+ </details>
401
+
402
+ <details>
403
+ <summary>Independence is symmetric: if E is independent of F, then F is independent of E</summary>
404
+ ✅ True! The definition P(E∩F) = P(E)P(F) is symmetric in E and F.
405
+ </details>
406
+
407
+ <details>
408
+ <summary>Three events being pairwise independent means they are mutually independent</summary>
409
+ ❌ False! Pairwise independence doesn't guarantee mutual independence - we need to check all combinations.
410
+ </details>
411
+ """
412
+ )
413
+ return
414
+
415
+
416
+ @app.cell(hide_code=True)
417
+ def _(mo):
418
+ mo.md(
419
+ """
420
+ ## Summary
421
+
422
+ In this exploration of probability independence, we've discovered how to recognize when events truly don't influence each other. Through the lens of both mathematical definitions and interactive examples, we've seen how independence manifests in scenarios ranging from simple coin flips to critical system designs.
423
+
424
+ The power of independence lies in its simplicity: when events are independent, we can multiply their individual probabilities to understand their joint behavior. Yet, as our examples showed, true independence is often more nuanced than it first appears. What seems independent might harbor hidden dependencies, and what appears dependent might be independent under certain conditions.
425
+
426
+ _The art lies not just in calculating probabilities, but in developing the intuition to recognize independence in real-world scenarios—a skill essential for making informed decisions in uncertain situations._
427
+ """
428
+ )
429
+ return
430
+
431
+
432
+ @app.cell
433
+ def _():
434
+ import numpy as np
435
+ import pandas as pd
436
+ return np, pd
437
+
438
+
439
+ if __name__ == "__main__":
440
+ app.run()