You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中使用curve_fit对loglog双对数数据进行直线拟合

双对数图幂律拟合代码调整方案

你当前使用curve_fit直接拟合原始幂律函数的逻辑,是在原始线性数值空间最小化残差平方和,大数值点的残差会主导拟合结果,因此在对数尺度下观察时,小数值区间的拟合偏差会非常明显,这就是你拟合效果不佳的核心原因。

调整方案

方案1:对数转换后做线性拟合(推荐,最适配双对数场景)

幂律关系y = a*x^b两边取常用对数后可得log10(y) = log10(a) + b*log10(x),属于标准线性关系,直接对对数化后的数据做线性拟合即可得到准确斜率,完全适配双对数坐标的拟合需求。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import linregress

fig = plt.figure(figsize=[7,7])
ax = plt.axes()
ax.set_xscale("log")
ax.set_yscale("log")
y_val = unumpy.nominal_values(dn_dm)
ax.errorbar(m, y_val , yerr= unumpy.std_devs(dn_dm), fmt='k.', label='Data')

# 过滤y<=0的无效点(对数运算要求输入为正)
mask = y_val > 0
log_m = np.log10(m[mask])
log_y = np.log10(y_val[mask])

# 线性拟合
res = linregress(log_m, log_y)
b = res.slope
a = 10 ** res.intercept
print(f"拟合斜率为:{b:.3f}")

newX = np.logspace(-.25, .5, base=10)
ax.plot(newX, a * np.power(newX, b), 'r-', label=f'拟合线: 斜率={b:.3f}')
ax.legend()

方案2:改进curve_fit的加权逻辑

如果你需要保留对原始幂律函数的拟合,可以给curve_fit添加权重,抵消大数值点的残差主导效应,最小化对数尺度下的残差:

from scipy.optimize import curve_fit

# 过滤无效点
y_val = unumpy.nominal_values(dn_dm)
mask = y_val > 0
m_filtered = m[mask]
y_filtered = y_val[mask]

def myExpFunc(x, a, b):
    return a * np.power(x, b)
# 加权拟合,权重设置等价于最小化对数空间残差
popt, pcov = curve_fit(myExpFunc, m_filtered, y_filtered, sigma=y_filtered, absolute_sigma=True)

newX = np.logspace(-.25, .5, base=10)
ax.plot(newX, myExpFunc(newX, *popt), 'r-', label=f'拟合线: 斜率={popt[1]:.3f}')

拟合效果参考

拟合效果示意图

内容的提问来源于stack exchange,提问作者Lewis Cooper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 16:54:09