14. 故障树不确定性#

除了Anaconda中已有的库外,本讲座还需要以下库:

!pip install quantecon tabulate

Hide code cell output

Requirement already satisfied: quantecon in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (0.11.4)
Requirement already satisfied: tabulate in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (0.10.0)
Requirement already satisfied: numba>=0.49.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from quantecon) (0.65.1)
Requirement already satisfied: numpy>=1.17.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from quantecon) (2.4.6)
Requirement already satisfied: requests in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from quantecon) (2.34.2)
Requirement already satisfied: scipy>=1.5.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from quantecon) (1.18.0)
Requirement already satisfied: sympy in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from quantecon) (1.14.0)
Requirement already satisfied: llvmlite<0.48,>=0.47.0dev0 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from numba>=0.49.0->quantecon) (0.47.0)
Requirement already satisfied: charset_normalizer<4,>=2 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from requests->quantecon) (3.4.7)
Requirement already satisfied: idna<4,>=2.5 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from requests->quantecon) (3.18)
Requirement already satisfied: urllib3<3,>=1.26 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from requests->quantecon) (2.7.0)
Requirement already satisfied: certifi>=2023.5.7 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from requests->quantecon) (2026.6.17)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.13/site-packages (from sympy->quantecon) (1.3.0)

14.1. 概述#

本讲将运用基本工具来近似计算由多个关键部件组成的系统的年度故障率的概率分布。

我们将使用对数正态分布来近似关键部件的概率分布。

为了近似描述系统总故障率(表示为 \(n\) 个对数正态随机变量之)的概率分布,我们计算这些分布的卷积。

我们将使用以下概念和工具:

  • 对数正态分布

  • 描述独立随机变量之和的概率分布的卷积定理

  • 用于近似多组件系统故障率的故障树分析

  • 用于描述不确定概率的层次概率模型

  • 傅里叶变换和傅里叶逆变换作为计算序列卷积的高效方法

参见

关于傅里叶变换的更多信息,请参见 循环矩阵 以及 协方差平稳过程谱估计

El-Shanawany et al. [2018]Greenfield and Sargent [1993] 应用了这些方法来近似核设施安全系统的故障概率。

这些技术响应了 Apostolakis [1990] 提出的关于量化安全系统可靠性不确定性的建议。

本讲座将使用以下导入和设置:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf"
mpl.font_manager.fontManager.addfont(FONTPATH)
plt.rcParams['font.family'] = ['Source Han Serif SC']

from scipy.signal import fftconvolve
from tabulate import tabulate
import quantecon as qe

14.2. 对数正态分布#

如果随机变量 \(x\) 服从均值为 \(\mu\)、方差为 \(\sigma^2\) 的正态分布,那么 \(y = \exp(x)\) 服从参数为 \(\mu, \sigma^2\)对数正态分布

备注

我们将 \(\mu\)\(\sigma^2\) 称为参数而不是均值和方差,因为:

  • \(\mu\)\(\sigma^2\)\(x = \log(y)\) 的均值和方差

  • 它们不是 \(y\) 的均值和方差

  • \(y\) 的均值是 \(\exp(\mu + \frac{1}{2}\sigma^2)\),方差是 \((e^{\sigma^2} - 1) e^{2\mu + \sigma^2}\)

对数正态随机变量 \(y\) 始终是非负的。

\(y\) 的概率密度函数是

(14.1)#\[f(y) = \frac{1}{y \sigma \sqrt{2 \pi}} \exp \left( \frac{- (\log y - \mu)^2 }{2 \sigma^2} \right), \quad y \geq 0\]

对数正态随机变量的重要特性是:

(14.2)#\[\begin{split}\begin{aligned} \text{均值:} & \quad e ^{\mu + \frac{1}{2} \sigma^2} \\ \text{方差:} & \quad (e^{\sigma^2} - 1) e^{2 \mu + \sigma^2} \\ \text{中位数:} & \quad e^\mu \\ \text{众数:} & \quad e^{\mu - \sigma^2} \\ \text{0.95 分位数:} & \quad e^{\mu + 1.645 \sigma} \\ \text{0.95/0.05 分位数比:} & \quad e^{3.29 \sigma} \end{aligned}\end{split}\]

