Для проекта я хочу использовать sympy
для построения и вычисления максимальной вероятности гауссовского распределения для дискретного числа точек данных. Метод, который я следую, находится по адресу mathworld.Как использовать массив python в символическом выражении?
Но я столкнулся с проблемой, когда попытался использовать массив в символическом выражении с Product
и/или Sum
. Ниже приведен упрощенный вариант моих предыдущих попыток.
В записной книжке в Yupyter Anaconda, я создать массив питона, скажем x
:
N = 10
x = range(N)
И я хочу использовать x
в символическое выражение в sympy
следующим образом:
from sympy import *, Symbol
i = Symbol('i', integer=True)
mu = Symbol('mu')
s = Sum((x[i]-mu)**2, (i, 0, N-1))
Но это не работает, поскольку оценка ячейки приводит к:
TypeError Traceback (most recent call last)
<ipython-input-1-19c174235872> in <module>()
7 mu = Symbol('mu')
8
----> 9 s = Sum((x[i]-mu)**2, (i,0,N-1))
TypeError: list indices must be integers, not Symbol
Еще одна попытка:
X = MatrixSymbol(X, 1, N) # No clue how to convince `sympy` to use 1-dimensional arrays using only one index.
s = Sum((X[0,i]-mu)**2, (i,0,N-1))
s.doit()
Дает:
(-mu + X[0, 0])**2 + (-mu + X[0, 1])**2 + (-mu + X[0, 2])**2 + (-mu + X[0, 3])**2 + (-mu + X[0, 4])**2 + (-mu + X[0, 5])**2 + (-mu + X[0, 6])**2 + (-mu + X[0, 7])**2 + (-mu + X[0, 8])**2 + (-mu + X[0, 9])**2
вид работ, но как получить реальные значения x
в этом символическое выражение, т.е. заменяя каждый из этих X[0,i]
для значения от x[i]
?
Еще одна попытка:
X = Matrix(1,N, range(N))
s = Sum((X[i]-mu)**2, (i, 0, N-1))
s.doit()
Сейчас питон/SymPy очень несчастна:
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-7-6d106fb975e1> in <module>()
1 X = Matrix(1,N, range(N))
2
----> 3 s = Sum((X[i]-mu)**2, (i, 0, N-1))
4 s.doit()
/Users/twan/anaconda/lib/python2.7/site-packages/sympy/matrices/dense.pyc in __getitem__(self, key)
94 if isinstance(key, slice):
95 return self._mat[key]
---> 96 return self._mat[a2idx(key)]
97
98 def __setitem__(self, key, value):
/Users/twan/anaconda/lib/python2.7/site-packages/sympy/matrices/matrices.pyc in a2idx(j, n)
4412 j = j.__index__()
4413 except AttributeError:
-> 4414 raise IndexError("Invalid index a[%r]" % (j,))
4415 if n is not None:
4416 if j < 0:
IndexError: Invalid index a[i]
Я не имею ни малейшего понятия, что попробовать еще и я застрял с sympy
здесь. Мне интересно, столкнулся ли я с ограничением sympy
для очень важного вычисления в статистике.
EDIT:
Я должен отметить, что слагаемым должен был быть разработан в (E**(-((x-mu)**2)/(2 * s**2)))/(s * sqrt(2 * pi))
. Возрождение делает его несколько иной проблемой.
Хотя решение @ unutbu не сработало для меня, пытаясь использовать это предложение, указал мне, что я должен сдерживать домены до действительных чисел.
@ предложение Зефир в сделал работу, полное решение теперь:
from sympy import symbols, E, pi, sqrt, init_printing
from sympy import diff, IndexedBase
from sympy.solvers import solve
x, mu = symbols('x mu', real=True)
sigma = symbols('sigma', real=True, positive=True)
bell = (E**(-((x-mu)**2)/(2 * sigma**2)))/(sigma * sqrt(2 * pi))
def likelihood(factor, xs):
return np.prod([factor.subs(x,i) for i in xs])
def loglikelihood(factor, xs):
return expand_log(log(likelihood(factor, xs)))
N = 3
X = IndexedBase('X')
Xs = [X[i] for i in range(N)]
solve(diff(loglikelihood(gauss,Xs), mu).subs(sigma, 1), mu)
Большое спасибо @Marshmellow и @unutbu.
Спасибо @Marshmallow, ваше предложение использовать сумму или продукт над пониманием списка поставил меня на правильный путь. См. Мое редактирование. – nanitous