web-dev-qa-db-ja.com

Python / Matplotlib:切片と勾配が与えられたプロットに回帰直線を追加する

次の小さなデータセットを使用します。

bill = [34,108,64,88,99,51]
tip =  [5,17,11,8,14,5]  

最適な回帰直線を(手動で)計算しました。

yi = 0.1462*x - 0.8188 #yi = slope(x) + intercept

私は次のようにMatplotlibを使用して元のデータをプロットしました:

scatter(bill,tip, color="black")
plt.xlim(20,120) #set ranges
plt.ylim(4,18)

#plot centroid point (mean of each variable (74,10))
line1 = plt.plot([74, 74],[0,10], ':', c="red")
line2 = plt.plot([0,74],[10,10],':', c="red")

plt.scatter(74,10, c="red")

#annotate the centroid point
plt.annotate('centroid (74,10)', xy=(74.1,10), xytext=(81,9),
        arrowprops=dict(facecolor="black", shrink=0.01),
        )

#label axes
xlabel("Bill amount ($)")
ylabel("Tip amount ($)")

#display plot
plt.show()

プロット自体に回帰直線を取得する方法がわかりません。ベストフィットラインをすばやくフィットして表示するための組み込み機能がたくさんあることは知っていますが、これは練習として行いました。 '0,0.8188'(切片)で線を開始できることはわかっていますが、勾配値を使用して線を完成する方法(線の終点を設定)がわかりません。

X軸の増加ごとに、勾配は「0.1462」だけ増加するはずです。開始点に(0,0.8188)、終了点に(100,14.62)を試しました。しかし、この線は私の重心点を通過しません。見逃しているだけです。

乾杯、ジョン

6
Jonathan

質問の推論は部分的に正しいです。関数f(x) = a*x +bがあれば、y軸(x = 0)でのインターセプトを(0, b)(この場合は(0,-0.8188))として最初のポイントとして取得できます。
その行の他のポイントは、(x, f(x))、または(x, a*x+b)によって指定されます。したがって、x = 100の点を見ると、(100, f(100))が得られ、次のように接続できます:(100, 0.1462*100-0.8188) = (100,13.8012)。質問であなたが説明した場合、あなたはbを考慮に入れることを忘れました。

以下は、その関数を使用してmatplotlibに線をプロットする方法を示しています。

import matplotlib.pyplot as plt
import numpy as np

bill = [34,108,64,88,99,51]
tip =  [5,17,11,8,14,5]  
plt.scatter(bill, tip)

#fit function
f = lambda x: 0.1462*x - 0.8188
# x values of line to plot
x = np.array([0,100])
# plot fit
plt.plot(x,f(x),lw=2.5, c="k",label="fit line between 0 and 100")

#better take min and max of x values
x = np.array([min(bill),max(bill)])
plt.plot(x,f(x), c="orange", label="fit line between min and max")

plt.legend()
plt.show()

enter image description here

もちろんフィッティングは自動的に行うこともできます。 numpy.polyfitの呼び出しから勾配と切片を取得できます。

#fit function
a, b = np.polyfit(np.array(bill), np.array(tip), deg=1)
f = lambda x: a*x + b

残りのプロットは同じままです。

関数フィットを定義し、データのエンドポイントを取得し、タプルをplot()に入れます

def fit(x):
    return 0.1462*x - 0.8188 #yi = slope(x) - intercept
xfit, yfit = (min(bill), max(bill)), (fit(min(bill)), fit(max(bill)))    
plt.plot(xfit, yfit,'b')
1
f5r5e5d

クイックノート:回帰の式は

return 0.1462*x + 0.8188 #yi = slope(x) + intercept

-ではなく+を意味します。

0
Enzo Calogero