【问题标题】:LogLog regression line is not straight with negative log values?LogLog 回归线不是直的负对数值?
【发布时间】:2019-07-01 03:25:13
【问题描述】:

我有一个相关图,我试图在对数刻度中显示值。我试图在相关图上显示最佳拟合线。

以下是我的代码。

import numpy             as np
import matplotlib        as mpl
import matplotlib.pyplot as plt

from scipy import stats

def loglogplot(seed):
    mpl.rcParams.update({'font.size': 10})
    figh, figw = 1.80118*2, 1.80118*2    
    fig, axes  = plt.subplots(1, 1, figsize=(figh, figw))

    axes.set_xscale('log')
    axes.set_yscale('log')

    np.random.seed(seed)
    x = 10 ** np.random.uniform(-3, 3, size=1000*4)
    y = x * 10 ** np.random.uniform(-1, 1, size=1000*4)
    axes.scatter(x, y, color='black', s=10, alpha=0.1)

    logx = np.log10(x)
    logy = np.log10(y)

    slope, intercept, r_value, p_value, std_err = stats.linregress(logx, logy)
    xps = np.arange(10**-4, 10**4, 1)
    axes.plot(xps, slope * xps + intercept, color='red', lw=2)    

    axes.set_xlim((10**-4, 10**4))
    axes.set_ylim((10**-4, 10**4))

    plt.show()

当使用loglogplot(seed=5) 运行时,我得到以下图像。

当使用loglogplot(seed=10) 运行时,我得到以下图像。

我很困惑,为什么回归线在 x=1 之前没有绘制为直线。我做错了什么?

编辑:将xps = np.arange(10**-4, 10**4, 1)改成xps = np.logspace(-4, 4, 1000),结果在质量上也好不到哪里去。

Seed = 5 给出:

种子 = 10 给出:

【问题讨论】:

  • 尝试使用np.logspace(-4,4,N)而不是np.arange生成xps。
  • 试过了,但没有多大帮助。检查问题中的编辑以获取由更改产生的图像。
  • 您需要将最适合的参数转换回其原始单位
  • 对不起,你能告诉我我应该在哪里做吗?我想我在对数转换空间本身中绘制所有内容,并且事情或多或少是相同的。
  • slope * xps + intercept 不在日志空间中执行

标签: python numpy matplotlib plot regression


【解决方案1】:

这里问题的症结在于对数刻度不会转换数据,而是转换数据在图纸空间中的显示位置。这意味着,您不能采用对数转换的最佳拟合参数并将它们用于非对数转换的数据,并正确绘制它。

您需要对数据进行日志转换并直接使用它们,或者您需要考虑您实际建模的关系并(根据需要撤消它)。

通过拟合数据的日志,您已经符合以下等式:

log(y) = m * log(x) + p

使用数学,这变成:

y = exp(p) * (x ^ m)

所以你的代码变成了:

import numpy
from matplotlib import rcParams, pyplot
from scipy import stats

def loglogplot(seed):
    rcParams.update({'font.size': 10})
    figh, figw = 1.80118*2, 1.80118*2    
    fig, axes  = pyplot.subplots(1, 1, figsize=(figh, figw))

    axes.set_xscale('log')
    axes.set_yscale('log')

    numpy.random.seed(seed)
    x = 10 ** numpy.random.uniform(-3, 3, size=1000*4)
    y = x * 10 ** numpy.random.uniform(-1, 1, size=1000*4)
    axes.scatter(x, y, color='black', s=10, alpha=0.1)

    logx = numpy.log(x)  # <-- doesn't matter that we use natural log
    logy = numpy.log(y)  #     so long as we're consistent

    slope, intercept, r_value, p_value, std_err = stats.linregress(logx, logy)
    xhat = numpy.logspace(-4, 4, 1000)
    yhat = numpy.exp(intercept) * xhat ** slope  # exp -> consistency
    axes.plot(xhat, yhat, color='red', lw=2)    

    axes.set_xlim((10**-4, 10**4))
    axes.set_ylim((10**-4, 10**4))

    return fig

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-29
    • 2020-12-24
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 2020-04-07
    • 2021-08-09
    • 2020-12-24
    相关资源
    最近更新 更多