よちよちpython

独習 python/Qpython/Pydroid3/termux

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()

f:id:chayarokurokuro:20200122185911p:plain



この点を結ぶ線に近似する、近からず遠からずな良い感じの線を探す。

上の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]

20200122185947

前回やった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型で指定
  • 以下オプション
    • rcond=None : 近似の相対的番号。なんのこっちゃわからん。float型で指定
    • full=False : 戻り値は係数を返すがTrueにすると特異値分解の診断情報も返す。なんのこっちゃ。
    • w=None : y座標に対する重みを変える。配列で指定
    • cov=False : 共分散行列を返すbool型指定

おまけ


多項式とセットで説明されてたりするので

微分する


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