たとえば、関数の導関数を計算するにはどうすればよいですか
y = x2+1
numpy
を使用していますか?
たとえば、x = 5での微分値が必要です...
4つのオプションがあります
有限差分には外部ツールは必要ありませんが、数値エラーが発生しやすく、多変量の状況にある場合は時間がかかることがあります。
シンボリック微分は、問題が単純な場合に理想的です。シンボリックメソッドは、最近非常に堅牢になっています。 SymPy は、NumPyとうまく統合できるこのための優れたプロジェクトです。 autowrapまたはlambdify関数を確認するか、 同様の質問に関するJensenのブログ投稿 をチェックしてください。
自動派生物は非常にクールで、数値エラーを起こしにくいですが、追加のライブラリが必要になります(このためのグーグル、いくつかの良いオプションがあります)。これは最も堅牢ですが、設定するのが最も洗練された/難しい選択です。自分をnumpy
構文に制限する場合は、 Theano が適切な選択です。
SymPyを使用した例を次に示します
In [1]: from sympy import *
In [2]: import numpy as np
In [3]: x = Symbol('x')
In [4]: y = x**2 + 1
In [5]: yprime = y.diff(x)
In [6]: yprime
Out[6]: 2⋅x
In [7]: f = lambdify(x, yprime, 'numpy')
In [8]: f(np.ones(5))
Out[8]: [ 2. 2. 2. 2. 2.]
私が考えることができる最も簡単な方法は、 numpyの勾配関数 を使用することです:
x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)
このように、dydxは中心差分を使用して計算され、前方差分を使用して(n-1)サイズのベクトルを返すnumpy.diffとは異なり、yと同じ長さを持ちます。
NumPyは、導関数を計算するための一般的な機能を提供しません。ただし、多項式の単純で特殊なケースを処理できます。
>>> p = numpy.poly1d([1, 0, 1])
>>> print p
2
1 x + 1
>>> q = p.deriv()
>>> print q
2 x
>>> q(5)
10
導関数を数値的に計算したい場合は、大部分のアプリケーションに中心差分商を使用することで回避できます。単一点の導関数の場合、式は次のようになります
x = 5.0
eps = numpy.sqrt(numpy.finfo(float).eps) * (1.0 + x)
print (p(x + eps) - p(x - eps)) / (2.0 * eps * x)
関数値の対応する配列x
を持つ横座標のy
配列がある場合、導関数の近似を計算できます
numpy.diff(y) / numpy.diff(x)
numpy
を使用すると仮定すると、 Rigorous definition を使用して、任意の時点で関数の導関数を数値的に計算できます。
def d_fun(x):
h = 1e-5 #in theory h is an infinitesimal
return (fun(x+h)-fun(x))/h
より良い結果を得るために 対称導関数 を使用することもできます:
def d_fun(x):
h = 1e-5
return (fun(x+h)-fun(x-h))/(2*h)
あなたの例を使用すると、完全なコードは次のようになります。
def fun(x):
return x**2 + 1
def d_fun(x):
h = 1e-5
return (fun(x+h)-fun(x-h))/(2*h)
これで、数値的にx=5
で派生物を見つけることができます:
In [1]: d_fun(5)
Out[1]: 9.999999999621423
パイルに別のメソッドをスローします...
scipy.interpolate
の多くの補間スプラインは、導関数を提供できます。したがって、線形スプライン(k=1
)を使用すると、スプラインの導関数(derivative()
メソッドを使用)は前方差分と同等になります。完全には定かではありませんが、3次スプライン導関数を使用することは、3次スプラインを構成する前と後の値を使用するため、中央差分導関数に似ていると思います。
from scipy.interpolate import InterpolatedUnivariateSpline
# Get a function that evaluates the linear spline at any x
f = InterpolatedUnivariateSpline(x, y, k=1)
# Get a function that evaluates the derivative of the linear spline at any x
dfdx = f.derivative()
# Evaluate the derivative dydx at each x location...
dydx = dfdx(x)
必要な精度のレベルに応じて、差別化の簡単な証明を使用して自分で解決できます。
>>> (((5 + 0.1) ** 2 + 1) - ((5) ** 2 + 1)) / 0.1
10.09999999999998
>>> (((5 + 0.01) ** 2 + 1) - ((5) ** 2 + 1)) / 0.01
10.009999999999764
>>> (((5 + 0.0000000001) ** 2 + 1) - ((5) ** 2 + 1)) / 0.0000000001
10.00000082740371
勾配の限界を実際にとることはできませんが、それはちょっと楽しいです。気をつけなきゃ
>>> (((5+0.0000000000000001)**2+1)-((5)**2+1))/0.0000000000000001
0.0
勾配を計算するために、機械学習コミュニティはAutogradを使用します。
インストールする:
pip install autograd
以下に例を示します。
import autograd.numpy as np
from autograd import grad
def fct(x):
y = x**2+1
return y
grad_fct = grad(fct)
print(grad_fct(1.0))
複雑な関数の勾配も計算できます。多変量関数。