设计二十个问题算法

时间:2011-02-06 20:12:30

标签: algorithm artificial-intelligence puzzle

我感兴趣的是编写一个类似于twenty questionsakinator算法,以及20q.net在较小程度上使用的算法。后者似乎更关注对象,明确告诉你不要想到人或地方。可以说akinator更通用,允许你从字面上思考任何东西,包括诸如“我的兄弟”之类的抽象。

这个问题在于我不知道这些网站使用的是什么算法,但从我读到的内容来看,他们似乎正在使用一种概率方法,根据问题给出的问题具有一定的适应性。正确的猜测。这个SO question提出了几种技巧,但含糊不清,我会对更多细节感兴趣。

那么,什么是一个准确有效的算法来播放二十个问题呢?

我对以下方面感兴趣:

  1. 接下来要问什么问题。
  2. 如何在20个问题结束时做出最佳猜测。
  3. 如何将新对象和新问题插入数据库。
  4. 如何有效地查询(1,2)和更新(3)数据库。
  5. 我意识到这可能并不容易,我不是要求代码或2000字的演示文稿。关于每个操作和底层数据结构的几句话应该足以让我开始。

4 个答案:

答案 0 :(得分:11)

好吧,三年后,我做到了(虽然我没有全职工作)。如果有人有兴趣的话,我在http://twentyquestions.azurewebsites.net/举办了一次粗略的实施(请不要教太多错误的内容!)。

这并不难,但我会说,你不会立即想到的那种不直观的不直观的事情。我的方法包括一些基于健康的琐碎排名,来自reinforcement learning的想法和一个安排要问的新问题的round-robin方法。所有这些都是在规范化的关系数据库上实现的。

我的基本想法如下。如果有人有兴趣,我也会分享代码,请联系我。我打算最终把它变成开源,但是一旦我做了更多的测试和改造。所以,我的想法:

  • 实体表,其中包含所播放的字符和对象;
  • 包含问题的问题表,也由用户提交;
  • EntityQuestions 表包含实体 - 问题关系。这保留了每个问题与每个实体相关的每个答案的次数(嗯,无论如何要求提出问题的答案)。它还有一个Fitness字段,用于排序来自"更一般"到#34;更具体的";
  • GameEntities 表用于根据目前为每个正在进行的游戏给出的答案对实体进行排名。 A对问题Q的回答推动了对问题Q的多数回答为A的所有实体;
  • 第一个问题是从 EntityQuestions 表中具有最高合适度的人中挑选出来的;
  • GameEntities表中当前最高条目相关的适应度最高的那些问题中挑选出下一个问题。预期答案为“是”的问题甚至在适应性之前受到青睐,因为这些问题有更多机会巩固当前排名靠前的实体;
  • 如果系统在提出所有20个问题之前都非常确定答案,那么它将开始提出与其答案无关的问题,以便了解有关该实体的更多信息。现在,这是通过全球问题池以循环方式完成的。 讨论:是循环正常的,还是应该完全随机?
  • 在某些条件和概率下也给出了过早的答案;
  • 根据 GameEntities 中的排名给出猜测。这也允许系统解释谎言,因为它永远不会消除任何可能性,只会降低其作为答案的可能性;
  • 每场比赛结束后,健身和答案统计数据会相应更新:如果游戏丢失,实体 - 问题关联的适合度值会降低,否则会增加。

如果有兴趣,我可以提供更多细节。我也愿意合作改进算法和实现。

答案 1 :(得分:4)

我正在尝试使用天真的贝叶斯网络编写一个python实现来学习并在问题被回答为选择问题的标准后最小化预期的熵(ε有机会选择随机问题以便学习关于这个问题的更多信息),遵循http://lists.canonical.org/pipermail/kragen-tol/2010-March/000912.html中的想法。到目前为止,我已经把我所得到的东西放在了github上。

  1. 优选选择具有低剩余熵预期的问题。 (为了快速组合一些东西,我偷走了ε-贪婪的多臂强盗学习和使用:概率1-ε:用最低剩余熵期望问题。用概率ε:问任何随机问题。但是,这种方法似乎远非最佳。)
  2. 由于我的方法是贝叶斯网络,我获得了对象的概率,并且可以询问最可能的对象。
    • 新对象作为新列添加到概率矩阵中,具有较低的先验概率,如果给出或如果没有给出贝叶斯网络猜测,则给出问题的答案。 (如果我要添加贝叶斯网络结构学习而不是仅仅使用朴素的贝叶斯,我希望第二部分可以更好地工作。)
    • 同样,新问题是矩阵中的新行。如果它来自用户输入,可能只知道很少的答案概率,其余的需要猜测。 (一般来说,如果你可以通过询问属性来获取对象,你可以通过询问给定对象是否具有它们来获得属性,并且这些属性之间的转换基本上是贝叶斯定理,并且在最简单的情况下分解为转置。一旦网络具有适当的结构,质量应该再次提高。)
  3. (这是一个问题,因为我计算了很多概率。我的目标是使用针对加权有向非循环图优化的面向数据库的稀疏张量计算来实现。)

答案 2 :(得分:4)

这是一个非常有趣的问题。不幸的是,我没有完整的答案,让我在10分钟内写下我能提出的想法:

  • 如果您能够将每个问题的可用答案集合减半,则可以区分2 ^ 20~1百万个“对象”。你的设置可能会更大,所以假设有时你必须猜测是正确的。
  • 您希望最大化实用程序。有些对象的选择频率高于其他对象。如果你想做出好的猜测,你必须在创建树时考虑每个对象的权重(=该对象被挑选的概率)。
  • 如果您信任一些用户,您可以根据他们的答案获得知识。这也意味着您不能使用静态树来提问,因为这样您就可以获得相同问题的答案。如果您遇到同一个对象,您将不会学到任何新东西。< / LI>
  • 如果一个简单的问题无法将该组分成两半,您可以将它们组合起来以获得更好的结果:例如:“对象是绿色还是蓝色?”。 “绿色有圆形吗?”

答案 3 :(得分:1)

看看基于决策树的算法能为您提供多好的服务会很有趣。这里的诀窍纯粹是在树的学习/排序中。我想要注意的是,这是我记得AI班和学生在AI工作组中工作的东西,应该用半大粒(或金块)加盐。

回答问题:

  1. 你只是走在树上:))
  2. 这是决策树的一大缺点。您只有一个猜测可以附加到深度为20的树的末端节点(或者更早,如果树仍然稀疏)。
  3. 有专门讨论这个主题的全书。据我记得AI类,你总是尝试最小化熵,所以你想提出一些问题,理想地将剩余对象集分成两组相等的大小。我担心你不得不在AI书中查看它。
  4. 在查询阶段,决策树非常高效,因为您实际上是在走树,并在每个节点上遵循“是”或“否”分支。更新效率取决于所应用的学习算法。您可以像在夜间批量更新中那样离线执行此操作。