【问题标题】:Too many copies? Poor comparison? Urn Probability Problem副本太多?比较差?瓮概率问题
【发布时间】:2022-07-08 11:34:29
【问题描述】:

完整代码:https://gist.github.com/QuantVI/79a1c164f3017c6a7a2d860e55cf5d5b

TLDR:sum(a3) 给出了一个类似 770 的数字,而它应该更像是 270 - 如在 1000 次试验中的 270 次,其中绘制 4包含(至少)2 个蓝色和 1 个绿球。


我已经重写了我创建示例输出的方式,以及我已经两次比较结果的方式。 Python 作为我最初使用的语法 `all(x in a for x n b)`,然后改成更深思熟虑的东西,看看是否有变化。每次试验我仍然有 750 多个“真实”评估。这就是为什么我重新评估我是如何选择不更换的。

我已经用不同的Hats 单独测试了draw 函数,并确定它有效。

从包含 (blue=3,red=2,green=6) 且结果包含 (blue=2,green=1) 或 ['blue' ,'蓝绿色'] 约为 27.2%。在我的 1000 次试验中,我反复超过 700 次。

错误是在Hat.draw() 还是在experiment()

注意:有些东西被注释掉了,因为我在调试。因此使用 sum(a3) 因为 experiment 被注释掉以返回除了概率之外的东西。

import copy
import random
# Consider using the modules imported above.

class Hat:
    def __init__(self, **kwargs):
        self.d = kwargs
        self.contents = [
            key for key, val in kwargs.items() for num in range(val)
        ]
    def draw(self, num: int) -> list:
        if num >= len(self.contents):
            return self.contents
        else:
            indices = random.sample(range(len(self.contents)), num)

            chosen = [self.contents[idx] for idx in indices]

            #new_contents = [ v for i, v in enumerate(self.contents) if i not in indices]

            new_contents = [pair[1] for pair in enumerate(self.contents) 
                            if pair[0] not in indices]
            self.contents = new_contents
            return chosen

    def __repr__(self): return str(self.contents)

def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
  trials =[]
  for n in range(num_experiments):
    copyn = copy.deepcopy(hat)
    result = copyn.draw(num_balls_drawn)
    trials.append(result)

  #trials = [ copy.deepcopy(hat).draw(num_balls_drawn) for n in range(num_experiments) ]

  expected_contents =  [key for key, val in expected_balls.items() for num in range(val)]

  temp_eval = [[o for o in expected_contents if o in trial] for trial in trials]

  temp_compare = [ evaled == expected_contents for evaled in temp_eval]

  return expected_contents,temp_eval,temp_compare, trials

  #evaluations = [ all(x in trial for x in expected_contents) for trial in trials ]

  #if evaluations: prob = sum(evaluations)/len(evaluations)
  #else: prob = 0

  #return prob, expected_contents


#hat3 = Hat(red=5, orange=4, black=1, blue=0, pink=2, striped=9)
#hat4 = Hat(red=1, orange=2, black=3, blue=2)

hat1 = Hat(blue=3,red=2,green=6)

a1,a2,a3,a4 = experiment(hat=hat1, expected_balls={"blue":2,"green":1}, num_balls_drawn=4, num_experiments=1000)
        #actual = probability
        #expected = 0.272
        #self.assertAlmostEqual(actual, expected, delta = 0.01, msg = 'Expected experiment method to return a different probability.')


hat2 = Hat(yellow=5,red=1,green=3,blue=9,test=1)

b1,b2,b3,b4 = experiment(hat=hat2, expected_balls={"yellow":2,"blue":3,"test":1}, num_balls_drawn=20, num_experiments=100)
        #actual = probability
        #expected = 1.0
        #self.assertAlmostEqual(actual, expected, delta = 0.01, msg = 'Expected experiment method to return a different probability.')

【问题讨论】:

  • 像往常一样,发布问题后才有意义。我想我知道这个问题:我应该重新排序eval。我会在确认后发布。

标签: python-3.x list-comprehension probability deep-copy python-all-function


【解决方案1】:

问题是temp_eval = [[o for o in expected_contents if o in trial] for trial in trials]。即使一次试验的结果中只存在一个blue,它也会始终将blue 都添加到列表中。

但是,我无法直接修复错误。相反,当我需要大约 0.27(1000 次试验中的 270 次)时,我的修复创建了一个低得多的答案,小于 0.1

迂回的解决方案是使用该列表的collections.Counter 上的list['red', 'green', 'blue', 'green'] 之类的列表转换为字典。然后对值进行关键比较,例如[y[key]<= x.get(key,0) for key in y.keys()])。在此比较中,yexpected_balls 变量,x 是计数器对象的列表。如果x 没有其中一个键,我们得到0。零将小于expected_balls 中任何键的值。

从这里我们使用functols.reduce 将输出转换为单个 True 或 False 值。然后我们map 在所有试验中使用该功能(比较所有键并获得一个 T/F 值)。

def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
    trials =[]
    trials = [ copy.deepcopy(hat).draw(num_balls_drawn) 
              for n in range(num_experiments) ]
    trials_kvpairs = [dict(collections.Counter(trial)) for trial in trials]
    
    def contains(contained:dict , container:dict):
        each = [container.get(key,0) >= contained[key]
                for key in contained.keys()]
        return reduce(lambda item0,item1: item0 and item1, each)
    
    trials_success = list(map(lambda t: contains(expected_balls,t), trials_kvpairs))
    
    # expected_contents =  [pair[0] for pair in expected_balls.items() for num in range(pair[1])]
    # temp_eval = [[o for o in trial if o in expected_contents] for trial in trials]
    # temp_compare = [ evaled == expected_contents for evaled in temp_eval]
    # if temp_compare: prob = sum(temp_compare)/len(trials)
    # else: prob = 0
    return 'prob', trials_kvpairs, trials_success

当使用 this experiment(hat=hat1, expected_balls={"blue":2,"green":1}, num_balls_drawn=4, num_experiments=1000) 运行时,输出的第三部分的总和为 276

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2018-06-12
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多