截尾正态分布

https://www.zhihu.com/question/49923924/answer/136319388

<think>我们讨论的是单边截尾正态分布(Truncated Normal Distribution),具体是右截尾(从左侧截断)的情况。给定密度函数: \[ f(v) = \begin{cases} \frac{1}{\sigma_z} \cdot \frac{\phi\left(\frac{v - h_0}{\sigma_z}\right)}{1 - \Phi\left(\frac{l - h_0}{\sigma_z}\right)} & \text{for } l < v < +\infty \\ 0 & \text{otherwise} \end{cases} \] 这实际上是正态分布 \( \mathcal{N}(h_0, \sigma_z^2) \) 在区间 \((l, +\infty)\) 上的截断分布。其中,\(\phi\) 是标准正态密度函数,\(\Phi\) 是标准正态累积分布函数。 在Matlab中,我们可以利用内置函数`normpdf`和`normcdf`来实现。为了支持向量化计算(即v可以是向量),我们需要对代码进行修改,使得当v是向量时,对每个元素分别计算。 ### 向量化版本的Matlab代码 ```matlab function f = truncated_normal_pdf(v, h0, sigma_z, l) % 计算单边截尾正态分布的密度函数(右截尾,截断点为l,定义域v>l) % 输入: v (标量、向量或矩阵), h0 (均值参数), sigma_z (标准差参数), l (截断点) % 输出: f (与v相同大小的密度值数组) % 初始化输出数组,与v同大小,初始值为0(对应v<=l的情况) f = zeros(size(v)); % 找出v>l的索引 idx = (v > l); % 计算分母:1 - Φ((l - h0)/sigma_z) denominator = 1 - normcdf((l - h0) / sigma_z); % 对于v>l的元素,计算密度 if denominator > 0 % 计算分子:φ((v(idx) - h0)/sigma_z) numerator = normpdf((v(idx) - h0) / sigma_z); % 计算密度值 f(idx) = (1 / sigma_z) * (numerator / denominator); else % 如果分母为0(或接近0),则避免除0错误,这里可以设置为0或NaN,根据需求 % 由于分母为0意味着截断点l右侧的概率为0,所以理论上密度应为0,但实际中可能是数值问题 % 我们可以选择将大于l的点设为NaN,或者0。这里设为NaN以表示异常。 f(idx) = NaN; end end ``` ### 代码说明: 1. 向量化处理:通过逻辑索引`idx`,只对满足`v>l`的元素进行计算,其余元素保持0。 2. 分母计算:分母是一个常数(与v无关),所以只需计算一次。 3. 分母为零的处理:当分母为零时,表示截断部分没有概率质量,因此理论上密度函数在截断区间内应为0。但由于浮点计算,分母可能非常接近0,导致数值不稳定。这里我们检查分母是否大于0,否则将对应位置设为NaN(也可以根据实际需求设为0或使用其他数值稳定方法)。 ### 数值稳定性的进一步考虑: 如果分母非常小(接近0),那么分子通常也会非常小(因为v>l且l已经很大,所以v更大,正态密度也很小),但两者的比值可能并不小。然而,在分母接近0时,计算可能会受到浮点误差的影响。一种改进方法是使用正态分布的互补累积分布函数(即`normcdf`的补)的精确计算方法,但Matlab的`normcdf`函数已经相对稳定。另外,我们可以使用对数变换来避免小数的除法,但这里由于分母是常数,且分子分母都是小数值,所以直接除法在大多数情况下是可行的。如果分母小于一个很小的阈值(如1e-10),我们可以认为截断部分几乎不可能发生,从而返回0或NaN。 ### 应用场景: 这种分布常用于需要避免低于某个阈值的随机变量的建模,例如: - 工程中的强度要求(材料强度必须超过某个最小值)。 - 金融中的损失分布(只关心超过某个阈值的损失)。 - 生存分析中的生存时间(通常只关心大于某个时间点的生存情况)。 §§相关问题§§ 1. 如何从单边截尾正态分布中生成随机数? 2. 在参数估计中,如何利用最大似然估计法估计单边截尾正态分布的参数(如h0, sigma_z, l)? 3. 双边截尾正态分布(同时有上界和下界)的密度函数如何表示?如何用Matlab实现? 4. 截尾正态分布与删失正态分布(Censored Normal Distribution)有什么区别?</think>### 单边截尾正态分布(Truncated Normal Distribution) 单边截尾正态分布正态分布在一个方向(通常为右侧)被截断后的概率分布。给定密度函数: \[ f(v) = \begin{cases} \frac{1}{\sigma_z} \cdot \frac{\phi\left(\frac{v - h_0}{\sigma_z}\right)}{1 - \Phi\left(\frac{l - h_0}{\sigma_z}\right)} & \text{for } l < v < +\infty \\ 0 & \text{otherwise} \end{cases} \] #### 关键特征: 1. **截断点**:在 \( v = l \) 处右截断(只保留大于 \( l \) 的部分) 2. **参数**: - \( h_0 \):原始正态分布的均值 - \( \sigma_z \):原始正态分布的标准差 - \( l \):截断点 3. **归一化因子**:分母 \( 1 - \Phi\left(\frac{l - h_0}{\sigma_z}\right) \) 确保密度积分为1 #### MATLAB 实现代码 ```matlab function pdf = truncated_normal_pdf(v, mu, sigma, trunc_point) % 单边截尾正态分布密度函数(右截断) % v: 输入值(标量/向量) % mu: 原始正态分布均值 (h0) % sigma: 原始正态分布标准差 (σz) % trunc_point: 截断点 (l) % 标准化计算 z_v = (v - mu) / sigma; z_trunc = (trunc_point - mu) / sigma; % 计算分母(截断部分累积概率) denominator = 1 - normcdf(z_trunc); % 初始化PDF pdf = zeros(size(v)); % 仅对 v > trunc_point 计算密度 idx = v > trunc_point; pdf(idx) = (1/sigma) .* normpdf(z_v(idx)) ./ denominator; end ``` #### 使用示例: ```matlab % 生成测试数据 v = linspace(0, 10, 100); % 计算截尾分布密度 (h0=3, σz=1.5, l=2) pdf_values = truncated_normal_pdf(v, 3, 1.5, 2); % 可视化 plot(v, pdf_values); xlabel('v'); ylabel('Probability Density'); title('Right-Truncated Normal Distribution (l=2)'); grid on; ``` #### 应用场景: 1. 金融风险管理(极端损失建模) 2. 工程可靠性分析(零件寿命>阈值) 3. 环境科学(污染物浓度>安全限值) 4. 生存分析(患者生存时间>治疗期)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值