1. 理论知识
如果已经有了一个累积分布函数(CDF)的图形,函数图形为 F ( x ) F(x) F(x),可以通过以下步骤计算其均值和方差:
1). 计算均值(Mean):
- 在CDF图形中,均值对应于横轴上使得CDF值等于0.5的那个点。这个点表示随机变量落在该值以下的概率为0.5,即中位数。用函数计算为:
μ = ∫ − ∞ ∞ [ x ∗ F ′ ( x ) ] d x μ = \int_{-\infty}^{\infty}[x * F'(x)] dx μ=∫−∞∞[x∗F′(x)]dx - 如果CDF是以离散值给出的,则中位数是距离0.5最近的那个值。
2). 计算方差(Variance):
- 方差是对数据分布的离散程度的一种度量。在一维情况下,方差定义为每个数据点与均值之间的平方差的平均值。
- 对于CDF图形,可以使用下面的公式计算方差:
V a r ( X ) = σ 2 = ∫ [ ( x − μ ) 2 ∗ F ′ ( x ) ] d x Var (X)=\sigma^2 = ∫[(x - μ)^2 * F'(x)] dx Var(X)=σ2=∫[(x−μ)2∗F′(x)]dx - 如果只有离散值的CDF,可以使用下面的公式来近似计算方差:
V a r = ∑ i = 1 N ( x i − μ ) 2 ⋅ P ( x i ) Var = \sum_{i=1}^{N} (x_i - \mu)^2 \cdot P(x_i) Var=i=1∑N(xi−μ)2⋅P(xi)
其中, x i x_i xi 是第 i i i 个数据点, P ( x i ) P(x_i) P(xi) 是数据点 x i x_i xi 的概率。
通过这些步骤,可以利用CDF图形计算出均值和方差。
但是若知道概率密度函数PDF图形,函数图形为$f(x)$, 则
μ
=
∫
−
∞
∞
[
x
∗
f
(
x
)
]
d
x
;
μ = \int_{-\infty}^{\infty}[x * f(x)] dx ;
μ=∫−∞∞[x∗f(x)]dx;
σ
2
=
∫
−
∞
∞
(
x
−
μ
)
2
⋅
f
(
x
)
d
x
\sigma^2= \int_{-\infty}^{\infty} (x - \mu)^2 \cdot f(x) dx
σ2=∫−∞∞(x−μ)2⋅f(x)dx
其中,
μ
\mu
μ是均值,
f
(
x
)
f(x)
f(x)是概率密度函数(PDF),如果只有CDF,可以通过对CDF进行微分来获取PDF。 如前面所写:
μ
=
∫
−
∞
∞
[
x
∗
F
′
(
x
)
]
d
x
\mu= \int_{-\infty}^{\infty}[x * F'(x)] dx
μ=∫−∞∞[x∗F′(x)]dx;
σ
2
=
∫
[
(
x
−
μ
)
2
∗
F
′
(
x
)
]
d
x
\sigma^2 = ∫[(x - μ)^2 * F'(x)] dx
σ2=∫[(x−μ)2∗F′(x)]dx.
2.代码实现
import sympy as sp
import scipy.integrate as spi
import matplotlib.pyplot as plt
import numpy as np
'''
这段代码的目的是计算一个累积分布函数(CDF)在某个区间内的均值和方差
然后使用matplotlib库来绘制图形
'''
# 定义变量 x
x = sp.Symbol('x')
# 定义累积分布函数
def cdf(x):
return (1/10)*x - 4.8
# 求导
cdf_diff = cdf(x).diff(x)
# 积分上下限
dowm_limit = 48
up_limit = 58
# 使用lambdify函数,将sympy的Symbol类型转换为Python的函数类型(function类型),以便进行数值计算
x_lambda = sp.lambdify(x, x * cdf_diff)
# 使用scipy的quad函数,计算x * cdf_diff在给定的上下限之间的定积分,该积分即为均值
mean, error = spi.quad(lambda x: x_lambda(x), dowm_limit, up_limit)
print("均值为:", round(mean, 2))
# 定义一个函数m_lambda,用于计算(x-均值)^2 * cdf_diff的值
m_lambda = sp.lambdify(x, ((x - mean) ** 2) * cdf_diff)
# 使用scipy的quad函数,计算(x-均值)^2 * cdf_diff在给定的上下限之间的定积分,该积分即为方差
variance, error = spi.quad(lambda x: m_lambda(x), dowm_limit, up_limit)
print("方差为:", round(variance, 2))
# 定义累积分布函数cdf(x)
cdf = (1/10)*x - 4.8
# 使用matplotlib绘制cdf图形
X = np.linspace(48, 58, 100)
Y = [cdf.subs(x, xx).evalf() for xx in X]
plt.plot(X, Y)
plt.xlabel('x')
plt.ylabel('CDF(x)')
plt.title('CDF figure')
plt.show()