![](/img/trans.png)
[英]Fitting a dataset with a straight line using polyfit on a log-log plot
[英]Fitting a straight line to a log-log curve in matplotlib
我和我有一個情節,兩個軸都是對數的。 我有pyplot的loglog
函數來執行此操作。 它還給出了兩個軸上的對數刻度。
現在,使用numpy我直線到我擁有的點集。 但是,當我在情節上繪制這條線時,我無法得到一條直線。 我得到一條曲線。
藍線是所謂的“直線”。 它沒有直接繪制。 我想將這條直線擬合到由紅點繪制的曲線上
這是我用來繪制點數的代碼:
import numpy
from matplotlib import pyplot as plt
import math
fp=open("word-rank.txt","r")
a=[]
b=[]
for line in fp:
string=line.strip().split()
a.append(float(string[0]))
b.append(float(string[1]))
coefficients=numpy.polyfit(b,a,1)
polynomial=numpy.poly1d(coefficients)
ys=polynomial(b)
print polynomial
plt.loglog(b,a,'ro')
plt.plot(b,ys)
plt.xlabel("Log (Rank of frequency)")
plt.ylabel("Log (Frequency)")
plt.title("Frequency vs frequency rank for words")
plt.show()
為了更好地理解這個問題,讓我們首先談談普通的線性回歸( polyfit
函數,在這種情況下,是你的線性回歸算法)。
假設您有一組數據點(x,y),如下所示:
您想要創建一個模型,將y
預測為x
的函數,因此您可以使用線性回歸。 那使用模型:
y = mx + b
並使用一些線性代數計算最能預測數據的m
和b
的值。
接下來,使用模型預測y的值作為x的函數。 您可以通過為x(想想linspace)選擇一組值並計算y的相應值來完成此操作。 繪制這些(x,y)對可以得到回歸線。
現在,我們來談談對數回歸。 在這種情況下,我們仍然有兩個變量,Y與X,我們仍有興趣在他們的關系,即能預測y
給出x
。 唯一的區別是,現在y
和x
恰好是兩個其他變量的對數,我稱之為log(F)
和log(R)
。 到目前為止,這只不過是名稱的簡單更改。
線性回歸也以相同的方式工作。 你仍然在回歸y和x。 線性回歸算法並不關心y
和x
實際上是log(F)
和log(R)
- 它對算法沒有影響。
最后一步有點不同 - 這就是你在上面的情節中被絆倒的地方。 你正在做的是計算
F = m R + b
但這是不正確的,因為F
和R
之間的關系不是線性的。 (這就是你使用對數日志圖的原因。)
相反,你應該計算
log(F) = m log(R) + b
如果你改變它(將10增加到雙方的力量並重新排列),你得到
F = c R^m
其中c = 10^b
。 這是F
和R
之間的關系:它是一種冪律關系。 (冪律關系是對數 - 對數圖最好的。)
在你的代碼中,你在調用polyfit
時使用的是A和B,但你應該使用log(A)
和log(B)
。
您的線性擬合不會在loglog-plot中顯示的相同數據上執行。
制作像這樣的a和b numpy數組
a = numpy.asarray(a, dtype=float)
b = numpy.asarray(b, dtype=float)
現在您可以對它們執行操作。 loglog-plot的作用是將對數取為a和b的10的基數。 你也可以這樣做
logA = numpy.log10(a)
logB = numpy.log10(b)
這是loglog圖可視化的內容。 通過將logA和logB繪制為常規圖來檢查這一點。 在日志數據上重復線性擬合,並在與logA,logB數據相同的圖中繪制線。
coefficients = numpy.polyfit(logB, logA, 1)
polynomial = numpy.poly1d(coefficients)
ys = polynomial(b)
plt.plot(logB, logA)
plt.plot(b, ys)
其他答案提供了很好的解釋和解決方案。 不過,我想提出一個幫助自己的解決方案,也許會幫助你。
編寫適合對數對數刻度的線的另一種簡單方法是下面的代碼中的函數powerfit
。 它接收原始的x
和y
數據,並且通過使用許多新的x點,您可以在對數對數刻度上獲得直線。 在當前情況下,值xnew
與x
相同(均為b
)。
定義新的x坐標的優點是,無論出於何種目的,您都可以獲得功能強大的線路中的少量或多個點。
import numpy as np
from matplotlib import pyplot as plt
import math
def powerfit(x, y, xnew):
"""line fitting on log-log scale"""
k, m = np.polyfit(np.log(x), np.log(y), 1)
return np.exp(m) * xnew**(k)
fp=open("word-rank.txt","r")
a=[]
b=[]
for line in fp:
string=line.strip().split()
a.append(float(string[0]))
b.append(float(string[1]))
ys = powerfit(b, a, b)
plt.loglog(b,a,'ro')
plt.plot(b,ys)
plt.xlabel("Log (Rank of frequency)")
plt.ylabel("Log (Frequency)")
plt.title("Frequency vs frequency rank for words")
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.