【问题标题】:How to use scipy's minimize within a class?如何在课堂上使用 scipy 最小化?
【发布时间】:2020-12-17 17:38:09
【问题描述】:

我是 python 新手,所以这可能是一个愚蠢的问题,但是我无法在任何地方找到答案。

我正在尝试根据另一名玩家的动作找到一个玩家的最佳反应。这种情况是您对那些熟悉的经济学的典型 Bertrand 价格竞争。代码如下:

import numpy as np
from scipy.optimize import minimize

class Player:
    def __init__(self):
        self.action = np.random.choice(np.linspace(0, 1, 11))

    def payoff(self, other):
        if self.action < other.action:
            return (1 - self.action) * self.action
        elif self.action == other.action:
            return 0.5 * (1 - self.action) * self.action
        else:
            return 0

    def best_reply(self, other):
        br = minimize(-self.payoff, 0.5, other)
        return br['x']

A = Player()
B = Player()

print(A.best_reply(B))

当我运行上面的代码时,我得到一个错误:

TypeError: bad operand type for unary -: 'method'

有人可以向我解释这是为什么吗?我能够通过将收益乘以 -1 并从 best_reply 函数中删除“-”来规避这个问题。但是,当我运行代码时,我得到:

TypeError: payoff() takes 2 positional arguments but 3 were given

怎么会?我给出的唯一论据是自我(A)和其他玩家(B)。如果有人能够通过解释我到底做错了什么以及运行此类代码的正确方法是什么来帮助我,我将非常感激。提前谢谢!

编辑:向代码添加导入

【问题讨论】:

  • minimize 的第一个参数应该是一个函数。 -self.payoff 不是有效操作。你不能否定一个函数。你可以否定它返回的数组或数字,但你不能在-抽象地应用到函数(或方法)。
  • 马上,我看到你在 minimize 函数中调用 -self.payoff 没有参数 other。还。要使用 scipy 最小化功能,您需要添加from scipy.optimize import minimize

标签: python scipy scipy-optimize scipy-optimize-minimize


【解决方案1】:

我会这样做。将要优化的函数与类方法分开,并有一个私有的static method 用于两种方法都可以使用的收益计算。

import numpy as np
from scipy.optimize import minimize

class Player:
    def __init__(self):
        self.action = np.random.choice(np.linspace(0, 1, 11))

    @staticmethod
    def _calc_payoff(a, b):
        if a < b:
            return (1 - a) * a
        elif a == b:
            return 0.5 * (1 - a) * a
        else:
            return 0

    def payoff(self, other):
        return self._calc_payoff(self.action, other.action)

    def best_reply(self, other):
        f = lambda x: 1 - self._calc_payoff(x, other.action)
        br = minimize(f, 0.5)
        return br.x.item()

A = Player()
B = Player()

print(A.best_reply(B))

0.5 是正确的结果吗?

【讨论】:

  • 是的,非常感谢!这种方法非常有效。如果对手选择高于 0.5 的动作,则 0.5 是正确答案,否则正确答案略低于对方玩家的动作。在任何情况下,您的方法都能够解决最佳依赖问题,尽管我必须将收益乘以 -1 才能找到最大值。
  • 啊,是的,好点子。这是一个错误。我会相应地更新代码。
【解决方案2】:

payoff 是一种方法,您不能对方法进行数学运算,只能使用它们的返回值。就像 Python 无法计算出 -print 是什么一样,它也无法计算出 -self.payoff 是什么。

第二个错误参考minimize方法的documentation。我认为问题在于您需要更改调用minimize 的方式。试试这个,请发布结果:

br = minimize(self.payoff, 0.5, (other,))

【讨论】:

  • 应该是一个元组,带逗号,(other,)
  • @hpaulj 感谢您的关注。编辑了答案:)
  • 感谢您的意见@Filip。但是,在只有 1 个 arg 的情况下,是否将 args 作为元组进行转换似乎没有区别。结果是一样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 2019-05-13
  • 2015-03-31
相关资源
最近更新 更多