代码之家  ›  专栏  ›  技术社区  ›  neo4k

对数回归线不直,对数值为负?

  •  2
  • neo4k  · 技术社区  · 7 年前

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

    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)

    LogLog function invocation with seed=5

    当与 loglogplot(seed=10) 我得到下面的图像。

    LogLog function invocation with seed=5

    我预先弄明白了为什么在x=1之前,回归线没有绘制成一条直线。我做错了什么?

    编辑:已更改 xps = np.arange(10**-4, 10**4, 1) xps = np.logspace(-4, 4, 1000) 从定性上看,结果并不好。

    LogSpace points between -4 and 4 for seed=5

    Seed=10表示:

    LogSpace points between -4 and 4 for seed=10

    1 回复  |  直到 7 年前
        1
  •  2
  •   Paul H    7 年前

    问题的关键在于 日志比例不会转换数据 . 这意味着,您不能将日志转换后的最佳拟合参数用于非日志转换后的数据,并正确地进行打印。

    您要么需要记录转换数据并直接使用它们,要么需要考虑实际建模的关系并(根据需要撤消它)。

    通过拟合数据日志,您可以拟合以下等式:

    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
    

    enter image description here