14.2.1. 稳定性性质#

回顾独立正态分布随机变量具有以下稳定性性质:

如果 \(x_1 \sim N(\mu_1, \sigma_1^2)\)\(x_2 \sim N(\mu_2, \sigma_2^2)\) 是独立的,那么 \(x_1 + x_2 \sim N(\mu_1 + \mu_2, \sigma_1^2 + \sigma_2^2)\)

独立的对数正态分布具有不同的稳定性性质:独立对数正态随机变量的乘积也是对数正态分布。

具体来说,如果 \(y_1\) 是参数为 \((\mu_1, \sigma_1^2)\) 的对数正态分布,且 \(y_2\) 是参数为 \((\mu_2, \sigma_2^2)\) 的对数正态分布,那么 \(y_1 y_2\) 是参数为 \((\mu_1 + \mu_2, \sigma_1^2 + \sigma_2^2)\) 的对数正态分布。

警告

虽然两个对数正态分布的乘积是对数正态分布,但两个对数正态分布的不是对数正态分布。

这个观察结果引出了本讲座的核心挑战:近似独立对数正态随机变量之和的概率分布。

14.3. 卷积定理#

\(x\)\(y\) 是概率密度分别为 \(f(x)\)\(g(y)\) 的独立随机变量,其中 \(x, y \in \mathbb{R}\)

\(z = x + y\)

那么 \(z\) 的概率密度为

(14.3)#\[h(z) = (f * g)(z) \equiv \int_{-\infty}^\infty f(\tau) g(z - \tau) d\tau\]

其中 \((f*g)\) 表示 \(f\)\(g\)卷积

对于非负随机变量,这可以特化为

(14.4)#\[h(z) = (f * g)(z) \equiv \int_{0}^z f(\tau) g(z - \tau) d\tau\]

14.3.1. 离散卷积#

我们将使用卷积公式的离散化版本。

我们将 \(f\)\(g\) 都替换为离散化的对应形式,并归一化使其和为 1。

离散卷积公式为

(14.5)#\[h_n = (f*g)_n = \sum_{m=0}^n f_m g_{n-m}, \quad n \geq 0\]

这计算了两个离散随机变量之和的概率质量函数。

14.3.2. 示例:离散分布#

考虑两个概率质量函数:

\[ f_j = \Pr(X = j), \quad j = 0, 1 \]

\[ g_j = \Pr(Y = j), \quad j = 0, 1, 2, 3 \]

\(Z = X + Y\) 的分布由卷积 \(h = f * g\) 给出。

# 定义概率质量函数
f = [0.75, 0.25]
g = [0.0, 0.6, 0.0, 0.4]

# 使用两种方法计算卷积
h = np.convolve(f, g)
hf = fftconvolve(f, g)

print(f"f = {f}, sum = {np.sum(f):.3f}")
print(f"g = {g}, sum = {np.sum(g):.3f}")
print(f"h = {h}, sum = {np.sum(h):.3f}")
print(f"hf = {hf}, sum = {np.sum(hf):.3f}")
f = [0.75, 0.25], sum = 1.000
g = [0.0, 0.6, 0.0, 0.4], sum = 1.000
h = [0.   0.45 0.15 0.3  0.1 ], sum = 1.000
hf = [0.   0.45 0.15 0.3  0.1 ], sum = 1.000

numpy.convolvescipy.signal.fftconvolve 都得到相同的结果,但对于长序列,fftconvolve 要快得多。

为了提高效率,本讲座将始终使用 fftconvolve

14.4. 近似连续分布#

现在我们验证离散化分布能否准确近似来自底层连续分布的样本。

我们从三个独立的对数正态随机变量中生成25,000个样本,并计算它们的两两之和与三者之和。

然后我们将样本的直方图与离散化分布的直方图进行比较。

# 设置对数正态分布的参数
μ, σ = 5.0, 1.0
n_samples = 25000

