智能重写 sympy 中的表达式
Smart rewriting of expressions in sympy
我发现这很难解释,但我会通过一个例子尽力而为。
考虑下面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
,使其 none 项看起来像
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
提及这一点 :)。
我完全不确定这是否可行,但知道是否可以在某种程度上做到这一点会很有趣。
您只是在寻找 simplify
吗?
>>> grad
-a*b*exp(-a*b*x)/(1 + exp(-a*b*x))
>>> simplify(grad)
-a*b/(exp(a*b*x) + 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
(请参阅 cancel 在 SymPy 教程中获取更多信息)。
请注意,这只有效,因为它使用 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
我发现这很难解释,但我会通过一个例子尽力而为。
考虑下面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
,使其 none 项看起来像
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
提及这一点 :)。
我完全不确定这是否可行,但知道是否可以在某种程度上做到这一点会很有趣。
您只是在寻找 simplify
吗?
>>> grad
-a*b*exp(-a*b*x)/(1 + exp(-a*b*x))
>>> simplify(grad)
-a*b/(exp(a*b*x) + 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
(请参阅 cancel 在 SymPy 教程中获取更多信息)。
请注意,这只有效,因为它使用 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