ฉันจะคำนวณอนุพันธ์โดยใช้ Numpy ได้อย่างไร


96

ฉันจะคำนวณอนุพันธ์ของฟังก์ชันได้อย่างไร

y = x 2 +1

ใช้numpy?

สมมติว่าฉันต้องการค่าอนุพันธ์ที่ x = 5 ...


5
คุณต้องใช้ Sympy: sympy.org/en/index.html Numpy เป็นไลบรารีการคำนวณตัวเลขสำหรับ Python
prrao

หรือคุณต้องการวิธีการประมาณค่าตัวเลขของอนุพันธ์หรือไม่? สำหรับวิธีนี้คุณสามารถใช้วิธีที่แตกต่างอย่างแน่นอน แต่โปรดจำไว้ว่าพวกเขามักจะมีเสียงดังอย่างน่ากลัว
Henry Gomersall

คำตอบ:


148

คุณมีสี่ตัวเลือก

  1. ความแตกต่าง จำกัด
  2. ตราสารอนุพันธ์อัตโนมัติ
  3. ความแตกต่างเชิงสัญลักษณ์
  4. คำนวณอนุพันธ์ด้วยมือ

ความแตกต่าง จำกัด ไม่จำเป็นต้องใช้เครื่องมือภายนอก แต่มีแนวโน้มที่จะเกิดข้อผิดพลาดทางตัวเลขและหากคุณอยู่ในสถานการณ์หลายตัวแปรอาจใช้เวลาสักครู่

การแยกแยะสัญลักษณ์เหมาะอย่างยิ่งหากปัญหาของคุณง่ายพอ วิธีการเชิงสัญลักษณ์เริ่มมีประสิทธิภาพมากในทุกวันนี้ SymPyเป็นโครงการที่ยอดเยี่ยมสำหรับสิ่งนี้ซึ่งทำงานร่วมกับ NumPy ได้เป็นอย่างดี ดู autowrap หรือ lambdify ฟังก์ชั่นหรือเช็คเอาblogpost เซ่นเกี่ยวกับคำถามที่คล้ายกัน

อนุพันธ์อัตโนมัตินั้นยอดเยี่ยมมากไม่มีแนวโน้มที่จะเกิดข้อผิดพลาดเกี่ยวกับตัวเลข แต่ต้องการไลบรารีเพิ่มเติม (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 เนื่องจากความสม่ำเสมอความสามารถในการปรับขนาดและความเกียจคร้าน 4 เป็นสิ่งที่จำเป็นหาก 3 ไม่สามารถหาทางออกได้
MRocklin

4
ในบรรทัดที่ 7 เราสร้าง f ฟังก์ชันที่คำนวณอนุพันธ์ของ y wrt x ใน 8 เราใช้ฟังก์ชันอนุพันธ์นี้กับเวกเตอร์ของทุกตัวและรับเวกเตอร์ของสองทั้งหมด เนื่องจากตามที่ระบุไว้ในบรรทัดที่ 6 yprime = 2 * x
MRocklin

เพื่อความสมบูรณ์คุณยังสามารถสร้างความแตกต่างได้โดยการรวม (ดูสูตรอินทิกรัลของ Cauchy) มันถูกนำไปใช้เช่นในmpmath(ไม่แน่ใจว่ามันทำอะไรกันแน่)
DerWeh

มีวิธีง่ายๆในการสร้างความแตกต่างแบบ จำกัด ในตัวเลขโดยไม่ต้องดำเนินการด้วยตัวเองหรือไม่? เช่นฉันต้องการค้นหาการไล่ระดับสีของฟังก์ชันที่จุดที่กำหนดไว้ล่วงหน้า
Alex

43

วิธีที่ตรงไปตรงมาที่สุดที่ฉันคิดได้คือการใช้ฟังก์ชันการไล่ระดับสีของ numpy :

x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)

วิธีนี้จะคำนวณ dydx โดยใช้ความแตกต่างส่วนกลางและจะมีความยาวเท่ากับ y ซึ่งแตกต่างจาก numpy.diff ซึ่งใช้ความแตกต่างข้างหน้าและจะส่งกลับเวกเตอร์ขนาด (n-1)


2
จะเกิดอะไรขึ้นถ้า dx ไม่คงที่?
weberc2

3
@ weberc2 ในกรณีนี้คุณควรหารเวกเตอร์หนึ่งโดยอีกตัวหนึ่ง แต่ให้แยกขอบแยกกันด้วยอนุพันธ์ไปข้างหน้าและข้างหลังด้วยตนเอง
Sparkler

2
หรือคุณสามารถสอดแทรก y ด้วยค่าคงที่ dx จากนั้นคำนวณการไล่ระดับสี
IceArdor

