使用Scipy rv_continuous实现Kumaraswamy-Laplace分布拟合时出现NaN错误的问题求助
使用Scipy rv_continuous实现Kumaraswamy-Laplace分布拟合时出现NaN错误的问题求助
我最近在尝试用Scipy的rv_continuous类自定义Kumaraswamy-Laplace分布,用来拟合市场收益率数据,参考了相关论文和社区思路,但拟合阶段一直碰到NaN相关的报错,折腾好一阵都没解决,特来求助!
问题概况
我已经实现了该分布的PDF和参数校验逻辑,手动给定参数绘制PDF/CDF时结果完全符合预期,但一调用fit()方法拟合样本数据,就会抛出:
ValueError: The function value at x=nan is NaN; solver cannot continue.
我怀疑是数值计算过程中出现了溢出或无效值,但摸不准具体哪里出问题,也不清楚自定义这类分布做拟合时,有哪些数值稳定性的细节需要注意。
自定义分布的实现代码
import numpy as np import scipy.stats as st class kl(st.rv_continuous): def _pdf(self, x, mu, sigma, p, q): v = (x - mu) / sigma # 分正负区间实现的PDF计算逻辑 fx = np.where( v < 0, p * q * 2. ** (-p) * np.exp(p * v) * (1. - 2. ** (-p) * np.exp(p * v)) ** (q - 1.), .5 * p * q * np.exp(-v) * (1. - .5 * np.exp(-v)) ** (p - 1.) * (1. - (1. - .5 * np.exp(-v)) ** p) ** (q - 1.) ) return fx def _argcheck(self, mu, sigma, p, q): # 确保参数的合法性:sigma、p、q必须为正 s = sigma > 0 p_bool = p > 0 q_bool = q > 0 all_bool = s & p_bool & q_bool return all_bool
拟合与绘图相关代码
触发报错的拟合代码
# 初始参数猜测:均值、标准差、p、q initial_guess = [np.mean(sample_data), np.std(sample_data), 1.0, 1.0] my_kl_distribution = kl() # 执行这行代码时就会抛出NaN相关的ValueError estimated_params = my_kl_distribution.fit(sample_data, *initial_guess)
正常工作的手动参数绘图代码
import matplotlib.pyplot as plt # 手动指定参数生成分布实例 mu = 0 sigma = 1 p = 0.6 q = 0.7 my_kl_distribution = kl() # 生成绘图用的x轴数据 x_values = np.linspace(-5, 5, 1000) # 计算PDF和CDF值 pdf_values = my_kl_distribution.pdf(x_values, mu, sigma, p, q) cdf_values = my_kl_distribution.cdf(x_values, mu, sigma, p, q) # 绘制PDF plt.figure(figsize=(10, 5)) plt.plot(x_values, pdf_values, label='PDF') plt.title('Kumaraswamy-Laplace分布的概率密度函数(PDF)') plt.xlabel('x') plt.ylabel('密度') plt.legend() plt.grid(True) plt.show() # 绘制CDF plt.figure(figsize=(10, 5)) plt.plot(x_values, cdf_values, label='CDF', color='orange') plt.title('Kumaraswamy-Laplace分布的累积分布函数(CDF)') plt.xlabel('x') plt.ylabel('概率') plt.legend() plt.grid(True) plt.show()
测试用的样本数据
我使用的是CAC40指数的收益率数据,处理代码如下:
import yfinance as yf import datetime start_date = datetime.datetime(2010, 1, 1) end_date = datetime.datetime.now() cac40_data = yf.download("^FCHI", start=start_date, end=end_date) daily_close = cac40_data['Close'] variations_cac40 = daily_close.pct_change().dropna() * 100 sample_data = np.log(np.add(1, variations_cac40 / 100)).dropna()
我已经排查的内容
- 手动给定参数时,PDF/CDF的绘制结果完全符合预期,说明正常参数下PDF逻辑是正确的
- 已经通过
_argcheck方法确保了sigma、p、q均为正数 - 尝试过两种不同的PDF实现逻辑,拟合时都会触发相同的NaN报错
想请教各位大佬:
- 这个NaN错误大概率出在数值计算的哪个环节?
- 自定义这类分区间处理的分布时,在数值稳定性上有什么需要注意的细节?
- 有没有什么调整方法能让拟合过程顺利进行?
内容来源于stack exchange
相关产品推荐
相关产品推荐

