最近,我偶然发现了以下图片,描述了一个控制台应用程序,该程序通过提出系列问题并在猜错时更新问题,试图猜出用户正在思考的动物:
尽管我对机器学习一无所知,但我认为使用决策树复制这个程序是相当简单的,所以我拼凑了下面的Python代码:
JSON文件DecisionTree1.json包含以下数据,这些数据应该代表一个(非常小的)决策树:
{ "start": { "question": "Is it smaller than a bicycle?", "children": { "yes": { "question": "Is it a rabbit?", "children": null }, "no": { "question": "Is it an elephant?", "children": null } } }}
这个想法应该是,如果用户猜错了,那么程序在做出猜测时查看的叶节点应该被替换为一个新的内部节点,该节点为程序的猜测提供额外的过滤级别。
就JSON而言,这意味着:
- 用用户指定的问题替换包含当前猜测的节点的“question”属性
- 更新节点的“children”属性,使其不再为null,而是包含两个新节点,每个节点都构成了一个猜测(即一个叶节点)
我的问题是如何以这种方式更新文件中的JSON?
目前,我的Python代码中的query
变量更新了JSON,使得“children”属性的值变为一个字符串,而不是两个子节点。
编辑:根据martineau的评论,以下是更新后的JSON应有的样子示例:
假设用户在思考乌龟。如今,程序会错误地猜测他们的动物是兔子。当被要求“输入一个对乌龟回答是’是’,对兔子回答是’不是’的问题”时,他们可能会指定问题“它有壳吗?”。现有的JSON(如上所示)然后应变为
{ "start": { "question": "Is it smaller than a bicycle?", "children": { "yes": { "question": "Does it have a shell?", "children": { "yes": { "question": "Is it a tortoise?", "children": null }, "no": { "question": "Is it a rabbit?", "children": null } } }, "no": { "question": "Is it an elephant?", "children": null } } }}
回答:
你的问题确实很有趣。我尝试了一下,但在解释解决方案之前,我想指出我在处理你的代码时发现的一些概念问题。以下是我所做的更改:
-
我认为你的JSON结构解析起来不太容易。我选择了更舒适的结构,通过移除“children”节点,因为总是只有两个可能的选择:是或不是。
-
不要混淆:一旦加载,像你这样的JSON消息只不过是一个包含其他
dict
的简单dict
。你不需要自己在JSON文件中写入任何内容,因为Python知道如何转换这种结构。 -
在树层次结构中使用迭代在性能和易用性方面被认为是不好的选择。使用递归更加直接,我强烈建议你学习在某些情况下(如这个)它是如何有效的。
-
我发现验证是你迭代过程的一个副作用。在我看来,你不需要在每个地方都使用那个额外的
validation
参数,但如果你真的需要它,欢迎你重新集成它。 -
我通过添加一些东西“优化”了你的代码,比如
if __name__ == "__main__"
,其目的是检查Python文件是作为模块启动还是嵌入在另一个解决方案中。你还误用了open
指令来读写文件。我为你修正了这些错误。
希望通过阅读我的解决方案,你能学到一些技巧,这就是我写它的原因。我并不自称无所不知,所以可能也会有错误,但它应该能帮助你继续推进你的项目。我通常期望你将脚本的学习部分拆分到其他函数中。