@Sparkler ขอบคุณสำหรับคำแนะนำของคุณ ถ้าฉันอาจถามคำถามเล็ก ๆ 2 ข้อ (i) ทำไมเราdxถึงส่งไปnumpy.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ของ abscissae ที่มีอาร์เรย์yของค่าฟังก์ชันที่สอดคล้องกันคุณสามารถคำนวณค่าประมาณของอนุพันธ์ด้วย

numpy.diff(y) / numpy.diff(x)

2
'การคำนวณอนุพันธ์เชิงตัวเลขสำหรับกรณีทั่วไปนั้นง่ายกว่า' - ฉันขอแตกต่างกันการคำนวณอนุพันธ์เชิงตัวเลขสำหรับกรณีทั่วไปค่อนข้างยาก คุณเพิ่งเลือกฟังก์ชั่นที่มีพฤติกรรมดี
High Performance Mark

2 หมายถึงอะไรหลังจาก >>> พิมพ์ p ?? (ในบรรทัดที่ 2)
DrStrangeLove

@DrStrangeLove: นั่นคือเลขชี้กำลัง หมายถึงการจำลองสัญกรณ์ทางคณิตศาสตร์
Sven Marnach

@SvenMarnach เป็นเลขชี้กำลังสูงสุด ?? หรืออะไร?? ทำไมถึงคิดว่าเลขชี้กำลังเป็น 2 ?? เราป้อนค่าสัมประสิทธิ์เท่านั้น ...
DrStrangeLove

2
@DrStrangeLove: ผลลัพธ์ควรจะอ่านเป็น1 * x**2 + 1. พวกเขาวางไว้2ในบรรทัดด้านบนเพราะเป็นเลขชี้กำลัง มองจากระยะไกล
Sven Marnach

15

สมมติว่าคุณต้องการใช้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.interpolateSpline interpolating จำนวนมากสามารถให้อนุพันธ์ได้ ดังนั้นการใช้เส้นโค้งเชิงเส้น ( k=1) อนุพันธ์ของเส้นโค้ง (โดยใช้derivative()วิธีนี้) ควรเทียบเท่ากับผลต่างไปข้างหน้า ฉันไม่แน่ใจทั้งหมด แต่ฉันเชื่อว่าการใช้อนุพันธ์ลูกบาศก์ spline จะคล้ายกับอนุพันธ์ผลต่างกึ่งกลางเนื่องจากใช้ค่าจากก่อนและหลังในการสร้างเส้นโค้งของลูกบาศก์

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)

เพียงแค่ลองสิ่งนี้ฉันได้รับข้อผิดพลาดจากฟังก์ชัน AxisError นี้อยู่เรื่อย ๆ : แกน -1 อยู่นอกขอบเขตสำหรับอาร์เรย์ของมิติ 0 และฉันไม่เห็นคำตอบใด ๆ สำหรับสิ่งนี้ในชุมชนเช่นกันความช่วยเหลือใด ๆ ?
Ayan Mitra

โพสต์ปัญหาของคุณเป็นคำถามใหม่และลิงก์ไปที่นี่ การให้ตัวอย่างที่ทำให้เกิดข้อผิดพลาดอาจจำเป็น ข้อผิดพลาดที่ฉันมีกับฟังก์ชัน interp มักเป็นเพราะข้อมูลไม่ได้ถูกสร้างขึ้นอย่างดีเช่นค่าที่ซ้ำกันจำนวนมิติที่ไม่ถูกต้องอาร์เรย์หนึ่งในนั้นว่างเปล่าโดยไม่ได้ตั้งใจข้อมูลจะไม่เรียงลำดับเทียบกับ x หรือเมื่อจัดเรียงไม่ใช่ a ฟังก์ชันที่ถูกต้อง ฯลฯ เป็นไปได้ว่า scipy เรียก numpy ไม่ถูกต้อง แต่ไม่น่าเป็นไปได้มาก ตรวจสอบ x.shape และ y.shape ดูว่า np.interp () ใช้งานได้หรือไม่ซึ่งอาจให้ข้อผิดพลาดที่เป็นประโยชน์มากขึ้นหากไม่
flutefreak7

6

ในการคำนวณการไล่ระดับสีชุมชนแมชชีนเลิร์นนิงใช้ 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))

นอกจากนี้ยังสามารถคำนวณการไล่ระดับสีของฟังก์ชันที่ซับซ้อนเช่นฟังก์ชันหลายตัวแปร


สวัสดีสามารถใช้ฟังก์ชันนี้เพื่อแยกความแตกต่างระหว่างคอลัมน์ข้อมูลสองคอลัมน์โดยระบุความยาวขั้นตอนได้หรือไม่? ขอบคุณ
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.