簡體   English   中英

用 Python Sympy 求解方程組

[英]Solve System of Equations with Python Sympy

我正在嘗試使用 Sympy 求解 Python 中的兩個方程組。 這比標准問題有點棘手,因為它在兩個方程中都包含求和,其中兩個方程都是通過對對數正態 pdf 的負對數似然度求導得到的。 這是我的代碼:

import numpy as np
from pprint import pprint
import sympy as sym
from sympy.solvers import solve
from sympy import Product, Function, oo, IndexedBase, diff, Eq, symbols, log, exp, pi, S, expand_log
from scipy.stats import lognorm
import scipy

np.random.seed(seed=111)
test = pd.DataFrame(data=lognorm.rvs(s=1,loc=2,scale=1,size=1000),columns=['y'])

x = IndexedBase('x')
i = symbols('i', positive=True)
n = symbols('n', positive=True)
mu = symbols('mu', positive=True)
sigma = symbols('sigma', positive=True)

pdf2 = 1 / (x[i] * sigma * sqrt(2 * pi)) * exp(-S.Half * ((log(x[i])-mu)/(sigma))**2)
Log_LL2 = -log(Product(pdf2, (i, 0, n-1)))
Log_LL22 = expand_log(Log_LL2, force=True)
pprint(Log_LL22)

回報:

-Sum(-log(sigma) - log(x[i]) - log(pi)/2 - log(2)/2 - (-mu + log(x[i]))**2/(2*sigma**2), (i, 0, n - 1))
df_dmu = diff(Log_LL22, mu)
df_dsigma = diff(Log_LL22, sigma)
pprint(df_dmu )
pprint(df_dsigma )

回報:

-Sum(-(2*mu - 2*log(x[i]))/(2*sigma**2), (i, 0, n - 1))
-Sum(-1/sigma + (-mu + log(x[i]))**2/sigma**3, (i, 0, n - 1))
solve([df_dmu.subs([(n,len(test['y'])),(x,test['y'])]),df_dsigma.subs([(n,len(test['y'])),(x,test['y'])])],mu,sigma,set=True)

這個最終命令返回“([], set())”。 我不確定如何在告訴求解器替換 x_i 和 n 以求解 mu 和 sigma 的同時實現這個方程組。 如果可能的話,我也很樂意不插入 x_i 和 n 並收到關於 x_i 和 n 的答案。 I understand these parameters can be solved for with scipy's fit function, however, when I compute the Hessian of the negative loglikelihood and plug in the scipy fitted parameters, the result is orders of magnitude difference between the scipy fitted parameters and the manually computed parameters.

我正在運行 sympy 1.7.1、numpy 1.19.2 和 scipy 1.5.2

謝謝!

基本上你想找到musigma使這些表達式為零:

In [47]: df_dmu
Out[47]: 
 n - 1                      
  ____                      
  ╲                         
   ╲   -(2⋅μ - 2⋅log(x[i])) 
    ╲  ─────────────────────
-   ╱              2        
   ╱            2⋅σ         
  ╱                         
  ‾‾‾‾                      
 i = 0                      

In [48]: df_dsigma
Out[48]: 
 n - 1                          
 _____                          
 ╲                              
  ╲                             
   ╲   ⎛                      2⎞
    ╲  ⎜  1   (-μ + log(x[i])) ⎟
-   ╱  ⎜- ─ + ─────────────────⎟
   ╱   ⎜  σ            3       ⎟
  ╱    ⎝              σ        ⎠
 ╱                              
 ‾‾‾‾‾                          
 i = 0    

您正在嘗試將數據替換為x[i]然后求解,但這並不是 sympy 的真正用途。 如果您只是在尋找數值解決方案,最好使用 numpy 中的fsolve等。

sympy 的目的是找到解決方案的一般公式。 所以我們只想為musigma解決上述問題。 不幸的是, solve不明白如何處理這樣的求和,所以它放棄了:

In [36]: solve([df_dmu, df_dsigma], [mu, sigma])
Out[36]: []

我們可以通過操縱方程從求和中提取感興趣的符號來幫助解決問題:

In [49]: eq_mu = factor_terms(expand(df_dmu))

In [50]: eq_sigma = factor_terms(expand(df_dsigma))

In [51]: eq_mu
Out[51]: 
  n - 1     n - 1          
   ___       ___           
   ╲         ╲             
    ╲         ╲            
μ⋅  ╱   1 -   ╱   log(x[i])
   ╱         ╱             
   ‾‾‾       ‾‾‾           
  i = 0     i = 0          
───────────────────────────
              2            
             σ             

In [52]: eq_sigma
Out[52]: 
     n - 1         n - 1                       n - 1           
      ___           ___                         ___            
      ╲             ╲                           ╲              
   2   ╲             ╲                           ╲      2      
  μ ⋅  ╱   1   2⋅μ⋅  ╱   log(x[i])   n - 1       ╱   log (x[i])
      ╱             ╱                 ___       ╱              
      ‾‾‾           ‾‾‾               ╲         ‾‾‾            
     i = 0         i = 0               ╲       i = 0           
- ────────── + ─────────────────── +   ╱   1 - ────────────────
       2                 2            ╱                2       
      σ                 σ             ‾‾‾             σ        
                                     i = 0                     
───────────────────────────────────────────────────────────────
                               σ   

現在solve給出了一般的解決方案:

In [54]: s1, s2 = solve([eq_mu, eq_sigma], [mu, sigma])

In [55]: s2
Out[55]: 
⎛                           _________________________________________⎞
⎜                          ╱                                       2 ⎟
⎜n - 1                    ╱    n - 1              ⎛n - 1          ⎞  ⎟
⎜ ___                    ╱      ___               ⎜ ___           ⎟  ⎟
⎜ ╲                     ╱       ╲                 ⎜ ╲             ⎟  ⎟
⎜  ╲                   ╱         ╲      2         ⎜  ╲            ⎟  ⎟
⎜  ╱   log(x[i])      ╱      n⋅  ╱   log (x[i]) - ⎜  ╱   log(x[i])⎟  ⎟
⎜ ╱                  ╱          ╱                 ⎜ ╱             ⎟  ⎟
⎜ ‾‾‾               ╱           ‾‾‾               ⎜ ‾‾‾           ⎟  ⎟
⎜i = 0            ╲╱           i = 0              ⎝i = 0          ⎠  ⎟
⎜───────────────, ───────────────────────────────────────────────────⎟
⎝       n                                  n                         ⎠

另一個解決方案s1用於負sigma ,所以我猜這不是你想要的。

現在您可以將您的值替換為x[i]或將上面的公式轉換為代碼或使用lambdify或您想做的任何事情,例如:

In [57]: lambdify((n, x), s2)(3, [5, 6, 7])
Out[57]: (1.7823691769058227, 0.1375246031240532)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM