Вам необходимо использовать Sympy: sympy.org/en/index.html Numpy - это библиотека числовых вычислений для Python
prrao
Или вам нужен метод оценки числового значения производной? Для этого вы можете использовать метод конечных разностей, но имейте в виду, что он очень шумный.
Конечные различия не требуют внешних инструментов, но подвержены числовым ошибкам и, если вы находитесь в многомерной ситуации, могут занять некоторое время.
Символическая дифференциация идеальна, если ваша проблема достаточно проста. В наши дни символические методы становятся все более надежными. SymPy - отличный проект для этого, который хорошо интегрируется с NumPy. Посмотрите на функции autowrap или lambdify или почитайте блог Дженсена по аналогичному вопросу .
Автоматические производные очень хороши, не подвержены числовым ошибкам, но требуют дополнительных библиотек (для этого есть несколько хороших вариантов в 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. символической дифференциацией и 4. ручной дифференциацией ??
DrStrangeLove
11
Когда я сказал «символическое различие», я имел в виду, что этим процессом управляет компьютер. Принципиально 3 и 4 различаются только тем, кто выполняет эту работу: компьютер или программист. 3 предпочтительнее 4 из-за согласованности, масштабируемости и лени. 4 необходимо, если 3 не может найти решение.
MRocklin
4
В строке 7 мы создали функцию f, которая вычисляет производную y по x. В 8 мы применяем эту производную функцию к вектору всех единиц и получаем вектор всех двоек. Это потому, что, как указано в строке 6, yprime = 2 * x.
MRocklin
Просто для полноты вы также можете выполнить дифференцирование путем интегрирования (см. Интегральную формулу Коши), это реализовано, например, в mpmath(не уверен, однако, что именно они делают).
DerWeh
Есть ли простой способ сделать конечные различия в numpy, не реализуя его самостоятельно? например, я хочу найти градиент функции в заранее определенных точках.
Алекс
44
Самый простой способ, который я могу придумать, - это использовать функцию градиента 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).
@ weberc2, в этом случае вы должны разделить один вектор на другой, но обрабатывать края отдельно с помощью прямых и обратных производных вручную.
Sparkler 02
2
Или вы можете интерполировать y с постоянным dx, а затем вычислить градиент.
IceArdor
@Sparkler Спасибо за ваше предложение. Если я могу задать 2 небольших вопроса: (i) почему мы переходим dxк numpy.gradientвместо x? (ii) Можем ли мы сделать последнюю вашу строчку следующим образом dydx = numpy.gradient(y, numpy.gradient(x)):?
user929304
2
Начиная с версии 1.13, неравномерный интервал можно указать с помощью массива в качестве второго аргумента. См. Раздел Примеры на этой странице .
Натаниэль Джонс
28
NumPy не предоставляет общих функций для вычисления производных. Однако он может обрабатывать простой частный случай многочленов:
>>> p = numpy.poly1d([1, 0, 1])
>>> print p
21 x + 1>>> q = p.deriv()
>>> print q
2 x
>>> q(5)
10
Если вы хотите вычислить производную численно, вы можете обойтись без использования центральных разностных коэффициентов для подавляющего большинства приложений. Для производной в одной точке формула будет выглядеть примерно так:
«Вычислить числовые производные для более общего случая легко» - я позволю себе отличиться, вычисление числовых производных для общих случаев довольно сложно. Вы просто выбрали хорошо управляемые функции.
High Performance Mark
что означает 2 после >>> print p ?? (на 2-й строке)
DrStrangeLove
@DrStrangeLove: Это показатель степени. Он предназначен для моделирования математической записи.
Sven Marnach
@SvenMarnach это максимальный показатель ?? или что?? Почему он думает, что показатель степени равен 2 ?? Мы ввели только коэффициенты ...
DrStrangeLove
2
@DrStrangeLove: вывод должен читаться как 1 * x**2 + 1. Они поместили 2в строку выше, потому что это показатель степени. Посмотрите на это издалека.
Sven Marnach
15
Предполагая, что вы хотите использовать numpy, вы можете численно вычислить производную функции в любой точке, используя строгое определение :
defd_fun(x):
h = 1e-5#in theory h is an infinitesimalreturn (fun(x+h)-fun(x))/h
scipy.interpolateМногие интерполирующие сплайны могут предоставлять производные. Таким образом, при использовании линейного сплайна ( k=1) производная сплайна (с использованием derivative()метода) должна быть эквивалентна прямой разнице. Я не совсем уверен, но я считаю, что использование производной кубического сплайна было бы похоже на производную с центрированной разностью, поскольку для построения кубического сплайна используются значения до и после.
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, и я тоже не вижу ответов на это в сообществе, какая-либо помощь?
Аян Митра
Опубликуйте свою проблему как новый вопрос и дайте ссылку на нее здесь. Вероятно, потребуется предоставить пример, который вызывает вашу ошибку. Ошибки, которые у меня возникают с интерполяционными функциями, обычно возникают из-за того, что входящие данные неправильно сформированы - например, повторяющиеся значения, неправильное количество измерений, один из массивов случайно пуст, данные не сортируются по x или когда сортировка не является допустимая функция и т.д. Возможно, scipy неправильно вызывает numpy, но это очень маловероятно. Отметьте x.shape и y.shape. Посмотрите, работает ли np.interp () - в противном случае он может предоставить более полезную ошибку.
flutefreak7
6
Для расчета градиентов сообщество машинного обучения использует Autograd:
Ответы:
У вас есть четыре варианта
Конечные различия не требуют внешних инструментов, но подвержены числовым ошибкам и, если вы находитесь в многомерной ситуации, могут занять некоторое время.
Символическая дифференциация идеальна, если ваша проблема достаточно проста. В наши дни символические методы становятся все более надежными. SymPy - отличный проект для этого, который хорошо интегрируется с NumPy. Посмотрите на функции autowrap или lambdify или почитайте блог Дженсена по аналогичному вопросу .
Автоматические производные очень хороши, не подвержены числовым ошибкам, но требуют дополнительных библиотек (для этого есть несколько хороших вариантов в 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.]
источник
mpmath
(не уверен, однако, что именно они делают).Самый простой способ, который я могу придумать, - это использовать функцию градиента 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).
источник
dx
кnumpy.gradient
вместоx
? (ii) Можем ли мы сделать последнюю вашу строчку следующим образомdydx = numpy.gradient(y, numpy.gradient(x))
:?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
значений функций, вы можете вычислить приближения производных систочник
1 * x**2 + 1
. Они поместили2
в строку выше, потому что это показатель степени. Посмотрите на это издалека.Предполагая, что вы хотите использовать
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
источник
Закину на кучу другой метод ...
scipy.interpolate
Многие интерполирующие сплайны могут предоставлять производные. Таким образом, при использовании линейного сплайна (k=1
) производная сплайна (с использованиемderivative()
метода) должна быть эквивалентна прямой разнице. Я не совсем уверен, но я считаю, что использование производной кубического сплайна было бы похоже на производную с центрированной разностью, поскольку для построения кубического сплайна используются значения до и после.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)
источник
Для расчета градиентов сообщество машинного обучения использует 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))
Он также может вычислять градиенты сложных функций, например многомерных функций.
источник
В зависимости от требуемого уровня точности вы можете решить это самостоятельно, используя простое доказательство дифференциации:
>>> (((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
источник
Вы можете использовать
scipy
, что довольно просто:scipy.misc.derivative(func, x0, dx=1.0, n=1, args=(), order=3)
В твоем случае:
from scipy.misc import derivative def f(x): return x**2 + 1 derivative(f, 5, dx=1e-6) # 10.00000000139778
источник