sympy中表达式的智能重写

4
我发现这个解释有点棘手,但我会通过一个例子尽力说明。
考虑下面分配给变量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 :)。
我不确定这是否完全可行,但知道在某种程度上是否可能做到会很有趣。
2个回答

1
你只是在寻找简化吗?
>>> 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是否可以尝试以最佳方式将表达式重写为某些特定用户定义的子表达式?就像谷歌搜索一样,您可以强制要求哪些术语应该出现或不出现在搜索结果中。我可以更新问题,提供一个simplify无法解决的示例。 - IssamLaradji
好的,与其直接使用simplify,你也可以使用你需要的特定简化(powsimpradsimptogetherlogcombinecancel?...)。如果这不是你想要的,那我不知道了,我对Sympy相对较新。 - L3viathan

1

cancel does this

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接