文章目录
- 相关教程
- 基本信息
- 数学定义
- 参数的影响
- Python 实现
- 安装 `scipy`
- 生成和绘制偏正态分布的数据
- 解释
- 应用
- 右偏(即长尾在右侧)的正态分布
- 1. 对数变换 (Log Transformation)
- 2. 平方根变换 (Square Root Transformation)
- 3. Box-Cox 变换
- 注意事项
- 左偏(即长尾在左侧)的正态分布
- 1. 对数变换 (Log Transformation)
- 2. 平方根变换 (Square Root Transformation)
- 3. Box-Cox 变换
- 4. 幂变换 (Power Transformation)
- 5. 反正弦变换 (Arcsin Transformation)
- 注意事项
作者:小猪快跑
基础数学&计算数学,从事优化领域7年+,主要研究方向:MIP求解器、整数规划、随机规划、智能优化算法
偏正态分布(Skew Normal Distribution)是一种扩展了标准正态分布的连续概率分布,它允许数据具有偏斜性。标准正态分布是对称的,而偏正态分布则可以是左偏或右偏的。偏正态分布在金融、经济、生物统计等领域中广泛应用,因为现实世界中的许多数据集往往不是完全对称的。
如有错误,欢迎指正。如有更好的算法,也欢迎交流!!!——@小猪快跑
相关教程
- 常用分布的数学期望、方差、特征函数
- 【推导过程】常用离散分布的数学期望、方差、特征函数
- 【推导过程】常用连续分布的数学期望、方差、特征函数
- Z分位数速查表
- 【概率统计通俗版】极大似然估计
- 【附代码&原理】正态分布检验
- 【附代码&原理】偏正态分布的数据处理方法
- 【机器学习】【通俗版】EM算法(待更新)
基本信息
偏正态分布(Skew Normal Distribution)是一种扩展了标准正态分布的连续概率分布,它允许数据具有偏斜性。标准正态分布是对称的,而偏正态分布则可以是左偏或右偏的。偏正态分布在金融、经济、生物统计等领域中广泛应用,因为现实世界中的许多数据集往往不是完全对称的。
数学定义
偏正态分布由三个参数定义:
- 位置参数(Location Parameter) ξ \xi ξ:表示分布的中心位置。
- 尺度参数(Scale Parameter) ω \omega ω:控制分布的扩散程度,类似于标准差。
- 形状参数(Shape Parameter) α \alpha α:控制分布的偏斜方向和程度。当 α = 0 \alpha = 0 α=0 时,偏正态分布退化为标准正态分布。
偏正态分布的概率密度函数(PDF)可以表示为:
f ( x ; ξ , ω , α ) = 2 ω ϕ ( x − ξ ω ) Φ ( α ( x − ξ ω ) ) f(x; \xi, \omega, \alpha) = \frac{2}{\omega} \phi\left(\frac{x - \xi}{\omega}\right) \Phi\left(\alpha \left(\frac{x - \xi}{\omega}\right)\right) f(x;ξ,ω,α)=ω2ϕ(ωx−ξ)Φ(α(ωx−ξ))
其中:
-
ϕ
(
z
)
\phi(z)
ϕ(z) 是标准正态分布的密度函数:
ϕ ( z ) = 1 2 π e − z 2 2 \phi(z) = \frac{1}{\sqrt{2\pi}} e^{-\frac{z^2}{2}} ϕ(z)=2π1e−2z2 -
Φ
(
z
)
\Phi(z)
Φ(z) 是标准正态分布的累积分布函数(CDF):
Φ ( z ) = ∫ − ∞ z ϕ ( t ) d t \Phi(z) = \int_{-\infty}^{z} \phi(t) \, dt Φ(z)=∫−∞zϕ(t)dt
参数的影响
- 位置参数 ξ \xi ξ:决定了分布的中心位置。改变 ξ \xi ξ 会使整个分布沿 x 轴平移。
- 尺度参数 ω \omega ω:决定了分布的宽度。增大 ω \omega ω 会使分布变得更加分散,减小 ω \omega ω 会使分布变得更加集中。
- 形状参数 α \alpha α:决定了分布的偏斜方向和程度。当 α > 0 \alpha > 0 α>0 时,分布右偏;当 α < 0 \alpha < 0 α<0 时,分布左偏;当 α = 0 \alpha = 0 α=0 时,分布退化为标准正态分布。
Python 实现
在Python中,可以使用 scipy.stats
库中的 skewnorm
模块来生成和处理偏正态分布的数据。
安装 scipy
如果您还没有安装 scipy
,可以使用 pip 安装:
pip install scipy
生成和绘制偏正态分布的数据
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import skewnorm
# 定义偏正态分布的参数
xi = 5 # 位置参数
omega = 2 # 尺度参数
alpha = 5 # 形状参数
# 生成偏正态分布的数据
data = skewnorm.rvs(a=alpha, loc=xi, scale=omega, size=1000)
# 绘制直方图
plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, density=True, alpha=0.6, color='g', edgecolor='black')
plt.title('Skew Normal Distribution')
plt.xlabel('Value')
plt.ylabel('Density')
# 绘制理论的偏正态分布曲线
x = np.linspace(min(data), max(data), 1000)
pdf = skewnorm.pdf(x, a=alpha, loc=xi, scale=omega)
plt.plot(x, pdf, 'r-', lw=2)
plt.show()
解释
- 位置参数 ξ \xi ξ:控制分布的中心位置。
- 尺度参数 ω \omega ω:控制分布的宽度。
- 形状参数
α
\alpha
α:控制分布的偏斜方向和程度。在这个例子中,
alpha = 5
表示分布右偏。
应用
偏正态分布广泛应用于以下领域:
- 金融:用于建模股票价格、收益率等。
- 经济学:用于分析收入分布、消费行为等。
- 生物学:用于描述生物体的生长模式、基因表达等。
- 工程:用于可靠性分析、质量控制等。
通过使用偏正态分布,可以更准确地描述和分析那些具有偏斜性的数据集,从而提高模型的准确性和解释能力。
右偏(即长尾在右侧)的正态分布
当您的数据呈现出右偏(即长尾在右侧)的正态分布时,这意味着数据集中存在较多的大值,导致分布曲线向右延伸。对于这种类型的数据,有几种常见的处理方法,旨在使数据更加符合标准正态分布,从而提高统计分析的有效性和模型的性能。以下是几种处理右偏数据的方法:
1. 对数变换 (Log Transformation)
对数变换是处理右偏数据最常用的方法之一。通过取数据的自然对数(或10为底的对数),可以压缩较大的值,使得数据分布更加对称。
import numpy as np
import matplotlib.pyplot as plt
# 假设 data 是一个右偏的数据集
data = np.random.lognormal(mean=0, sigma=1, size=1000)
# 应用对数变换
log_data = np.log(data)
# 绘制原始数据和变换后的数据的直方图
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.hist(log_data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Log Transformed Data')
plt.show()
2. 平方根变换 (Square Root Transformation)
平方根变换同样可以减少数据的偏斜度,尤其适用于数据中有许多接近于零的小值的情况。
sqrt_data = np.sqrt(data)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.hist(sqrt_data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Square Root Transformed Data')
plt.show()
3. Box-Cox 变换
Box-Cox 变换是一种更为通用的方法,它可以应用于一系列连续的非负数据。它实际上是一系列幂变换的集合,包括对数变换、平方根变换等。Box-Cox 变换会找到一个最佳的λ值来最小化数据的偏斜度。
from scipy.stats import boxcox
# 执行 Box-Cox 变换
bc_data, _ = boxcox(data)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.hist(bc_data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Box-Cox Transformed Data')
plt.show()
注意事项
- 数据范围:确保您的数据是非负的,因为对数变换和 Box-Cox 变换不适用于负数或零。
- 解释性:变换后的数据可能难以直接解释,因此在报告结果时需要转换回原始尺度。
- 模型假设:并非所有模型都要求输入数据严格服从正态分布,因此在应用任何变换之前,请考虑您的具体需求和所使用的模型类型。
左偏(即长尾在左侧)的正态分布
当您的数据呈现出左偏(即长尾在左侧)的正态分布时,这意味着数据集中存在较多的小值,导致分布曲线向左延伸。处理左偏数据的目标是通过适当的变换使数据更加对称,从而更接近正态分布。以下是一些常用的处理方法及其Python实现:
1. 对数变换 (Log Transformation)
对数变换通常用于处理右偏数据,但对于左偏数据,可以尝试对数据取相反数后再进行对数变换。
import numpy as np
import matplotlib.pyplot as plt
# 假设 data 是一个左偏的数据集
data = -np.random.lognormal(mean=0, sigma=1, size=1000)
# 应用对数变换
log_data = np.log(-data)
# 绘制原始数据和变换后的数据的直方图
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.hist(log_data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Log Transformed Data')
plt.show()
2. 平方根变换 (Square Root Transformation)
平方根变换也可以用于处理左偏数据,方法类似对数变换,即对数据取相反数后再进行平方根变换。
sqrt_data = np.sqrt(-data)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.hist(sqrt_data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Square Root Transformed Data')
plt.show()
3. Box-Cox 变换
Box-Cox 变换是一种更为通用的方法,但它通常适用于非负数据。对于左偏数据,可以尝试对数据取相反数后再进行 Box-Cox 变换。
from scipy.stats import boxcox
# 对数据取相反数
neg_data = -data
# 执行 Box-Cox 变换
bc_data, _ = boxcox(neg_data)
# 再次取相反数以恢复数据的方向
bc_data = -bc_data
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.hist(bc_data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Box-Cox Transformed Data')
plt.show()
4. 幂变换 (Power Transformation)
幂变换是一种更灵活的方法,可以通过调整幂次来处理不同类型的偏斜。对于左偏数据,可以尝试使用负幂次。
# 选择一个合适的幂次
power = -0.5
# 应用幂变换
power_data = np.power(-data, power)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.hist(power_data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Power Transformed Data')
plt.show()
5. 反正弦变换 (Arcsin Transformation)
反正弦变换主要用于处理比例数据,但在某些情况下也可以用于处理左偏数据。
# 应用反正弦变换
arcsin_data = np.arcsin(np.sqrt(-data / np.max(-data)))
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.hist(arcsin_data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Arcsin Transformed Data')
plt.show()
注意事项
- 数据范围:确保您的数据在变换前后的合理范围内。特别是对数变换和 Box-Cox 变换不适用于负数或零。
- 解释性:变换后的数据可能难以直接解释,因此在报告结果时需要转换回原始尺度。
- 模型假设:并非所有模型都要求输入数据严格服从正态分布,因此在应用任何变换之前,请考虑您的具体需求和所使用的模型类型。