# 散布図を描いてみましょう。
import matplotlib.pyplot as plt
%matplotlib inline
X = [3,10,11,15,22,28,25,17,13,20]
Y = [5,9,15,16,29,29,20,22,20,15]
plt.xlim([0,30])
plt.ylim([0,30])
plt.scatter(X,Y)
<matplotlib.collections.PathCollection at 0x7fc0e0e20080>
# 散布図に直線を加えてみましょう。
import numpy as np
x = np.arange(0,30,0.1) # np.arangeで0から30までの間の値を0.1刻みで生成する
# 生成したxにaをかけてbを足した値をyとする
a = 1
b = 2.5
y = a*x + b
plt.xlim([0,30])
plt.ylim([0,30])
plt.scatter(X,Y)
# 生成したxとyの線グラフの描画
plt.plot(x,y,color="red")
[<matplotlib.lines.Line2D at 0x7fc0e1006470>]
# 以下は描画のためのコード
x = np.arange(0,30,0.1)
y = x + 2.5
plt.scatter(X,Y)
plt.plot(x,y,color="r")
for x,y in zip(X,Y):
plt.plot([x,x],[y,x+2.5],"grey")
# a(傾き)の候補のリストを作成
A = np.arange(0,2,0.1)
#b(切片)候補のリストを作成
B = np.arange(1,5,0.1)
# aを固定してbの値を変化させたリストを作成
D = []
for a in A:
for b in B:
D.append([a,b])
# すべての組み合わせの誤差の総和を算出
E = []
for a,b in D:
diff = 0
for x,y in zip(X,Y):
d = (y - (a*x+b))**2
diff += d
E.append(diff)
# 誤差がどのように変化するか視覚的に確認してみましょう。
A_c = []
B_c = []
for a,b in D:
A_c.append(a)
B_c.append(b)
import pandas as pd
data = pd.DataFrame({"A":A_c,"B":B_c,"E":E})
data.plot(x="A",y="B",c="E",kind="scatter")
<matplotlib.axes._subplots.AxesSubplot at 0x7fc0e1fba278>
# Eの最小値
np.min(E)
160.7
# Eの最小値のインデクス
E.index(np.min(E))
382
# 最小値を算出したaとbの値
D[E.index(np.min(E))]
[0.9, 3.200000000000002]
描画してみましょう。
a, b = D[E.index(np.min(E))]
x = np.arange(0,30,0.1)
y = a*x + b
plt.xlim([0,30])
plt.ylim([0,30])
plt.plot(x,y,color="red")
plt.scatter(X,Y)
<matplotlib.collections.PathCollection at 0x7fc0e21393c8>
mu_x = np.average(X)
s2_x = np.var(X,ddof=1)
mu_y = np.average(Y)
cov_xy = np.cov(X,Y)[0][1]
a = cov_xy / s2_x
b = mu_y - a * mu_x
print(a,b)
0.8559256390395042 3.9628195197521308
描画してみましょう。
x = np.arange(0,30,0.1)
y = a*x + b
plt.xlim([0,30])
plt.ylim([0,30])
plt.plot(x,y,color="red")
plt.scatter(X,Y)
<matplotlib.collections.PathCollection at 0x7fc0e21b72b0>
もちろん、パッケージもあります。
# パッケージのimport
from scipy import polyfit
a,b = polyfit(X,Y,1)
print(a,b)
0.8559256390395048 3.9628195197521143
x = np.arange(0,30,0.1)
y = a*x + b
plt.xlim([0,30])
plt.ylim([0,30])
plt.plot(x,y,color="red")
plt.scatter(X,Y)
<matplotlib.collections.PathCollection at 0x7fc0e266acf8>
# 物理のテストで20点とった人の数学のテストの予測得点
a * 20 + b
21.081332300542208