【问题标题】:Smart rewriting of expressions in sympysympy 中表达式的智能重写
【发布时间】:2016-02-11 00:54:07
【问题描述】:

我发现这很难解释,但我会尽力通过一个例子。

考虑下面分配给变量grad的表达式

 from sympy import *

 a, x, b = symbols("a x b")    
 y_pred = a * x    
 loss = log(1 + exp(- b * y_pred))
 grad = diff(loss, x, 1)

grad 有如下表达式:

-a*b*exp(-a*b*x)/(1 + exp(-a*b*x))

现在我想通过两种方式操作grad

1) 我希望sympy 尝试重写表达式grad,使其中的所有术语都不像

exp(-a*b*x)/(1 + exp(-a*b*x))

2) 我还希望它尝试重写表达式,使其至少包含一个类似于 1./(1 + exp(a*b*x)) 的术语。

所以最后,grad 变为:

-a*b/(1 + exp(a*b*x)

请注意,1./(1 + exp(a*b*x)) 等同于 exp(-a*b*x)/(1 + exp(-a*b*x)),但我不想明确提及 sympy :)。

我不确定这是否可行,但知道是否可以在某种程度上做到这一点会很有趣。

【问题讨论】:

    标签: python sympy equation


    【解决方案1】:

    cancel 这样做

    In [16]: cancel(grad)
    Out[16]:
      -a⋅b
    ──────────
     a⋅b⋅x
    ℯ      + 1
    

    之所以有效,是因为它将表达式视为-a*b*(1/A)/(1 + 1/A),其中A = exp(a*b*x)cancel 将有理函数重写为取消p/q(有关更多信息,请参阅SymPy 教程中的cancel 部分)。

    请注意,这只有效,因为它使用A = exp(a*b*x) 而不是A = exp(-a*b*x)。例如,cancel 不会在这里做类似的简化

    In [17]: cancel(-a*b*exp(a*b*x)/(1 + exp(a*b*x)))
    Out[17]:
          a⋅b⋅x
    -a⋅b⋅ℯ
    ────────────
      a⋅b⋅x
     ℯ      + 1
    

    【讨论】:

      【解决方案2】:

      您只是在寻找simplify吗?

      >>> grad
      -a*b*exp(-a*b*x)/(1 + exp(-a*b*x))
      >>> simplify(grad)
      -a*b/(exp(a*b*x) + 1)
      

      【讨论】:

      • 对,似乎simplify 在这种情况下有效,因为最简单的形式有1/(1+exp(a*b*x)),但是sympy 是否有可能尝试根据某些特定用户重写表达式-在最好的情况下定义子表达式可以吗?就像 Google 搜索一样,您可以在其中强制执行哪些术语应该出现在搜索结果中或不出现在搜索结果中。我可以更新问题以提供简化不起作用的示例。
      • 好吧,不用直接使用simplify,也可以使用你需要的具体简化(powsimp?radsimp?together?logcombine?cancel?.. .) 如果这不是你的意思,那么我不知道,我对 Sympy 比较陌生
      猜你喜欢
      • 2017-05-31
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      相关资源
      最近更新 更多