forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
joint_probability_distribution.py
124 lines (106 loc) · 3.89 KB
/
joint_probability_distribution.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""
Calculate joint probability distribution
https://en.wikipedia.org/wiki/Joint_probability_distribution
"""
def joint_probability_distribution(
x_values: list[int],
y_values: list[int],
x_probabilities: list[float],
y_probabilities: list[float],
) -> dict:
"""
>>> joint_distribution = joint_probability_distribution(
... [1, 2], [-2, 5, 8], [0.7, 0.3], [0.3, 0.5, 0.2]
... )
>>> from math import isclose
>>> isclose(joint_distribution.pop((1, 8)), 0.14)
True
>>> joint_distribution
{(1, -2): 0.21, (1, 5): 0.35, (2, -2): 0.09, (2, 5): 0.15, (2, 8): 0.06}
"""
return {
(x, y): x_prob * y_prob
for x, x_prob in zip(x_values, x_probabilities)
for y, y_prob in zip(y_values, y_probabilities)
}
# Function to calculate the expectation (mean)
def expectation(values: list, probabilities: list) -> float:
"""
>>> from math import isclose
>>> isclose(expectation([1, 2], [0.7, 0.3]), 1.3)
True
"""
return sum(x * p for x, p in zip(values, probabilities))
# Function to calculate the variance
def variance(values: list[int], probabilities: list[float]) -> float:
"""
>>> from math import isclose
>>> isclose(variance([1,2],[0.7,0.3]), 0.21)
True
"""
mean = expectation(values, probabilities)
return sum((x - mean) ** 2 * p for x, p in zip(values, probabilities))
# Function to calculate the covariance
def covariance(
x_values: list[int],
y_values: list[int],
x_probabilities: list[float],
y_probabilities: list[float],
) -> float:
"""
>>> covariance([1, 2], [-2, 5, 8], [0.7, 0.3], [0.3, 0.5, 0.2])
-2.7755575615628914e-17
"""
mean_x = expectation(x_values, x_probabilities)
mean_y = expectation(y_values, y_probabilities)
return sum(
(x - mean_x) * (y - mean_y) * px * py
for x, px in zip(x_values, x_probabilities)
for y, py in zip(y_values, y_probabilities)
)
# Function to calculate the standard deviation
def standard_deviation(variance: float) -> float:
"""
>>> standard_deviation(0.21)
0.458257569495584
"""
return variance**0.5
if __name__ == "__main__":
from doctest import testmod
testmod()
# Input values for X and Y
x_vals = input("Enter values of X separated by spaces: ").split()
y_vals = input("Enter values of Y separated by spaces: ").split()
# Convert input values to integers
x_values = [int(x) for x in x_vals]
y_values = [int(y) for y in y_vals]
# Input probabilities for X and Y
x_probs = input("Enter probabilities for X separated by spaces: ").split()
y_probs = input("Enter probabilities for Y separated by spaces: ").split()
assert len(x_values) == len(x_probs)
assert len(y_values) == len(y_probs)
# Convert input probabilities to floats
x_probabilities = [float(p) for p in x_probs]
y_probabilities = [float(p) for p in y_probs]
# Calculate the joint probability distribution
jpd = joint_probability_distribution(
x_values, y_values, x_probabilities, y_probabilities
)
# Print the joint probability distribution
print(
"\n".join(
f"P(X={x}, Y={y}) = {probability}" for (x, y), probability in jpd.items()
)
)
mean_xy = expectation(
[x * y for x in x_values for y in y_values],
[px * py for px in x_probabilities for py in y_probabilities],
)
print(f"x mean: {expectation(x_values, x_probabilities) = }")
print(f"y mean: {expectation(y_values, y_probabilities) = }")
print(f"xy mean: {mean_xy}")
print(f"x: {variance(x_values, x_probabilities) = }")
print(f"y: {variance(y_values, y_probabilities) = }")
print(f"{covariance(x_values, y_values, x_probabilities, y_probabilities) = }")
print(f"x: {standard_deviation(variance(x_values, x_probabilities)) = }")
print(f"y: {standard_deviation(variance(y_values, y_probabilities)) = }")