# 生成样本
rng = np.random.default_rng(1234)
s1 = rng.lognormal(μ, σ, n_samples)
s2 = rng.lognormal(μ, σ, n_samples)
s3 = rng.lognormal(μ, σ, n_samples)

# 计算和
ssum2 = s1 + s2
ssum3 = s1 + s2 + s3

# 绘制 s1 的直方图
fig, ax = plt.subplots()
ax.hist(s1, 1000, density=True, alpha=0.6)
ax.set_xlabel('数值')
ax.set_ylabel('密度')
plt.show()
findfont: Failed to find font weight normal, now using 600.
_images/dee0f367991220e202c1995bae17de3dda8e44799af4cbb376d7142078703aed.png

图 14.1 单个对数正态分布的样本直方图#

# 绘制两个对数正态分布之和的直方图
fig, ax = plt.subplots()
ax.hist(ssum2, 1000, density=True, alpha=0.6)
ax.set_xlabel('数值')
ax.set_ylabel('密度')
plt.show()
_images/9d694bbf6b28dc334b2b1a26bc8a28e4c5dff8938dd8959e143c210ff117eb61.png

图 14.2 两个对数正态分布之和的直方图#

# 绘制三个对数正态分布之和的直方图
fig, ax = plt.subplots()
ax.hist(ssum3, 1000, density=True, alpha=0.6)
ax.set_xlabel('数值')
ax.set_ylabel('密度')
plt.show()
_images/cb8dcb503d1754c863cb2c084903b38e70be150662923dfd61b77f5ff4444b9c.png

图 14.3 三个对数正态分布之和的直方图#

让我们验证样本均值是否与理论均值相匹配:

samp_mean = np.mean(s2)
theoretical_mean = np.exp(μ + σ**2 / 2)

print(f"理论均值: {theoretical_mean:.3f}")
print(f"样本均值: {samp_mean:.3f}")
理论均值: 244.692
样本均值: 243.197

14.5. 离散化对数正态分布#

我们定义辅助函数来创建对数正态概率密度函数的离散化版本。

def lognormal_pdf(x, μ, σ):
    """
    计算对数正态概率密度函数。
    """
    p = 1 / (σ * x * np.sqrt(2 * np.pi)) \
            * np.exp(-0.5 * ((np.log(x) - μ) / σ)**2)
    return p


def discretize_lognormal(μ, σ, I, m):
    """
    创建离散化的对数正态概率质量函数。
    """
    x = np.arange(1e-7, I, m)
    p_array = lognormal_pdf(x, μ, σ)
    p_array_norm = p_array / np.sum(p_array)
    return p_array, p_array_norm, x

我们将网格长度 \(I\) 设置为 2 的幂,以便进行高效的快速傅里叶变换计算。

备注

增大幂次 \(p\)(例如从12增加到15)可以提高近似质量,但会增加计算成本。

# 设置网格参数
p = 15
I = 2**p  # 截断值(2的幂以提高FFT效率)
m = 0.1   # 增量大小

让我们直观地看一下离散化分布对连续对数正态分布的近似效果:

# 计算离散化的概率密度函数
pdf, pdf_norm, x = discretize_lognormal(μ, σ, I, m)

# 绘制离散化的概率密度函数与直方图的对比
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, pdf, 'r-', lw=2, label='离散化概率密度函数')
ax.hist(s1, 1000, density=True, alpha=0.6, label='样本直方图')
ax.set_xlim(0, 2500)
ax.set_xlabel('数值')
ax.set_ylabel('密度')
ax.legend()
plt.show()
_images/039c1b0a24fdf6a264566c8842b037fbad999411883e39a4be3f72e780f3b898.png

图 14.4 离散化密度与样本的对比#

现在让我们验证离散化分布是否具有正确的均值:

# 从离散化的概率密度函数计算均值
mean_discrete = np.sum(x * pdf_norm)
mean_theory = np.exp(μ + 0.5 * σ**2)

print(f"理论均值: {mean_theory:.3f}")
print(f"离散化均值: {mean_discrete:.3f}")
理论均值: 244.692
离散化均值: 244.691

