You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

利用curve_fit拟合幂律曲线时镜像异常的原因及修正方法

双对数图幂律拟合出现Y轴镜像的原因及修正方法

兄弟,你的问题根本不是curve_fit用错了,而是绘制拟合曲线时的参数传反了

问题根源

看你代码里的这一行:

plt.plot(index_list, power_law(freq_list, *popt))

你把freq_list(也就是原始数据的Y值)当成了幂律函数的输入自变量x,但实际上幂律模型a*x^(-b)的自变量应该是index_list(原始数据的X轴索引)。把Y值当成X代入计算,相当于强行交换了X和Y的角色,结果自然就出现了镜像/扭曲的曲线。

修正方法

只需要把拟合曲线的绘制代码改成用index_list作为power_law的输入即可,同时可以优化细节让图表更清晰:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

f = open("input.txt", "r")
index_list = []
freq_list = []
index = 0
for line in f:
    split_line = line.split()
    freq_list.append(int(split_line[1]))
    index_list.append(index)
    index += 1

# 转成numpy数组,让curve_fit运算更稳定
index_array = np.array(index_list)
freq_array = np.array(freq_list)

# 绘制原始数据双对数图
plt.loglog(index_array, freq_array, label="原始数据")

def power_law(x, a, b):
    return a * np.power(x, -b)

# 执行拟合
popt, pcov = curve_fit(power_law, index_array, freq_array)
# 用正确的自变量index_array计算拟合曲线
plt.loglog(index_array, power_law(index_array, *popt), 'r--', label=f"拟合曲线: a={popt[0]:.2f}, b={popt[1]:.2f}")

plt.legend()
plt.xlabel("Index")
plt.ylabel("Frequency")
plt.show()

额外优化建议

  • 把列表转成numpy数组给curve_fit,运算效率更高,也能避免潜在的列表运算问题
  • 给曲线加图例、坐标轴标签,让图表可读性更强
  • 如果拟合收敛效果不好,可以给curve_fit加初始参数p0,比如p0=[np.max(freq_array), 1],帮助算法更快锁定最优解

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

火山引擎 最新活动