Numpyだけで回帰分析その4。polyfit()について。
Numpyだけを使って回帰分析をする悪あがきシリーズ。
今回はpolyfit()
について。
参考 polyfit
numpy.polyfit — NumPy v1.17 Manual
実行環境
Androidスマホ
termux
Python3.8
JupyterNotebook
polyfit() 多項式係数生成マシーン
各点(x,y)を結ぶ線に近似する次数degまでの多項式の係数を計算し出力する。
簡単な使い方としては、
- 引数 : x, y, deg(次数)
- 戻り値 : 近似多項式の各項の係数
たとえば、次のような点があるとする
import numpy as np # 配列xとyを適当に x = [1,7,24] y = [5,9,16] #グラフに点とる import matplotlib.pyplot as plt plt.scatter(x,y) plt.savefig("polyfit_1.png") plt.show()
この点を結ぶ線に近似する、近からず遠からずな良い感じの線を探す。
上の3つの点の座標をpolyfitに渡します。そして良い感じの直線の係数を出すよう命じます。
# 近似線の係数を算出 k = np.polyfit(x, y, 1) k
array([0.46370023, 5.05386417])
polyfit()の第3引数degに「1」を指定した。1次の近似線の係数が戻り値として返される。
この場合、直線 y=ax+b
の傾きa
と切片b
。
degの値を2,3,4…と変えると、多項式はx2 ,x3,x4…と順に次数の高い項が追加されていき、より複雑な曲線を表すようになっていく。polyfitはそれらの係数を配列で返す。
上のグラフはx軸が0から25までぐらい載っているので、適当に2点とったx=[0, 25]
を回帰直線の式に代入すればyが配列で得られる。それらをplotしてやれば近似直線が引ける筈だ。
いけー!
# 変数に置き換えとこ a, b = k # 適当にx軸の両端の値 x_reg = np.array([0, 25]) # 直線の式を作って配列xを代入 y_reg = a * x_reg + b print(y_reg) # グラフに点とりと保存と表示 # 元の点 plt.scatter(x,y) # 近似直線 plt.plot(x_reg, y_reg, color="red") plt.savefig("polyfit_2.png") plt.show()
[ 5.05386417 16.64637002]
前回やったpoly1dを使えば、この様にわざわざ直線の式を作って代入する手間が省ける。
poly1d使用例
グラフ省略(上と同じものができる)
# 係数を算出 k = np.polyfit(x,y,1) x_reg = [0,25] #多項式回帰線を生成し配列x_reg代入 y_reg = np.poly1d(k)(x_reg) plt.scatter(x,y) plt.plot(x_reg, y_reg, color="red") plt.show()
polyfitの引数
- x : 点のx座標を集めた配列
- y : 同じくy座標の配列
- deg : 近似する多項式の次数をint型で指定
- 以下オプション
おまけ
多項式とセットで説明されてたりするので
微分する
numpy.poly1d.deriv — NumPy v1.17 Manual
import numpy as np y = np.poly1d([1,0,0,0]) #y=x**3 print(y) # 微分、xで y1 = y.deriv() print(y1) # 二階微分 y2 = y.deriv(2) print(y2)
3
1 x
2
3 x
6 x
y = np.sin(x) y.deriv()
--------------------------------------------
AttributeErrorTraceback (most recent call last)
<ipython-input-124-4d8f2f0c2bd9> in <module>
1 y = np.sin(x)
----> 2 y.deriv()
AttributeError: 'numpy.ndarray' object has no attribute 'deriv'
# 係数を文字列にすると微分時にエラー #y = np.poly1d(["a",0,0,0]) #y.deriv()
積分する
import numpy as np #関数の生成 y = np.poly1d([1,0,0,0]) print(y) # 関数を1回xで積分 y_i1 = y.integ() print(y_i1) # 2回積分 y_i2 = y.integ(2) print(y_i2)
3
1 x
4
0.25 x
5
0.05 x