14.6. 概率质量函数的卷积#

现在我们使用卷积定理来计算上面参数化的两个对数正态随机变量之和的概率分布。

我们还将计算上面构造的三个对数正态分布之和的概率。

对于长序列,scipy.signal.fftconvolvenumpy.convolve 快得多,因为它使用了快速傅里叶变换。

让我们先定义傅里叶变换和傅里叶逆变换

14.6.1. 快速傅里叶变换#

序列 \(\{x_t\}_{t=0}^{T-1}\)傅里叶变换

(14.6)#\[x(\omega_j) = \sum_{t=0}^{T-1} x_t \exp(-i \omega_j t)\]

其中 \(\omega_j = \frac{2\pi j}{T}\)\(j = 0, 1, \ldots, T-1\)

序列 \(\{x(\omega_j)\}_{j=0}^{T-1}\)傅里叶逆变换

(14.7)#\[x_t = T^{-1} \sum_{j=0}^{T-1} x(\omega_j) \exp(i \omega_j t)\]

序列 \(\{x_t\}_{t=0}^{T-1}\)\(\{x(\omega_j)\}_{j=0}^{T-1}\) 包含相同的信息。

方程对 (14.6)(14.7) 说明了如何从一个序列恢复其傅里叶对应序列。

程序 scipy.signal.fftconvolve 利用了两个序列 \(\{f_k\}\)\(\{g_k\}\) 的卷积可以通过以下方式计算的定理:

  • 计算序列 \(\{f_k\}\)\(\{g_k\}\) 的傅里叶变换 \(F(\omega)\)\(G(\omega)\)

  • 形成乘积 \(H (\omega) = F(\omega) G (\omega)\)

  • 卷积 \(f * g\)\(H(\omega)\) 的傅里叶逆变换

快速傅里叶变换和相关的快速傅里叶逆变换能够非常快速地执行这些计算。

这就是 fftconvolve 使用的算法。

让我们做一个预热计算,比较 numpy.convolvescipy.signal.fftconvolve 所需的时间

# 离散化三个对数正态分布
_, pmf1, x = discretize_lognormal(μ, σ, I, m)
_, pmf2, x = discretize_lognormal(μ, σ, I, m)
_, pmf3, x = discretize_lognormal(μ, σ, I, m)

# 计时 numpy.convolve
with qe.Timer() as timer_numpy:
    conv_np = np.convolve(pmf1, pmf2)
    conv_np = np.convolve(conv_np, pmf3)
time_numpy = timer_numpy.elapsed

# 计时 fftconvolve
with qe.Timer() as timer_fft:
    conv_fft = fftconvolve(pmf1, pmf2)
    conv_fft = fftconvolve(conv_fft, pmf3)
time_fft = timer_fft.elapsed

print(f"使用 np.convolve 所需时间: {time_numpy:.4f} 秒")
print(f"使用 fftconvolve 所需时间: {time_fft:.4f} 秒")
print(f"加速倍数: {time_numpy / time_fft:.1f}x")
37.4791 seconds elapsed
0.0763 seconds elapsed
使用 np.convolve 所需时间: 37.4791 秒
使用 fftconvolve 所需时间: 0.0763 秒
加速倍数: 491.3x

快速傅里叶变换带来了数量级的加速。

现在让我们将计算得到的两个对数正态随机变量之和的概率质量函数近似值与我们上面形成的样本直方图进行对比绘制

# 计算两个分布的卷积以进行比较
conv2 = fftconvolve(pmf1, pmf2)

fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, conv2[:len(x)] / m, 'r-', lw=2, label='卷积 (FFT)')
ax.hist(ssum2, 1000, density=True, alpha=0.6, label='样本直方图')
ax.set_xlim(0, 5000)
ax.set_xlabel('数值')
ax.set_ylabel('密度')
ax.legend()
plt.show()
_images/9b31f532aee4c6687fb16801d73ac947aa2ae2f35807e230c2c5b1f2d9a57d98.png

图 14.5 卷积与样本的对比,两个分量#

