<p>在日志刻度上沿直线下降的数据遵循<code>y = c*x^(m)</code>形式的幂关系。通过取两边的对数,可以得到要拟合的线性方程:</p>
<pre><code>log(y) = m*log(x) + c
</code></pre>
<p>调用<code>np.polyfit(log(x), log(y), 1)</code>提供<code>m</code>和{<cd4>}的值。然后可以使用这些值计算<code>log_y_fit</code>的拟合值,如下所示:</p>
^{pr2}$
<p>要根据原始数据绘制的拟合值为:</p>
<pre><code>y_fit = exp(log_y_fit) = exp(m*log(x) + c)
</code></pre>
<p>所以,你面临的两个问题是:</p>
<ol>
<li><p>使用原始x坐标而不是对数(x)坐标计算拟合值</p></li>
<li><p>绘制拟合y值的对数而不将其转换回原始比例</p></li>
</ol>
<p>在下面的代码中,我将<code>plt.plot(z, np.poly1d(np.polyfit(logA, logB, 1))(z))</code>替换为:</p>
<pre><code>m, c = np.polyfit(logA, logB, 1) # fit log(y) = m*log(x) + c
y_fit = np.exp(m*logA + c) # calculate the fitted values of y
plt.plot(z, y_fit, ':')
</code></pre>
<p>这可以放在一行:<code>plt.plot(z, np.exp(np.poly1d(np.polyfit(logA, logB, 1))(logA)))</code>,但我发现这使得调试更加困难。在</p>
<p>以下代码中有一些不同之处:</p>
<ul>
<li><p>当您从<code>z</code>计算<code>logA</code>以过滤掉任何值<;1时,您正在使用列表理解,但是<code>z</code>是一个线性范围,只有第一个值是<;1。从1开始创建<code>z</code>似乎更容易,我就是这样编码的。</p></li>
<li><p>我不知道你为什么在你的列表理解中使用<code>x*log(x)</code>这个词。这在我看来是个错误,所以我没有把它包括在答案中。</p></li>
</ul>
<p>此代码应能正确工作:</p>
<pre><code>fig=plt.figure()
ax = fig.add_subplot(111)
z=np.arange(1, len(x)+1) #start at 1, to avoid error from log(0)
logA = np.log(z) #no need for list comprehension since all z values >= 1
logB = np.log(y)
m, c = np.polyfit(logA, logB, 1) # fit log(y) = m*log(x) + c
y_fit = np.exp(m*logA + c) # calculate the fitted values of y
plt.plot(z, y, color = 'r')
plt.plot(z, y_fit, ':')
ax.set_yscale('symlog')
ax.set_xscale('symlog')
#slope, intercept = np.polyfit(logA, logB, 1)
plt.xlabel("Pre_referer")
plt.ylabel("Popularity")
ax.set_title('Pre Referral URL Popularity distribution')
plt.show()
</code></pre>
<p>当我在模拟数据上运行它时,我得到以下图表:</p>
<p><a href="https://i.stack.imgur.com/n4UMR.png" rel="noreferrer"><img src="https://i.stack.imgur.com/n4UMR.png" alt="Log-log graph with fitted line"/></a></p>
<p><strong>注意事项:</strong></p>
<ul>
<li><p>行的左右两端的“扭结”是使用“symlog”的结果,它将极小的值线性化,如<a href="https://stackoverflow.com/questions/3305865/what-is-the-difference-between-log-and-symlog">What is the difference between 'log' and 'symlog'?</a>的答案所述。如果这些数据绘制在“对数-对数”轴上,则拟合的数据将是一条直线。</p></li>
<li><p>您可能还想阅读这个答案:<a href="https://stackoverflow.com/a/3433503/7517724">https://stackoverflow.com/a/3433503/7517724</a>,它解释了如何使用加权来实现对日志转换数据的“更好”拟合。</p></li>
</ul>