【问题标题】:Linear regression to fit a power-law in Python线性回归以拟合 Python 中的幂律
【发布时间】:2021-01-15 06:07:06
【问题描述】:

我有两个数据集index_listfrequency_list,我用plt.loglog(index_list, freq_list) 在对数图中绘制它们。现在我正在尝试用线性回归拟合幂律a*x^(-b)。我希望曲线紧跟初始曲线,但以下代码似乎输出了类似的曲线,但在 y 轴上镜像。 我怀疑我使用 curve_fit 很糟糕。

为什么这条曲线在 x 轴上镜像,我怎样才能让它正确地适合我的初始曲线?

Using this data

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

plt.loglog(index_list, freq_list)
def power_law(x, a, b):
    return a * np.power(x, -b)

popt, pcov = curve_fit(power_law, index_list, freq_list)
plt.plot(index_list,  power_law(freq_list, *popt))
plt.show()

【问题讨论】:

  • 是的,不幸的是,这只会导致y=x
  • @JohanC 我已经编辑了帖子以包含示例数据。

标签: matplotlib linear-regression power-law


【解决方案1】:

下面的代码做了如下改动:

  • 为了使 scipy 函数正常工作,最好 index_listfreq_list 都是 numpy 数组,而不是 Python 列表。此外,为了使 power 不会过快溢出,这些数组应该是 float 类型(而不是 int)。
  • 由于0 的负幂会导致除零问题,因此将index_list1 开头是有意义的。
  • 由于权力的原因,浮点数也会产生溢出。因此,为curve_fit 添加边界是有意义的。特别是b应该限制在不超过50左右(最大值约为power(100000, b) giving an overflow when be.g. is100)。此外,设置初始值有助于指导拟合过程(p0=...)。
  • index_list 作为xpower_law(freq_list, ...) 作为y 绘制一个绘图会产生一条非常奇怪的曲线。绘图和函数必须使用相同的x

请注意,调用 plt.loglog() 会将绘图的两个轴更改为对数。同一轴上的所有后续绘图将继续使用对数刻度。

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

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

df = pd.read_csv("https://norvig.com/google-books-common-words.txt", delim_whitespace=True, header=None)

index_list = df.index.to_numpy(dtype=float) + 1
freq_list = df[1].to_numpy(dtype=float)

plt.loglog(index_list, freq_list, label='given data')

popt, pcov = curve_fit(power_law, index_list, freq_list, p0=[1, 1], bounds=[[1e-3, 1e-3], [1e20, 50]])

plt.plot(index_list, power_law(index_list, *popt), label='power law')
plt.legend()
plt.show()

【讨论】:

    猜你喜欢
    • 2015-11-23
    • 1970-01-01
    • 2016-06-24
    • 2020-05-15
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    相关资源
    最近更新 更多