现在我们展示三个对数正态随机变量之和的图:

fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, conv_fft[:len(x)] / m, 'r-', lw=2, label='卷积 (FFT)')
ax.hist(ssum3, 1000, density=True, alpha=0.6, label='样本直方图')
ax.set_xlim(0, 5000)
ax.set_xlabel('数值')
ax.set_ylabel('密度')
ax.legend()
plt.show()
_images/d09b1740605dabf080a5b9d29107b89e2f2a009c09a7dd131c2f1e36e6ba9395.png

图 14.6 卷积与样本的对比,三个分量#

让我们验证均值是否正确

# 两个分布之和的均值
mean_conv2 = np.sum(x * conv2[:len(x)])
mean_theory2 = 2 * np.exp(μ + 0.5 * σ**2)

print(f"两个分布之和:")
print(f"  理论均值: {mean_theory2:.3f}")
print(f"  计算均值: {mean_conv2:.3f}")
两个分布之和:
  理论均值: 489.384
  计算均值: 489.381
# 三个分布之和的均值
mean_conv3 = np.sum(x * conv_fft[:len(x)])
mean_theory3 = 3 * np.exp(μ + 0.5 * σ**2)

print(f"三个分布之和:")
print(f"  理论均值: {mean_theory3:.3f}")
print(f"  计算均值: {mean_conv3:.3f}")
三个分布之和:
  理论均值: 734.076
  计算均值: 734.071

14.7. 故障树分析#

我们即将应用卷积定理来计算故障树分析中顶事件的概率。

在应用卷积定理之前,我们首先描述将组成事件与我们要量化其故障率的顶端事件连接起来的模型。

正如 El-Shanawany et al. [2018] 所描述的,故障树分析是一种广泛使用的评估系统可靠性的技术。

为了构建统计模型,我们反复使用所谓的稀有事件近似

14.7.1. 稀有事件近似#

我们想要计算事件 \(A \cup B\) 的概率。

对于事件 \(A\)\(B\),并集的概率为

\[ P(A \cup B) = P(A) + P(B) - P(A \cap B) \]

其中 \(A \cup B\) 是事件 \(A\) \(B\) 发生的情况,\(A \cap B\) 是事件 \(A\) \(B\) 都发生的情况。

如果 \(A\)\(B\) 是独立的,那么 \(P(A \cap B) = P(A) P(B)\)

\(P(A)\)\(P(B)\) 都很小时,\(P(A) P(B)\) 就更小。

稀有事件近似

\[ P(A \cup B) \approx P(A) + P(B) \]

这种近似方法在系统故障分析中被广泛使用。

14.7.2. 系统故障概率#

考虑一个具有 \(n\) 个关键组件的系统,当任何一个组件发生故障时,系统就会发生故障。

我们假设:

  • 每个组件 \(A_i\) 的故障概率 \(P(A_i)\) 都很小

  • 组件故障在统计上是独立的

我们反复应用稀有事件近似,得到系统故障问题的以下公式:

\[ P(F) \approx P(A_1) + P (A_2) + \cdots + P (A_n) \]

(14.8)#\[P(F) \approx \sum_{i=1}^n P(A_i)\]

其中 \(P(F)\) 是系统故障概率。

每个事件的概率以每年故障率的形式记录。

14.8. 未知的故障率#

现在我们来讨论真正感兴趣的问题,遵循 El-Shanawany et al. [2018]Greenfield and Sargent [1993] 的方法,秉承 Apostolakis [1990] 的精神。

组件故障率 \(P(A_i)\) 并非精确已知,需要进行估计。

我们通过指定概率的概率来解决这个问题,这体现了不了解作为故障树分析输入的构成概率的一种概念。

因此,我们假设系统分析师对系统组件的故障率 \(P(A_i), i =1, \ldots, n\) 存在不确定性。

分析师通过将系统故障概率 \(P(F)\) 和每个组件概率 \(P(A_i)\) 视为随机变量来应对这种情况。

  • \(P(A_i)\) 概率分布的离散程度表征了分析师对故障概率 \(P(A_i)\) 的不确定性

  • \(P(F)\) 的隐含概率分布的离散程度表征了他对系统故障概率的不确定性

