helboukkouri commited on
Commit
221534d
·
1 Parent(s): 1bc3bf3

initial commit

Browse files
Files changed (3) hide show
  1. README.md +4 -3
  2. app.py +218 -0
  3. requirements.txt +198 -0
README.md CHANGED
@@ -1,6 +1,6 @@
1
  ---
2
- title: Probability Basics Pt2
3
- emoji: 🌍
4
  colorFrom: gray
5
  colorTo: purple
6
  sdk: gradio
@@ -10,4 +10,5 @@ pinned: false
10
  license: apache-2.0
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: Probability Basics (Pt. 2)
3
+ emoji: 🎲
4
  colorFrom: gray
5
  colorTo: purple
6
  sdk: gradio
 
10
  license: apache-2.0
11
  ---
12
 
13
+
14
+ Continue building towards a better understanding of Probability Theory with the introduction of the three `axioms of probability`.
app.py ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import gradio as gr
3
+
4
+ OUTCOMES = [1, 2, 3, 4, 5, 6]
5
+
6
+
7
+ # Function to simulate a simple die roll experiment
8
+ def roll_die():
9
+ result = random.choice(OUTCOMES)
10
+ return result
11
+
12
+ # Roll the die and check if the result is even
13
+ def test_event():
14
+ result = roll_die()
15
+ return result, "Yes!" if result % 2 == 0 else "No.."
16
+
17
+ # Make sure inputs are correct
18
+ def check_inputs(favorable_outcomes, possible_outcomes, test_subset=False):
19
+ if favorable_outcomes == "" or possible_outcomes == "":
20
+ raise Exception("Please input the set of favorable and possible outcomes")
21
+
22
+ favorable_outcomes = favorable_outcomes.split(",")
23
+ possible_outcomes = possible_outcomes.split(",")
24
+
25
+ try:
26
+ favorable_outcomes = list(map(int, favorable_outcomes))
27
+ except ValueError:
28
+ raise Exception("Please input a valid set of favorable outcomes")
29
+
30
+ try:
31
+ possible_outcomes = list(map(int, possible_outcomes))
32
+ except ValueError:
33
+ raise Exception("Please input a valid set of possible outcomes")
34
+
35
+ if test_subset:
36
+ if not set(favorable_outcomes).issubset(set(possible_outcomes)):
37
+ raise Exception("Favorable outcomes should be a subset of possible outcomes")
38
+ return favorable_outcomes, possible_outcomes
39
+
40
+ # Compute the probability of an event
41
+ def compute_event_probability(favorable_outcomes, possible_outcomes):
42
+ try:
43
+ favorable_outcomes, possible_outcomes = check_inputs(favorable_outcomes, possible_outcomes, test_subset=True)
44
+ except Exception as e:
45
+ return str(e)
46
+
47
+ probability = len(favorable_outcomes) / len(possible_outcomes)
48
+ return probability
49
+
50
+ # Produce randomized favorable and possible outcomes
51
+ def randomize_outcomes():
52
+ n_favorable_outcomes = random.randint(1, 6)
53
+ favorable_outcomes = random.sample(OUTCOMES, n_favorable_outcomes)
54
+ possible_outcomes = OUTCOMES
55
+ return ",".join(map(str, favorable_outcomes)), ",".join(map(str, possible_outcomes))
56
+
57
+ # Join two events
58
+ def join_events(event_a, event_b):
59
+ try:
60
+ event_a, event_b = check_inputs(event_a, event_b)
61
+ except Exception as e:
62
+ return str(e)
63
+
64
+ event_a_or_b = sorted(set(event_a + event_b))
65
+ return ",".join(map(str, event_a_or_b))
66
+
67
+
68
+ # Create a Gradio interface
69
+ css = """
70
+ .gradio-container {
71
+ width: 40%!important;
72
+ min-width: 800px;
73
+ }
74
+ """
75
+ with gr.Blocks(css=css) as demo:
76
+ gr.Markdown(
77
+ """
78
+ # Probability Basics (Pt. 2)
79
+ <div align="center">
80
+ <br>
81
+ <p>Let's learn about more fundamental principles of Probability theory!</p>
82
+ <br>
83
+ </div>
84
+
85
+ Welcome to this new segment of the Probability Basics series! 🎉
86
+ - first, we introduce the core principles, known as `axioms`, that shape the mathematical foundation for probability calculations;
87
+ - then, we will explore the concept of `probability distributions` and how they are used to describe the likelihood of random events.
88
+ """
89
+ )
90
+ gr.Markdown(
91
+ r"""
92
+ ## Axioms of Probability
93
+ In order to start working with more complex probability problems, we need to establish a set of `axioms` that will guide our calculations.
94
+
95
+ Just like in geometry, where we first accept general rules like `two parallel lines never meet` before starting to deal for larger problems; or in algebra, where we accept that `a number multiplied by zero is zero` before solving equations, we need to establish some general rules for probability theory as well.
96
+
97
+ ### Axiom 1: Non-negativity
98
+ *The probability of an event is always a non-negative number. That is, it is always `greater than or equal to zero`.*
99
+ $$\text{For any Event:} \quad P(\text{Event}) \geq 0 $$
100
+
101
+ This is because the probability of an event is a [measure](https://en.wikipedia.org/wiki/Measure_(mathematics)) of how likely it is to occur, it can be seen as the ratio of favorable outcomes to possible outcomes, and that, for all intents and purposes, is assumed to always be a positive (or zero) number.
102
+ """
103
+ )
104
+ with gr.Column():
105
+ with gr.Row():
106
+ randomize = gr.Button(value="Randomize favorable outcomes")
107
+ probability = gr.Button(value="Compute")
108
+ with gr.Row():
109
+ with gr.Column():
110
+ favorable_outcomes = gr.Textbox(label="Favorable Outcomes", value="2, 4, 6")
111
+ possible_outcomes = gr.Textbox(label="Possible Outcomes", value="1, 2, 3, 4, 5, 6")
112
+ with gr.Column():
113
+ probability_output = gr.Textbox(label="Probability", placeholder="", interactive=False)
114
+ static_probability_output = gr.Textbox(label="Is the probability positive?", placeholder="", interactive=False)
115
+ probability_output.change(lambda: "Yes!", [], [static_probability_output])
116
+ randomize.click(randomize_outcomes, [], [favorable_outcomes, possible_outcomes])
117
+ probability.click(
118
+ lambda a, b: f"The probability of the event is: {compute_event_probability(a, b):.0%}",
119
+ [favorable_outcomes, possible_outcomes], [probability_output]
120
+ )
121
+
122
+ gr.Markdown(
123
+ r"""
124
+ ### Axiom 2: Total Probability
125
+ *The probability of the entire `sample space` is always equal to `1` (or in other words `100%`).*
126
+ $$\text{For any Sample Space:} \quad P(\text{Sample Space}) = 1 $$
127
+
128
+ If we look back at the definition of the `sample space`, we can see that it contains **all possible outcomes**. This means that the probability of the **entire sample space** is the same as the probability of **all possible outcomes combined**, which is the same as the probability of the event `something happens` which is always certain to happen.
129
+
130
+ When dealing with a six-sided die, the probability of getting any of the possible faces is always `1`.<br>(assuming it cannot land on its edge or something else 😅)
131
+ """
132
+ )
133
+
134
+ with gr.Column():
135
+ with gr.Row():
136
+ randomize_total_probability = gr.Button(value="Randomize possible outcomes")
137
+ total_probability = gr.Button(value="Compute")
138
+ with gr.Row():
139
+ with gr.Column():
140
+ all_possible_outcomes = gr.Textbox(label="Favorable Outcomes", value="1, 2, 3, 4, 5, 6", interactive=False)
141
+ all_possible_outcomes_ = gr.Textbox(label="Possible Outcomes", value="1, 2, 3, 4, 5, 6")
142
+ with gr.Column():
143
+ total_probability_output = gr.Textbox(label="Probability of all possible outcomes", placeholder="", interactive=False)
144
+ randomize_total_probability.click(lambda: [randomize_outcomes()[0]]*2, [], [all_possible_outcomes, all_possible_outcomes_])
145
+ all_possible_outcomes_.change(lambda x: x, [all_possible_outcomes_], [all_possible_outcomes])
146
+ total_probability.click(
147
+ lambda a, b: f"The probability of the event is: {compute_event_probability(a, b):.0%}",
148
+ [all_possible_outcomes, all_possible_outcomes_], [total_probability_output]
149
+ )
150
+
151
+ gr.Markdown(
152
+ r"""
153
+ ### Axiom 3: Additivity
154
+ *The probability of the `union` of two or more `disjoint events` is the sum of their individual probabilities.*
155
+ - The `union` of two events is the event that `either one or the other happens, or both`.
156
+ - When events are `disjoint`, it means that they `cannot happen at the same time`, so the probabilities sum up.
157
+ $$\text{For any disjoint Events A and B:} \quad P(\text{Event A} \cup \text{Event B}) = P(\text{Event A}) + P(\text{Event B}) $$
158
+ """
159
+ )
160
+
161
+ with gr.Column():
162
+ with gr.Row():
163
+ randomize_disjoint = gr.Button(value="Randomize events A and B")
164
+ compute_disjoint = gr.Button(value="Compute")
165
+ with gr.Row():
166
+ with gr.Column():
167
+ favorable_a = gr.Textbox(label="Favorable Outcomes: A", value="1, 4, 6")
168
+ favorable_b = gr.Textbox(label="Favorable Outcomes: B", value="2, 4")
169
+ favorable_a_or_b = gr.Textbox(label="Favorable Outcomes: A U B", value="1, 2, 4, 6", interactive=False)
170
+ possible_outcomes_disjoint = gr.Textbox(label="Possible Outcomes", value="1, 2, 3, 4, 5, 6")
171
+ with gr.Column():
172
+ disjoint_probability_output_a = gr.Textbox(label="Probability: A", placeholder="", interactive=False)
173
+ disjoint_probability_output_b = gr.Textbox(label="Probability: B", placeholder="", interactive=False)
174
+ disjoint_probability_output_a_b = gr.Textbox(label="Probability: A U B", placeholder="", interactive=False)
175
+ disjoint_probability_output_a_p_b = gr.Textbox(label="(Probability A) + (Probability B)", placeholder="", interactive=False)
176
+ with gr.Row():
177
+ events_are_disjoint = gr.Textbox(label="Are the events disjoint?", placeholder="", interactive=False)
178
+ third_is_respected = gr.Textbox(label="Is the sum equal to the probability of the union?", placeholder="", interactive=False)
179
+
180
+ favorable_a.change(
181
+ lambda a, b: "No.." if (lambda x, y: len(set(x).intersection(set(y))))(*check_inputs(a, b)) else "Yes!",
182
+ [favorable_a, favorable_b], [events_are_disjoint]
183
+ )
184
+ favorable_b.change(
185
+ lambda a, b: "No.." if (lambda x, y: len(set(x).intersection(set(y))))(*check_inputs(a, b)) else "Yes!",
186
+ [favorable_a, favorable_b], [events_are_disjoint]
187
+ )
188
+
189
+ favorable_a.change(join_events, [favorable_a, favorable_b], [favorable_a_or_b])
190
+ favorable_b.change(join_events, [favorable_a, favorable_b], [favorable_a_or_b])
191
+
192
+ randomize_disjoint.click(lambda: (*randomize_outcomes(), randomize_outcomes()[0]), [], [favorable_a, possible_outcomes_disjoint, favorable_b])
193
+ compute_disjoint.click(
194
+ lambda a, b, c, d: (
195
+ f"The probability of the event is: {compute_event_probability(a, d):.0%}",
196
+ f"The probability of the event is: {compute_event_probability(b, d):.0%}",
197
+ f"The joint probability is: {compute_event_probability(c, d):.0%}",
198
+ f"The sum of probabilities is: {compute_event_probability(a, d) + compute_event_probability(b, d):.0%}",
199
+ "Yes!" if (compute_event_probability(a, d) + compute_event_probability(b, d) == compute_event_probability(c, d)) else "No.."
200
+ ),
201
+ [favorable_a, favorable_b, favorable_a_or_b, possible_outcomes_disjoint],
202
+ [disjoint_probability_output_a, disjoint_probability_output_b, disjoint_probability_output_a_b, disjoint_probability_output_a_p_b, third_is_respected]
203
+ )
204
+
205
+ gr.Markdown(
206
+ r"""
207
+ If you are curious about how to compute the probability of event that at NOT disjoint, this can also be achieved with a simple calculation.
208
+
209
+ When events are `not disjoint`, there is, included in the probability of each event, the probability that both events happen at the same time.
210
+ To correct for this we need to subtract this probability of the `intersection` of the two events from the sum of their probabilities.
211
+ $$\text{For any Events A and B:} \quad P(\text{Event A} \cup \text{Event B}) = P(\text{Event A}) + P(\text{Event B}) - P(\text{Event A} \cap \text{Event B}) $$
212
+
213
+ Where the `intersection` of two events is the event that `both happen at the same time`, denoted as `A ∩ B`.
214
+ """
215
+ )
216
+
217
+ # Launch the Blocks interface
218
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.10
3
+ # by the following command:
4
+ #
5
+ # pip-compile requirements.in
6
+ #
7
+ aiofiles==23.2.1
8
+ # via gradio
9
+ altair==5.2.0
10
+ # via gradio
11
+ annotated-types==0.6.0
12
+ # via pydantic
13
+ anyio==4.3.0
14
+ # via
15
+ # httpx
16
+ # starlette
17
+ attrs==23.2.0
18
+ # via
19
+ # jsonschema
20
+ # referencing
21
+ certifi==2024.2.2
22
+ # via
23
+ # httpcore
24
+ # httpx
25
+ # requests
26
+ charset-normalizer==3.3.2
27
+ # via requests
28
+ click==8.1.7
29
+ # via
30
+ # typer
31
+ # uvicorn
32
+ colorama==0.4.6
33
+ # via typer
34
+ contourpy==1.2.0
35
+ # via matplotlib
36
+ cycler==0.12.1
37
+ # via matplotlib
38
+ exceptiongroup==1.2.0
39
+ # via anyio
40
+ fastapi==0.110.0
41
+ # via gradio
42
+ ffmpy==0.3.2
43
+ # via gradio
44
+ filelock==3.13.1
45
+ # via huggingface-hub
46
+ fonttools==4.49.0
47
+ # via matplotlib
48
+ fsspec==2024.2.0
49
+ # via
50
+ # gradio-client
51
+ # huggingface-hub
52
+ gradio==4.19.2
53
+ # via -r requirements.in
54
+ gradio-client==0.10.1
55
+ # via gradio
56
+ h11==0.14.0
57
+ # via
58
+ # httpcore
59
+ # uvicorn
60
+ httpcore==1.0.4
61
+ # via httpx
62
+ httpx==0.27.0
63
+ # via
64
+ # gradio
65
+ # gradio-client
66
+ huggingface-hub==0.21.4
67
+ # via
68
+ # gradio
69
+ # gradio-client
70
+ idna==3.6
71
+ # via
72
+ # anyio
73
+ # httpx
74
+ # requests
75
+ importlib-resources==6.1.3
76
+ # via gradio
77
+ jinja2==3.1.3
78
+ # via
79
+ # altair
80
+ # gradio
81
+ jsonschema==4.21.1
82
+ # via altair
83
+ jsonschema-specifications==2023.12.1
84
+ # via jsonschema
85
+ kiwisolver==1.4.5
86
+ # via matplotlib
87
+ markdown-it-py==3.0.0
88
+ # via rich
89
+ markupsafe==2.1.5
90
+ # via
91
+ # gradio
92
+ # jinja2
93
+ matplotlib==3.8.3
94
+ # via gradio
95
+ mdurl==0.1.2
96
+ # via markdown-it-py
97
+ numpy==1.26.4
98
+ # via
99
+ # altair
100
+ # contourpy
101
+ # gradio
102
+ # matplotlib
103
+ # pandas
104
+ orjson==3.9.15
105
+ # via gradio
106
+ packaging==23.2
107
+ # via
108
+ # altair
109
+ # gradio
110
+ # gradio-client
111
+ # huggingface-hub
112
+ # matplotlib
113
+ pandas==2.2.1
114
+ # via
115
+ # altair
116
+ # gradio
117
+ pillow==10.2.0
118
+ # via
119
+ # gradio
120
+ # matplotlib
121
+ pydantic==2.6.3
122
+ # via
123
+ # fastapi
124
+ # gradio
125
+ pydantic-core==2.16.3
126
+ # via pydantic
127
+ pydub==0.25.1
128
+ # via gradio
129
+ pygments==2.17.2
130
+ # via rich
131
+ pyparsing==3.1.2
132
+ # via matplotlib
133
+ python-dateutil==2.9.0.post0
134
+ # via
135
+ # matplotlib
136
+ # pandas
137
+ python-multipart==0.0.9
138
+ # via gradio
139
+ pytz==2024.1
140
+ # via pandas
141
+ pyyaml==6.0.1
142
+ # via
143
+ # gradio
144
+ # huggingface-hub
145
+ referencing==0.33.0
146
+ # via
147
+ # jsonschema
148
+ # jsonschema-specifications
149
+ requests==2.31.0
150
+ # via huggingface-hub
151
+ rich==13.7.1
152
+ # via typer
153
+ rpds-py==0.18.0
154
+ # via
155
+ # jsonschema
156
+ # referencing
157
+ ruff==0.3.1
158
+ # via gradio
159
+ semantic-version==2.10.0
160
+ # via gradio
161
+ shellingham==1.5.4
162
+ # via typer
163
+ six==1.16.0
164
+ # via python-dateutil
165
+ sniffio==1.3.1
166
+ # via
167
+ # anyio
168
+ # httpx
169
+ starlette==0.36.3
170
+ # via fastapi
171
+ tomlkit==0.12.0
172
+ # via gradio
173
+ toolz==0.12.1
174
+ # via altair
175
+ tqdm==4.66.2
176
+ # via huggingface-hub
177
+ typer[all]==0.9.0
178
+ # via gradio
179
+ typing-extensions==4.10.0
180
+ # via
181
+ # altair
182
+ # anyio
183
+ # fastapi
184
+ # gradio
185
+ # gradio-client
186
+ # huggingface-hub
187
+ # pydantic
188
+ # pydantic-core
189
+ # typer
190
+ # uvicorn
191
+ tzdata==2024.1
192
+ # via pandas
193
+ urllib3==2.2.1
194
+ # via requests
195
+ uvicorn==0.27.1
196
+ # via gradio
197
+ websockets==11.0.3
198
+ # via gradio-client