Numpy를 사용하여 미분을 어떻게 계산합니까?


95

예를 들어 함수의 미분을 어떻게 계산합니까?

y = x 2 +1

사용 numpy?

x = 5에서 도함수의 값을 원한다고 가정 해 보겠습니다.


5
Sympy를 사용해야합니다. sympy.org/en/index.html Numpy는 Python 용 숫자 계산 라이브러리입니다
prrao

또는 미분의 수치를 추정하는 방법을 원하십니까? 이를 위해 유한 차분 방법을 사용할 수 있지만 매우 시끄러운 경향이 있음을 명심하십시오.
Henry Gomersall 2012 년

답변:


147

네 가지 옵션이 있습니다

  1. 유한 차이
  2. 자동 파생 상품
  3. 상징적 차별화
  4. 손으로 미분을 계산합니다.

유한 차분에는 외부 도구가 필요하지 않지만 수치 오류가 발생하기 쉬우 며 다변량 상황에있는 경우 시간이 걸릴 수 있습니다.

문제가 충분히 단순한 경우 상징적 차별화가 이상적입니다. 상징적 방법은 요즘 상당히 강력 해지고 있습니다. SymPy 는 NumPy와 잘 통합되는 훌륭한 프로젝트입니다. autowrap 또는 lambdify 함수를 보거나 비슷한 질문에 대한 Jensen의 블로그 게시물을 확인하십시오. .

자동 도함수는 매우 멋지고 숫자 오류가 발생하기 쉽지 않지만 몇 가지 추가 라이브러리가 필요합니다 (Google에서는 몇 가지 좋은 옵션이 있습니다). 이것은 가장 견고하지만 가장 정교하고 설정하기 어려운 선택입니다. 자신을 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.]

미안해,이게 어리석은 것 같다면, 3.Symbolic Differentiation과 4.by Hand Differentiation의 차이점은 무엇입니까 ??
DrStrangeLove

11
내가 "기호 적 차별화"라고 말했을 때 나는 그 과정이 컴퓨터에 의해 처리된다는 것을 암시하려고했다. 원칙적으로 3과 4는 작업을하는 사람, 컴퓨터 또는 프로그래머에 따라 다릅니다. 일관성, 확장 성 및 게으름 때문에 3이 4보다 선호됩니다. 3이 해결책을 찾지 못하면 4가 필요합니다.
MRocklin 2012

4
7 행에서 우리는 y wrt x의 미분을 계산하는 함수 인 f를 만들었습니다. 8에서는이 미분 함수를 모든 1의 벡터에 적용하고 모든 2의 벡터를 얻습니다. 이는 6 행에서 언급했듯이 yprime = 2 * x이기 때문입니다.
MRocklin 2012

완전성을 위해 통합을 통해 미분을 수행 할 수도 있습니다 (Cauchy의 적분 공식 참조). 예를 들어 구현됩니다 mpmath(하지만 정확히 무엇을하는지 확실하지 않음).
DerWeh

직접 구현하지 않고 numpy에서 유한 한 차이를 수행하는 쉬운 방법이 있습니까? 예를 들어 미리 정의 된 지점에서 함수의 기울기를 찾고 싶습니다.
Alex

42

내가 생각할 수있는 가장 간단한 방법은 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와 길이가 같습니다.


2
dx가 일정하지 않으면 어떨까요?
weberc2

3
@ weberc2,이 경우 한 벡터를 다른 벡터로 나눠야하지만 수동으로 순방향 및 역방향 도함수를 사용하여 가장자리를 별도로 처리해야합니다.
Sparkler

2
또는 상수 dx로 y를 보간 한 다음 기울기를 계산할 수 있습니다.
IceArdor 2011

@Sparkler 제안 해 주셔서 감사합니다. 2 개의 작은 질문을 할 수 있다면, (i) 왜 우리 dxnumpy.gradient대신 통과 x합니까? 다음과 같이 (II) 우리는 또한 당신의 마지막 줄을 수행 할 수 있습니다 dydx = numpy.gradient(y, numpy.gradient(x))?
user929304

2
v1.13부터는 배열을 두 번째 인수로 사용하여 균일하지 않은 간격을 지정할 수 있습니다. 이 페이지 의 예제 섹션을 참조하십시오 .
Nathaniel Jones

28

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)

2
'더 일반적인 경우에 대한 수치 도함수를 계산하는 것은 쉽습니다.'-저는 다른 점을 간청합니다. 일반적인 경우의 수치 도함수를 계산하는 것은 매우 어렵습니다. 멋지게 작동하는 함수를 선택했습니다.
High Performance Mark

>>> print p 뒤에 2는 무엇을 의미합니까 ?? (2 번째 줄)
DrStrangeLove 2012 년

@DrStrangeLove : 지수입니다. 수학적 표기법을 시뮬레이션하기위한 것입니다.
Sven Marnach

@ SvenMarnach는 최대 지수입니까 ?? 또는 무엇을?? 지수가 2라고 생각하는 이유는 무엇입니까 ?? 우리는 ... 단지 계수를 입력
닥터 스트레인지 러브

2
@DrStrangeLove : 출력은 1 * x**2 + 1. 2지수이기 때문에 위의 줄에 넣습니다 . 멀리서보세요.
Sven Marnach 2012 년

15

을 사용하고 싶다고 가정하면 Rigorous 정의를numpy 사용하여 언제든지 함수의 미분을 수치 적으로 계산할 수 있습니다 .

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

8

나는 더미에 다른 방법을 던질 것이다 ...

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)

그냥 이것을 시도, 나는이 함수에서 오류가 계속 발생합니다.
Ayan Mitra

문제를 새 질문으로 게시하고 여기에 링크하십시오. 오류를 발생시키는 예를 제공해야 할 것입니다. interp 함수에서 발생하는 오류는 일반적으로 반복되는 값, 잘못된 차원 수, 배열 중 하나가 실수로 비어 있거나 x에 대해 데이터가 정렬되지 않거나 정렬되지 않은 경우 데이터가 제대로 입력되지 않았기 때문입니다. 유효한 함수 등. scipy가 numpy를 잘못 호출했을 가능성이 있지만 가능성은 거의 없습니다. x.shape 및 y.shape를 확인하십시오. np.interp ()가 작동하는지 확인하십시오. 그렇지 않으면 더 유용한 오류를 제공 할 수 있습니다.
flutefreak7

6

기울기를 계산하기 위해 기계 학습 커뮤니티는 Autograd를 사용합니다.

" numpy 코드의 파생물을 효율적으로 계산합니다. "

설치하기 위해서:

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

또한 다변량 함수와 같은 복잡한 함수의 기울기를 계산할 수도 있습니다.


안녕하세요이 함수를 사용하여 스텝 길이를 제공하여 두 데이터 열을 수치 적으로 구분할 수 있습니까? 감사합니다
Ayan Mitra

3

필요한 정밀도 수준에 따라 간단한 차별화 증명을 사용하여 직접 해결할 수 있습니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.