这就是所谓的层次化模型,其中分析师对概率 \(P(A_i)\) 本身也有概率估计。

分析师通过以下假设来形式化他的不确定性:

  • 故障概率 \(P(A_i)\) 本身是一个对数正态随机变量,其参数为 \((\mu_i, \sigma_i)\)

  • 对于所有 \(i \neq j\) 的配对,故障率 \(P(A_i)\)\(P(A_j)\) 在统计上是相互独立的。

分析师通过阅读工程论文中的可靠性研究来校准故障事件 \(i = 1, \ldots, n\) 的参数 \((\mu_i, \sigma_i)\),这些研究考察了与所研究系统中使用的组件尽可能相似的组件的历史故障率。

分析师假设,这些关于年度故障率或故障时间的观测分散性的信息,可以帮助他预测零件在其系统中的性能表现。

分析师假设随机变量 \(P(A_i)\) 在统计上是相互独立的。

分析师想要近似系统故障概率 \(P(F)\) 的概率质量函数和累积分布函数。

  • 我们说概率质量函数是因为我们对每个随机变量进行了离散化,正如前文描述的那样。

分析师通过重复应用卷积定理来计算顶事件 \(F\)(即系统故障)的概率质量函数,以计算独立对数正态随机变量之和的概率分布,如方程 (14.8) 所述。

14.9. 应用:废物提升机失效率#

现在我们分析一个具有 \(n = 14\) 个组件的真实案例。

该应用估计了核废料设施中一个关键提升机的年度故障率。

监管机构要求系统的设计能够使顶事件的故障率以高概率保持在较小值。

14.9.1. 模型设定#

我们以接近实际的例子来说明,假设 \(n = 14\)

该例子估计了核废料设施中一个关键提升机的年度故障率。

监管机构希望系统的设计能够使顶事件的故障率以高概率保持在较小值。

这个例子是 Greenfield and Sargent [1993] 第27页表10中描述的设计方案B-2(案例I)。

该表描述了十四个对数正态随机变量的参数 \(\mu_i, \sigma_i\),这些随机变量由七对独立同分布的随机变量组成。

  • 在每一对内,参数 \(\mu_i, \sigma_i\) 是相同的

  • Greenfield and Sargent [1993] 第27页表10所述,七个唯一概率 \(P(A_i)\) 的对数正态分布参数已被校准为以下Python代码中的值:

# 组件故障率参数
# (参见 Greenfield & Sargent 1993 表10)
params = [
    (4.28, 1.1947),   # 组件类型 1
    (3.39, 1.1947),   # 组件类型 2
    (2.795, 1.1947),  # 组件类型 3
    (2.717, 1.1947),  # 组件类型 4
    (2.717, 1.1947),  # 组件类型 5
    (1.444, 1.4632),  # 组件类型 6
    (-0.040, 1.4632), # 组件类型 7 (出现8次)
]

备注

由于故障率都很小,这些对数正态分布实际上描述的是 \(P(A_i) \times 10^{-9}\)

所以我们将在概率质量函数和相关累积分布函数的 \(x\) 轴上标注的概率应该乘以 \(10^{-09}\)

我们定义一个辅助函数来查找数组索引:

def find_nearest(array, value):
    """
    查找数组中最接近给定值的元素的索引。
    """
    array = np.asarray(array)
    idx = (np.abs(array - value)).argmin()
    return idx

我们在以下代码中计算所需的十三个卷积。

(请随意尝试不同的幂参数 \(p\) 值,我们用它来设置网格中的点数,以构建离散化连续对数正态分布的概率质量函数。)

# 设置网格参数
p = 15
I = 2**p
m = 0.05

# 离散化所有组件的故障率分布
# 前6个组件使用各自独特的参数,后8个共享相同的参数
component_pmfs = []
for μ, σ in params[:6]:
    _, pmf, x = discretize_lognormal(μ, σ, I, m)
    component_pmfs.append(pmf)

