为什么我的模型无法学会玩这个游戏,即从一个部分填充的数组中生成一个包含从1到5的唯一元素的数组?
===
我正在尝试训练一个模型来执行这个任务:
给定一个由5个元素组成的固定数组,其中最多包含(1, 2, 3, 4, 5)中的每一个元素各一个,以及一个或多个(0),用适当的值替换0,使最终数组恰好包含(1, 2, 3, 4, 5)中的每一个元素各一个。
所以,游戏应该这样玩:
- [1, 2, 3, 4, 0] => [1, 2, 3, 4, 5]
- [4, 3, 0, 5, 1] => [4, 3, 2, 5, 1]
- [0, 3, 5, 4, 0] => [2, 3, 5, 4, 1] 或 [1, 3, 5, 4, 2]
- …
这对人类来说不是一个复杂的游戏,但我想要看看模型是否能识别出规则(用1到5替换0,使最终数组仅包含(1, 2, 3, 4, 5)中的每一个元素各一个)。
我这样做的步骤是:
- 生成N个包含[1, 2, 3, 4, 5]元素的组合配置作为答案的示例,并随机将一些元素替换为0。
- 例如,一个训练示例是[(0, 3, 5, 4, 0), (2, 3, 5, 4, 1)]。
- 可以有多个相同的输入映射到不同的输出,即[(0, 3, 5, 4, 0), (2, 3, 5, 4, 1)]和[(0, 3, 5, 4, 0), (1, 3, 5, 4, 2)]都可以作为两个独立的训练实例存在。
- 将训练数据集分成10份,洗牌后,使用Scikit-Learn的RandomForestClassifier进行训练。
- 正确输出定义为最终配置数组恰好包含(1, 2, 3, 4, 5)中的每一个元素各一个。因此(2, 4, 4, 5, 1)是不合法的。
===
令人惊讶的是,使用1000、10000、50000甚至100000个训练示例,结果模型在测试案例中仍然只能正确回答约70%,这意味着模型并没有随着训练示例的增加而学会如何玩这个游戏。
我想到的一件事是,RandomForestClassifier并不适合这种类型的问题,称为结构化机器学习,其中输出不是单一类别或实值输出,而是一个输出向量。
更多问题:
- 为什么模型无法学会这个游戏?
- 这是建模这个问题的正确方法吗?
- 数据是否不足以学习这个任务?但从1000增加到100000的数据似乎完全没有帮助。
回答:
lejlot的回答非常出色,但我认为我应该补充一些关于为什么随机森林在这个案例中失败的直觉。
你必须记住,机器学习并不是赋予计算机智能的某种魔法方式;它只是将特定模型拟合到你的数据上,并使用该模型进行泛化的方法。正如一句老话所说,“所有模型都是错误的,但有些是有用的”。你遇到了一个模型通常是错误的,而且恰好没有用的情况!
-
输出空间:随机森林的核心基本上是一种将输入映射到输出的巧妙且可泛化的方法。你的输出空间有
5^5 = 3125
种可能的唯一输出,其中只有5! = 120
种是有效的(即每个数字各一个的输出)。随机森林唯一能知道一个输出是否有效的方法是它是否见过它:因此,为了正确工作,你的训练集必须包含所有这120种输出的示例。 -
输入空间:当随机森林遇到之前见过的输入时,它会直接将其映射到之前见过的输出。但如果它遇到一个未见过的输入呢?例如,如果你询问
[0, 2, 3, 4, 1]
的答案,而这不在训练集中?在欧几里得距离方面(一种思考事物如何分组的有用方式),最接近的结果可能是像[0, 2, 3, 4, 0]
这样的东西,这可能会映射到[1, 2, 3, 4, 5]
,这是错误的。因此我们看到,为了使随机森林正确工作,你的训练集必须包含所有可能的输入。一些简单的组合学显示,你的训练集必须至少有5!*32 = 3840
个大小,且没有重复。 -
森林本身:即使你有一个完整的输入空间,随机森林也不仅仅是一个简单的输入到输出的字典映射。根据模型的参数,映射通常是从一组附近结果到单一答案的映射,因此,例如,
{[1, 2, 3, 4, 5], [1, 0, 3, 4, 5], [0, 1, 3, 4, 5]...}
都会映射到[1, 2, 3, 4, 5]
。这种泛化在大多数情况下是有用的,但对于你的特定问题却没有用。随机森林在你的案例中唯一能工作的方式是将max_depth
和min_samples
参数推到极端值,使森林基本上成为输入到其正确输出的逐一映射:换句话说,你的分类器将只是构建字典的一个极其复杂的方式。
总结:机器学习只是应用于数据的模型,在某些情况下是有用的。在你的案例中,模型并不是那么有用:为了使随机森林在你的问题上工作,你需要过度拟合一个全面的输入和输出集。到那时,你还不如直接构建一个字典了事。