目录
Python实例题
题目
Python计算概率论
代码实现
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns
from sympy import symbols, integrate, exp, sqrt, pi, simplify, latex
class ProbabilityCalculator:
"""概率论计算器类,支持概率分布、随机变量和统计量计算"""
def __init__(self):
"""初始化计算器"""
self.x = symbols('x')
def uniform_pdf(self, x, a, b):
"""
均匀分布的概率密度函数
参数:
x: 自变量值
a: 下界
b: 上界
返回:
float: 概率密度值
"""
return stats.uniform.pdf(x, loc=a, scale=b-a)
def uniform_cdf(self, x, a, b):
"""
均匀分布的累积分布函数
参数:
x: 自变量值
a: 下界
b: 上界
返回:
float: 累积概率值
"""
return stats.uniform.cdf(x, loc=a, scale=b-a)
def normal_pdf(self, x, mu, sigma):
"""
正态分布的概率密度函数
参数:
x: 自变量值
mu: 均值
sigma: 标准差
返回:
float: 概率密度值
"""
return stats.norm.pdf(x, loc=mu, scale=sigma)
def normal_cdf(self, x, mu, sigma):
"""
正态分布的累积分布函数
参数:
x: 自变量值
mu: 均值
sigma: 标准差
返回:
float: 累积概率值
"""
return stats.norm.cdf(x, loc=mu, scale=sigma)
def exponential_pdf(self, x, lambda_):
"""
指数分布的概率密度函数
参数:
x: 自变量值
lambda_: 率参数
返回:
float: 概率密度值
"""
return stats.expon.pdf(x, scale=1/lambda_)
def exponential_cdf(self, x, lambda_):
"""
指数分布的累积分布函数
参数:
x: 自变量值
lambda_: 率参数
返回:
float: 累积概率值
"""
return stats.expon.cdf(x, scale=1/lambda_)
def poisson_pmf(self, k, lambda_):
"""
泊松分布的概率质量函数
参数:
k: 事件发生次数(非负整数)
lambda_: 平均发生率
返回:
float: 概率质量值
"""
return stats.poisson.pmf(k, mu=lambda_)
def binomial_pmf(self, k, n, p):
"""
二项分布的概率质量函数
参数:
k: 成功次数(非负整数)
n: 试验次数
p: 每次试验成功的概率
返回:
float: 概率质量值
"""
return stats.binom.pmf(k, n, p)
def calculate_expected_value(self, distribution, params, lower, upper, num_points=1000):
"""
计算连续随机变量的期望值
参数:
distribution: 分布函数(如self.normal_pdf)
params: 分布参数(如[mu, sigma])
lower: 积分下限
upper: 积分上限
num_points: 数值积分的采样点数
返回:
float: 期望值
"""
x_vals = np.linspace(lower, upper, num_points)
dx = (upper - lower) / (num_points - 1)
expected_value = np.sum(x_vals * distribution(x_vals, *params)) * dx
return expected_value
def calculate_variance(self, distribution, params, lower, upper, num_points=1000):
"""
计算连续随机变量的方差
参数:
distribution: 分布函数(如self.normal_pdf)
params: 分布参数(如[mu, sigma])
lower: 积分下限
upper: 积分上限
num_points: 数值积分的采样点数
返回:
float: 方差
"""
x_vals = np.linspace(lower, upper, num_points)
dx = (upper - lower) / (num_points - 1)
# 计算期望值
expected_value = self.calculate_expected_value(distribution, params, lower, upper, num_points)
# 计算方差
variance = np.sum((x_vals - expected_value)**2 * distribution(x_vals, *params)) * dx
return variance
def calculate_covariance(self, X, Y):
"""
计算两个随机变量的协方差
参数:
X: 第一个随机变量的样本
Y: 第二个随机变量的样本
返回:
float: 协方差
"""
return np.cov(X, Y)[0, 1]
def calculate_correlation(self, X, Y):
"""
计算两个随机变量的相关系数
参数:
X: 第一个随机变量的样本
Y: 第二个随机变量的样本
返回:
float: 相关系数
"""
return np.corrcoef(X, Y)[0, 1]
def sample_from_distribution(self, distribution, params, size):
"""
从指定分布中生成随机样本
参数:
distribution: 分布函数(如stats.norm)
params: 分布参数(如[mu, sigma])
size: 样本大小
返回:
np.ndarray: 随机样本
"""
if distribution == stats.uniform:
return distribution.rvs(loc=params[0], scale=params[1]-params[0], size=size)
elif distribution == stats.norm:
return distribution.rvs(loc=params[0], scale=params[1], size=size)
elif distribution == stats.expon:
return distribution.rvs(scale=1/params[0], size=size)
elif distribution == stats.poisson:
return distribution.rvs(mu=params[0], size=size)
elif distribution == stats.binom:
return distribution.rvs(n=params[0], p=params[1], size=size)
else:
raise ValueError("不支持的分布类型")
def plot_pdf(self, distribution, params, lower, upper, title=None):
"""
绘制概率密度函数
参数:
distribution: 分布函数(如self.normal_pdf)
params: 分布参数(如[mu, sigma])
lower: x轴下限
upper: x轴上限
title: 图像标题,默认为None
"""
x_vals = np.linspace(lower, upper, 1000)
y_vals = distribution(x_vals, *params)
plt.figure(figsize=(10, 6))
plt.plot(x_vals, y_vals, 'b-', linewidth=2)
plt.fill_between(x_vals, y_vals, alpha=0.2, color='blue')
plt.grid(True)
plt.axhline(y=0, color='k', linewidth=0.5)
plt.axvline(x=0, color='k', linewidth=0.5)
if title:
plt.title(title, fontsize=14)
else:
plt.title(f"概率密度函数", fontsize=14)
plt.xlabel('x', fontsize=12)
plt.ylabel('密度', fontsize=12)
plt.show()
def plot_cdf(self, distribution, params, lower, upper, title=None):
"""
绘制累积分布函数
参数:
distribution: 分布函数(如self.normal_cdf)
params: 分布参数(如[mu, sigma])
lower: x轴下限
upper: x轴上限
title: 图像标题,默认为None
"""
x_vals = np.linspace(lower, upper, 1000)
y_vals = distribution(x_vals, *params)
plt.figure(figsize=(10, 6))
plt.plot(x_vals, y_vals, 'r-', linewidth=2)
plt.grid(True)
plt.axhline(y=0, color='k', linewidth=0.5)
plt.axvline(x=0, color='k', linewidth=0.5)
plt.axhline(y=1, color='k', linestyle='--', linewidth=0.5)
if title:
plt.title(title, fontsize=14)
else:
plt.title(f"累积分布函数", fontsize=14)
plt.xlabel('x', fontsize=12)
plt.ylabel('概率', fontsize=12)
plt.show()
def plot_histogram(self, data, bins=30, title=None):
"""
绘制样本直方图
参数:
data: 样本数据
bins: 直方图的箱数,默认为30
title: 图像标题,默认为None
"""
plt.figure(figsize=(10, 6))
sns.histplot(data, bins=bins, kde=True)
plt.grid(True)
plt.axvline(x=np.mean(data), color='r', linestyle='--', label=f'均值: {np.mean(data):.2f}')
plt.axvline(x=np.median(data), color='g', linestyle='--', label=f'中位数: {np.median(data):.2f}')
if title:
plt.title(title, fontsize=14)
else:
plt.title(f"样本直方图", fontsize=14)
plt.xlabel('值', fontsize=12)
plt.ylabel('频率', fontsize=12)
plt.legend()
plt.show()
def symbolic_expected_value(self, pdf_expr, x, lower, upper):
"""
使用符号计算期望值
参数:
pdf_expr: 概率密度函数的符号表达式
x: 符号变量
lower: 积分下限
upper: 积分上限
返回:
tuple: (期望值的符号表达式, LaTeX表示)
"""
try:
expected_value = integrate(x * pdf_expr, (x, lower, upper))
latex_expr = f"E[X] = \int_{{{lower}}}^{{{upper}}} x \cdot {latex(pdf_expr)} \, dx = {latex(expected_value)}"
return expected_value, latex_expr
except Exception as e:
print(f"符号计算期望值时出错: {e}")
return None, None
def symbolic_variance(self, pdf_expr, x, lower, upper):
"""
使用符号计算方差
参数:
pdf_expr: 概率密度函数的符号表达式
x: 符号变量
lower: 积分下限
upper: 积分上限
返回:
tuple: (方差的符号表达式, LaTeX表示)
"""
try:
# 计算期望值
E_X, _ = self.symbolic_expected_value(pdf_expr, x, lower, upper)
# 计算E[X²]
E_X_squared = integrate(x**2 * pdf_expr, (x, lower, upper))
# 计算方差
variance = E_X_squared - E_X**2
latex_expr = f"Var[X] = E[X^2] - (E[X])^2 = {latex(E_X_squared)} - ({latex(E_X)})^2 = {latex(variance)}"
return variance, latex_expr
except Exception as e:
print(f"符号计算方差时出错: {e}")
return None, None
# 示例使用
def example_usage():
calc = ProbabilityCalculator()
print("\n===== 概率分布示例 =====")
# 正态分布
mu = 0
sigma = 1
x = 1.96
print(f"正态分布 N({mu}, {sigma}) 在 x={x} 处的概率密度: {calc.normal_pdf(x, mu, sigma):.6f}")
print(f"正态分布 N({mu}, {sigma}) 在 x={x} 处的累积概率: {calc.normal_cdf(x, mu, sigma):.6f}")
# 指数分布
lambda_ = 0.5
x = 2
print(f"指数分布 Exp({lambda_}) 在 x={x} 处的概率密度: {calc.exponential_pdf(x, lambda_):.6f}")
print(f"指数分布 Exp({lambda_}) 在 x={x} 处的累积概率: {calc.exponential_cdf(x, lambda_):.6f}")
# 泊松分布
lambda_p = 3
k = 2
print(f"泊松分布 Poisson({lambda_p}) 在 k={k} 处的概率质量: {calc.poisson_pmf(k, lambda_p):.6f}")
# 二项分布
n = 10
p = 0.5
k = 5
print(f"二项分布 Binom({n}, {p}) 在 k={k} 处的概率质量: {calc.binom_pmf(k, n, p):.6f}")
print("\n===== 期望值和方差示例 =====")
# 正态分布的期望值和方差
lower = -10
upper = 10
expected_value = calc.calculate_expected_value(calc.normal_pdf, [mu, sigma], lower, upper)
variance = calc.calculate_variance(calc.normal_pdf, [mu, sigma], lower, upper)
print(f"正态分布 N({mu}, {sigma}) 的期望值: {expected_value:.6f}")
print(f"正态分布 N({mu}, {sigma}) 的方差: {variance:.6f}")
# 指数分布的期望值和方差
expected_value = calc.calculate_expected_value(calc.exponential_pdf, [lambda_], 0, 100)
variance = calc.calculate_variance(calc.exponential_pdf, [lambda_], 0, 100)
print(f"指数分布 Exp({lambda_}) 的期望值: {expected_value:.6f}")
print(f"指数分布 Exp({lambda_}) 的方差: {variance:.6f}")
print("\n===== 符号计算示例 =====")
# 符号计算均匀分布的期望值和方差
a, b = symbols('a b')
uniform_pdf = 1/(b - a)
E, latex_E = calc.symbolic_expected_value(uniform_pdf, calc.x, a, b)
Var, latex_Var = calc.symbolic_variance(uniform_pdf, calc.x, a, b)
print(f"均匀分布 U(a, b) 的期望值: {E}")
print(f"LaTeX: {latex_E}")
print(f"均匀分布 U(a, b) 的方差: {Var}")
print(f"LaTeX: {latex_Var}")
print("\n===== 随机样本生成示例 =====")
# 从正态分布生成样本
sample_size = 1000
normal_samples = calc.sample_from_distribution(stats.norm, [mu, sigma], sample_size)
print(f"从 N({mu}, {sigma}) 生成的样本均值: {np.mean(normal_samples):.6f}")
print(f"从 N({mu}, {sigma}) 生成的样本方差: {np.var(normal_samples):.6f}")
# 从指数分布生成样本
exp_samples = calc.sample_from_distribution(stats.expon, [lambda_], sample_size)
print(f"从 Exp({lambda_}) 生成的样本均值: {np.mean(exp_samples):.6f}")
print(f"从 Exp({lambda_}) 生成的样本方差: {np.var(exp_samples):.6f}")
print("\n===== 协方差和相关系数示例 =====")
# 生成两个相关的随机变量
X = np.random.normal(0, 1, 1000)
Y = 2*X + np.random.normal(0, 0.5, 1000) # Y与X线性相关
covariance = calc.calculate_covariance(X, Y)
correlation = calc.calculate_correlation(X, Y)
print(f"X 和 Y 的协方差: {covariance:.6f}")
print(f"X 和 Y 的相关系数: {correlation:.6f}")
print("\n===== 可视化示例 =====")
# 绘制正态分布的PDF和CDF
calc.plot_pdf(calc.normal_pdf, [mu, sigma], -5, 5, f"正态分布 N({mu}, {sigma}) 的概率密度函数")
calc.plot_cdf(calc.normal_cdf, [mu, sigma], -5, 5, f"正态分布 N({mu}, {sigma}) 的累积分布函数")
# 绘制样本直方图
calc.plot_histogram(normal_samples, 30, f"正态分布 N({mu}, {sigma}) 的样本直方图")
if __name__ == "__main__":
example_usage()
实现原理
这个概率论计算工具基于以下技术实现:
概率分布:
- 使用 SciPy.stats 模块提供常见概率分布(正态、均匀、指数、泊松、二项等)
- 支持概率密度函数 (PDF)、概率质量函数 (PMF) 和累积分布函数 (CDF) 的计算
统计量计算:
- 实现数值方法计算期望值、方差、协方差和相关系数
- 提供符号计算功能,使用 SymPy 进行精确计算
- 支持从各种分布生成随机样本
可视化功能:
- 使用 Matplotlib 和 Seaborn 绘制概率密度函数和累积分布函数
- 可视化样本直方图和统计特性
- 支持自定义图表样式和标题
关键代码解析
1. 概率分布计算
def normal_pdf(self, x, mu, sigma):
"""正态分布的概率密度函数"""
return stats.norm.pdf(x, loc=mu, scale=sigma)
def poisson_pmf(self, k, lambda_):
"""泊松分布的概率质量函数"""
return stats.poisson.pmf(k, mu=lambda_)
2. 期望值和方差计算
def calculate_expected_value(self, distribution, params, lower, upper, num_points=1000):
"""计算连续随机变量的期望值"""
x_vals = np.linspace(lower, upper, num_points)
dx = (upper - lower) / (num_points - 1)
expected_value = np.sum(x_vals * distribution(x_vals, *params)) * dx
return expected_value
def calculate_variance(self, distribution, params, lower, upper, num_points=1000):
"""计算连续随机变量的方差"""
x_vals = np.linspace(lower, upper, num_points)
dx = (upper - lower) / (num_points - 1)
expected_value = self.calculate_expected_value(distribution, params, lower, upper, num_points)
variance = np.sum((x_vals - expected_value)**2 * distribution(x_vals, *params)) * dx
return variance
3. 符号计算
def symbolic_expected_value(self, pdf_expr, x, lower, upper):
"""使用符号计算期望值"""
try:
expected_value = integrate(x * pdf_expr, (x, lower, upper))
latex_expr = f"E[X] = \int_{{{lower}}}^{{{upper}}} x \cdot {latex(pdf_expr)} \, dx = {latex(expected_value)}"
return expected_value, latex_expr
except Exception as e:
print(f"符号计算期望值时出错: {e}")
return None, None
4. 可视化功能
def plot_pdf(self, distribution, params, lower, upper, title=None):
"""绘制概率密度函数"""
x_vals = np.linspace(lower, upper, 1000)
y_vals = distribution(x_vals, *params)
plt.figure(figsize=(10, 6))
plt.plot(x_vals, y_vals, 'b-', linewidth=2)
plt.fill_between(x_vals, y_vals, alpha=0.2, color='blue')
plt.grid(True)
plt.title(title, fontsize=14)
plt.xlabel('x', fontsize=12)
plt.ylabel('密度', fontsize=12)
plt.show()
使用说明
安装依赖:
pip install numpy matplotlib scipy sympy seaborn
基本用法:
from probability_calculator import ProbabilityCalculator
# 创建计算器实例
calc = ProbabilityCalculator()
# 计算正态分布的概率密度和累积概率
mu = 0
sigma = 1
x = 1.96
print(f"正态分布在 x={x} 处的概率密度: {calc.normal_pdf(x, mu, sigma):.6f}")
print(f"正态分布在 x={x} 处的累积概率: {calc.normal_cdf(x, mu, sigma):.6f}")
# 计算期望值和方差
expected_value = calc.calculate_expected_value(calc.normal_pdf, [mu, sigma], -10, 10)
variance = calc.calculate_variance(calc.normal_pdf, [mu, sigma], -10, 10)
print(f"期望值: {expected_value:.6f}")
print(f"方差: {variance:.6f}")
# 符号计算
from sympy import symbols, exp
lambda_ = symbols('lambda')
pdf = lambda_ * exp(-lambda_ * calc.x) # 指数分布的PDF
E, latex_E = calc.symbolic_expected_value(pdf, calc.x, 0, float('inf'))
print(f"符号期望值: {E}")
print(f"LaTeX: {latex_E}")
# 绘制概率密度函数
calc.plot_pdf(calc.normal_pdf, [mu, sigma], -5, 5, "正态分布PDF")
示例输出:
正态分布在 x=1.96 处的概率密度: 0.058441
正态分布在 x=1.96 处的累积概率: 0.975002
期望值: 0.000000
方差: 1.000000
符号期望值: 1/lambda
LaTeX: E[X] = \int_{0}^{\infty} x \cdot \lambda e^{- \lambda x} \, dx = \frac{1}{\lambda}
扩展建议
增强功能:
- 添加更多概率分布(如卡方分布、t 分布、F 分布等)
- 实现多维分布和联合分布计算
- 添加大数定律和中心极限定理的演示功能
- 增加假设检验和置信区间计算
用户界面:
- 开发命令行交互界面
- 创建图形界面(如使用 Tkinter 或 PyQt)
- 实现 Web 界面(如使用 Flask 或 Django)
性能优化:
- 针对大规模样本计算进行优化
- 添加并行计算支持
- 优化符号计算的效率
教学辅助:
- 添加概率论概念解释和公式推导
- 提供计算步骤的详细解释
- 实现交互式可视化(如动态调整分布参数)