# 添加8份组件类型7的副本
μ7, σ7 = params[6]
_, pmf7, x = discretize_lognormal(μ7, σ7, I, m)
component_pmfs.extend([pmf7] * 8)

# 通过依次卷积计算系统故障分布
with qe.Timer() as timer:
    system_pmf = component_pmfs[0]
    for pmf in component_pmfs[1:]:
        system_pmf = fftconvolve(system_pmf, pmf)

print(f"13次卷积所需时间: {timer.elapsed:.4f} 秒")
3.9972 seconds elapsed
13次卷积所需时间: 3.9972 秒

现在我们绘制一个与 Greenfield and Sargent [1993] 第29页图5中的累积分布函数(CDF)相对应的图

# 计算累积分布函数
cdf = np.cumsum(system_pmf)

# 绘制累积分布函数
Nx = 1400
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x[:int(Nx / m)], cdf[:int(Nx / m)], 'b-', lw=2)

# 添加关键分位数的参考线
quantile_levels = [0.05, 0.10, 0.50, 0.90, 0.95]
for q in quantile_levels:
    ax.axhline(q, color='gray', linestyle='--', alpha=0.5)

ax.set_xlim(0, Nx)
ax.set_ylim(0, 1)
ax.set_xlabel(r'故障率 (每年 $\times 10^{-9}$)')
ax.set_ylabel('累积概率')
plt.show()
findfont: Failed to find font weight normal, now using 600.
_images/adc5ec80a4842054829ed9bebd4dee50f1f3afd8de1d2454f2f3c18c6afef993.png

图 14.7 系统故障率的累积分布函数#

我们还展示一个与 Greenfield and Sargent [1993] 第28页表11相对应的表,列出了系统故障率分布的关键分位数

# 查找分位数
quantiles = [0.01, 0.05, 0.10, 0.50, 0.665, 0.85, 0.90, 0.95, 0.99, 0.9978]
quantile_values = [x[find_nearest(cdf, q)] for q in quantiles]

# 创建表格
table_data = [[f"{100*q:.2f}%", f"{val:.3f}"]
              for q, val in zip(quantiles, quantile_values)]

print("\n系统故障率分位数 (×10^-9 每年):")
print(tabulate(table_data, 
      headers=['百分位数', '故障率'], tablefmt='grid'))
系统故障率分位数 (×10^-9 每年):
+------------+----------+
| 百分位数   |   故障率 |
+============+==========+
| 1.00%      |    76.15 |
+------------+----------+
| 5.00%      |   106.5  |
+------------+----------+
| 10.00%     |   128.2  |
+------------+----------+
| 50.00%     |   260.55 |
+------------+----------+
| 66.50%     |   338.55 |
+------------+----------+
| 85.00%     |   509.4  |
+------------+----------+
| 90.00%     |   608.8  |
+------------+----------+
| 95.00%     |   807.6  |
+------------+----------+
| 99.00%     |  1470.2  |
+------------+----------+
| 99.78%     |  2474.85 |
+------------+----------+

计算得到的分位数与 [Greenfield and Sargent, 1993] 第28页表11第2列的数据非常接近。

细微的差异可能是由于以下方面的差异所致:

  • 输入参数 \(\mu_i, \sigma_i\) 的数值精度

  • 离散化中的网格点数

  • 网格增量大小

14.10. 练习#

练习 14.1

尝试不同的幂参数 \(p\) 值(它决定了网格大小 \(I = 2^p\))。

尝试 \(p \in \{12, 13, 14, 15, 16\}\) 并比较:

  1. 计算时间

  2. 中位数(第50百分位数)与参考值相比的准确性

  3. 内存使用情况的影响

你观察到了哪些权衡?

练习 14.2

稀有事件近似假设 \(P(A_i) P(A_j)\)\(P(A_i) + P(A_j)\) 相比可以忽略不计。

利用计算得到的分布,计算系统故障率的期望值,并将其与各组件故障率期望值之和进行比较。

在这种情况下,稀有事件近似的效果如何?