使用 Python Sympy 求解方程组

如何解决使用 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,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),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),n - 1))
-Sum(-1/sigma + (-mu + log(x[i]))**2/sigma**3,n - 1))
solve([df_dmu.subs([(n,len(test['y'])),(x,test['y'])]),df_dsigma.subs([(n,test['y'])])],mu,sigma,set=True)

最后一条命令返回“([],set())”。我不确定如何实现这个方程组,同时告诉求解器替换 x_i 和 n 以求解 mu 和 sigma。如果可能的话,我也很乐意不插入 x_i 和 n 并根据 x_i 和 n 接收答案。我知道这些参数可以用 scipy 的拟合函数解决,但是,当我计算负对数似然的 Hessian 并插入 scipy 拟合参数时,结果是 scipy 拟合参数和手动计算参数之间的数量级差异。

我正在运行 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],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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?