原文:https://machinelearningmastery.com/different-results-each-time-in-machine-learning/
最后更新于 2020 年 8 月 27 日
你的机器学习算法是否得到了不同的结果?
也许你的结果不同于教程,你想知道为什么。
也许你的模型在每次训练时都会做出不同的预测,即使每次都是在相同的数据集上训练。
这是意料之中的,甚至可能是算法的一个特征,而不是一个错误。
在本教程中,您将发现为什么在使用机器学习算法时会期望不同的结果。
完成本教程后,您将知道:
- 如果训练数据集发生变化,机器学习算法将训练不同的模型。
- 随机机器学习算法在学习过程中使用随机性,确保每次运行都训练不同的模型。
- 开发环境的差异,如软件版本和中央处理器类型,会导致预测和模型评估中的舍入误差差异。
我们开始吧。
为什么我每次在机器学习中都得到不同的结果? 图片由邦妮·莫兰提供,版权所有。
本教程分为五个部分;它们是:
- 救命,我得到了不同的结果!?
- 训练数据引起的差异
- 学习算法引起的差异
- 评估程序引起的差异
- 平台导致的差异
别慌。机器学习算法或模型可以给出不同的结果。
不是你的错。事实上,它通常是一个特性,而不是一个 bug。
我们会明确说明和解释你的问题。
首先,让我们掌握基本知识。
在应用机器学习中,我们在数据集上运行机器学习“算法,得到机器学习“模型”然后,可以对训练期间未使用的数据或用于对新数据进行预测的数据(也是训练期间未看到的数据)评估该模型。
- 算法:对产生模型的数据运行的程序(例如训练或学习)。
- 模型:用于对数据进行预测的数据结构和系数。
有关机器学习算法和模型之间区别的更多信息,请参见教程:
监督机器学习意味着我们有输入和输出变量(列)的例子(行)。我们不能编写代码来预测给定输入的输出,因为这太难了,所以我们使用机器学习算法来学习如何从给定历史示例的输入中预测输出。
这被称为函数近似,我们正在学习或搜索一个函数,该函数在我们的特定预测任务上将输入映射到输出,以使其具有技能,这意味着映射的表现优于随机的,理想情况下优于我们尝试过的所有其他算法和算法配置。
- 监督学习:自动学习从输入示例到输出示例的映射函数。
从这个意义上说,机器学习模型是我们打算用于某个项目或应用的程序;碰巧的是,这个程序是从例子中学习的(使用一种算法),而不是用 if 语句等显式编写的。这是一种自动编程。
- 机器学习模型:一个“程序”自动从历史数据中学习。
与我们可能习惯的编程不同,这些程序可能不是完全确定的。
每次训练机器学习模型时,它们可能是不同的。反过来,模型可能会做出不同的预测,并且在评估时,可能会有不同程度的误差或准确性。
至少有四种情况你会得到不同的结果;它们是:
- 不同的结果是因为训练数据的不同。
- 不同的结果是因为随机学习算法。
- 不同的结果是因为随机评估程序。
- 因为平台不同,结果也不同。
让我们依次仔细看看每一个。
我是否遗漏了导致结果差异的可能原因? 在下面的评论里告诉我。
在不同的数据上运行相同的算法,会得到不同的结果。
这被称为机器学习算法的方差。你可能在偏差-方差权衡的背景下听说过它。
方差是衡量算法对训练过程中使用的特定数据的敏感度。
- 方差:算法对训练时使用的具体数据有多敏感。
更敏感的算法具有更大的方差,这将导致模型中更大的差异,进而导致模型的预测和评估。相反,不太敏感的算法具有较小的方差,并且将导致具有不同训练数据的结果模型中的较小差异,并且反过来,导致结果预测和模型评估中的较小差异。
- 高方差:算法对训练时使用的具体数据更加敏感。
- 低方差:算法对训练时使用的具体数据不太敏感。
有关方差和偏差-方差权衡的更多信息,请参见教程:
所有有用的机器学习算法都会有一些方差,一些最有效的算法也会有很高的方差。
与方差较小的算法相比,方差较大的算法通常需要更多的训练数据。如果我们考虑从输入和输出近似映射函数的模型和大数定律,这是直观的。
然而,当你在不同的训练数据上训练机器学习算法时,你会得到一个不同的模型,它有不同的行为。这意味着不同的训练数据将给出做出不同预测的模型,并具有不同的表现估计(例如误差或准确性)。
结果的差异程度将与每个模型的训练数据的差异程度以及您选择的特定模型和模型配置的差异有关。
您通常可以通过更改算法的超参数来减少模型的方差。
例如, k 中的k-最近邻控制算法的方差,其中像 k=1 这样的小值导致高方差,像 k=21 这样的大值导致低方差。
您可以通过更改算法来减少方差。例如,像线性回归和逻辑回归这样更简单的算法比其他类型的算法具有更低的方差。
您也可以通过增加训练数据集的大小来降低高方差算法的方差,这意味着您可能需要收集更多的数据。
由于学习算法的性质,当您对相同的数据运行相同的算法时,可能会得到不同的结果。
这很可能是你阅读本教程的原因。
你在同一个数据集上运行相同的代码,得到的模型每次都做出不同的预测或者有不同的表现,你认为这是一个 bug 什么的。 ***我说的对吗?*T3】
这不是 bug,这是特性。
一些机器学习算法是确定性的。就像你习惯的编程一样。这意味着,当算法被赋予相同的数据集时,它每次都学习相同的模型。一个例子是线性回归或逻辑回归算法。
有些算法是不确定的;相反,它们是随机的。这意味着他们的行为包含了随机性的元素。
随机不代表随机。随机机器学习算法不是学习随机模型。他们正在学习一个以你提供的历史数据为条件的模型。相反,算法在学习过程中做出的具体小决策可以随机变化。
其影响是,每次随机机器学习算法在相同的数据上运行时,它都会学习到稍微不同的模型。反过来,模型可能会做出稍微不同的预测,并且当使用误差或准确性进行评估时,可能会有稍微不同的表现。
有关随机及其在机器学习中的意义的更多信息,请参见教程:
给算法做出的一些决策增加随机性可以提高解决难题的表现。用域中有限的数据样本学习监督学习映射函数是一个非常困难的问题。
为数据集找到一个好的或最好的映射函数是一种搜索问题。我们测试定义搜索空间形状的不同算法和测试算法配置,并在搜索空间中给我们一个起点。然后,我们运行算法,然后将搜索空间导航到单个模型。
添加随机性可以帮助避免好的解决方案,并帮助在搜索空间中找到真正好的和伟大的解决方案。它们允许模型避开局部最优或欺骗性的局部最优(学习算法可能会遇到这种情况),并帮助找到更好的解决方案,甚至全局最优。
有关将监督学习视为搜索问题的更多信息,请参见教程:
在学习过程中使用随机性的算法的一个例子是神经网络。它以两种方式使用随机性:
- 随机初始权重(模型系数)。
- 每个时期的随机抽样。
神经网络(深度学习)是一种随机机器学习算法。随机初始权重允许模型在每次算法运行时尝试从搜索空间的不同起点进行学习,并允许学习算法在学习过程中“T0”打破对称性。训练期间示例的随机混洗确保每个梯度估计和权重更新略有不同。
有关神经网络随机特性的更多信息,请参见教程:
另一个例子是随机的集成机器学习算法,例如 bagging。
随机性用于训练数据集的采样过程,以确保为集合中的每个贡献成员准备不同的决策树。在集成学习中,这被称为集成多样性,是一种从单个训练数据集模拟独立预测的方法。
有关打包集合的随机性质的更多信息,请参见教程:
学习算法使用的随机性是可以控制的。
例如,您设置伪随机数发生器使用的种子,以确保每次运行算法时,它都获得相同的随机性。
有关随机数生成器和设置固定种子的更多信息,请参见教程:
这可能是教程的一个好方法,但在实践中不是一个好方法。它会引发这样的问题:
- 伪随机数发生器的最佳种子是什么?
随机机器学习算法没有最佳种子。你在对抗算法的本质,迫使随机学习成为确定性的。
您可以使用一个固定的种子来证明最终模型是合适的,以确保在进行任何部署前系统测试之前,在生产中使用相同的数据创建相同的模型。然而,一旦训练数据集改变,模型就会改变。
更好的方法是接受机器学习算法的随机特性。
考虑到您的数据集没有单一的模型。相反,有一个随机过程(算法管道)可以为您的问题生成模型。
有关这方面的更多信息,请参见教程:
然后,您可以将这些模型(算法管道)的表现总结为具有平均预期误差或精确率以及标准偏差的分布。
然后,您可以通过在数据集上拟合多个最终模型,并在需要对新数据进行预测时对它们的预测进行平均,来确保实现模型的平均表现。
有关最终模型的集成方法的更多信息,请参见教程:
由于评估过程,在使用相同数据运行相同算法时,您可能会得到不同的结果。
两种最常见的评估程序是列车测试分割和 k 倍交叉验证。
一个训练-测试分割包括随机分配用于训练模型或评估模型以满足预定义的训练或测试集大小的行。
有关列车测试分割的更多信息,请参见教程:
k 折叠交叉验证过程包括将数据集划分为 k 个不重叠的分区,并将一个折叠用作测试集,将所有其他折叠用作训练集。模型适合训练集,并在保持折叠上进行评估,此过程重复 k 次,使每个折叠都有机会用作保持折叠。
有关 k-fold 交叉验证的更多信息,请参见教程:
这两种模型评估程序都是随机的。
同样,这并不意味着它们是随机的;这意味着在这个过程中做出的小决定包含随机性。具体来说,选择将哪些行分配给给定的数据子集。
这种随机性的使用是一个特性,而不是一个 bug。
在这种情况下,随机性的使用允许重采样近似模型表现的估计,该估计独立于从域中提取的特定数据样本。这种近似是有偏差的,因为我们只有一小部分数据样本,而不是全部可能的观测值。
当对训练期间未看到的数据进行领域预测时,表现估计提供了模型的预期或平均能力的概念。不考虑用于训练或测试模型的特定数据行,至少在理想情况下是这样。
有关更一般的统计抽样主题的更多信息,请参见教程:
因此,确定性机器学习算法的每个评估,像线性回归或逻辑回归,可以给出不同的误差或精确率估计。
这种情况下的解决方案很像随机学习算法的情况。
伪随机数发生器的种子可以是固定的,或者可以包含过程的随机性。
与随机学习算法不同,两种解决方案都相当合理。
如果在预测建模任务中系统地评估大量机器学习算法和算法配置,修复评估过程的随机种子可能是一个好主意。任何价值都行。
其思想是,每个候选解决方案(每个算法或配置)将以相同的方式进行评估。这确保了苹果对苹果的比较。如果需要,它还允许以后使用成对的统计假设检验来检查算法之间的差异是否具有统计学意义。
拥抱随机性也是合适的。这包括多次重复评估程序,并报告绩效分数分布的摘要,如平均值和标准偏差。
也许重复评估中偏差最小的方法是使用重复的 k 倍交叉验证,例如三次重复 10 倍(3×10),这很常见,或者五次重复两次(5×2),这在比较算法和统计假设检验时很常用。
有关使用统计假设检验来比较算法的简单介绍,请参见教程:
有关比较平均算法表现和假设检验的教程,请参见教程:
在不同的计算机上对相同的数据运行相同的算法时,可以得到不同的结果。
即使您固定随机数种子来解决学习算法和评估过程的随机性质,这也可能发生。
这种情况下的原因是用于运行示例的平台或开发环境,结果通常会有细微的不同,但并不总是如此。
这包括:
- 系统架构的差异,例如 CPU 或 GPU。
- 操作系统的差异,如 MacOS 或 Linux。
- 基础数学库的差异,例如 LAPACK 或 BLAS。
- Python 版本的差异,例如 3.6 或 3.7。
- 库版本的差异,例如 Sklearn 0.22 或 0.23。
- …
机器学习算法是一种数值计算。
这意味着它们通常涉及大量浮点值的数学运算。体系结构和操作系统等方面的差异可能会导致舍入误差的差异,这可能会与执行的计算数量相加,从而产生非常不同的结果。
此外,库版本的差异可能意味着错误的修复和功能的改变,这也会导致不同的结果。
此外,这也解释了为什么在由不同语言(如 R 和 Python)实现的同一台机器上,相同的算法会得到不同的结果。实现中的微小差异和/或使用的底层数学库的差异将导致最终模型和该模型所做预测的差异。
这并不意味着平台本身可以被视为一个超参数,并针对预测建模问题进行调整。
相反,这意味着在评估机器学习算法时,平台是一个重要因素,并且应该是固定的或完全描述的,以确保从开发到生产或在学术研究中报告表现时的完全再现性。
一种方法可能是使用虚拟化,如 docker 或虚拟机实例,以确保环境保持不变,如果完全再现性对项目至关重要的话。
老实说,在实践中,只要主要软件版本足够好或足够接近,效果往往很小(至少在我有限的经验中是这样)。
如果您想更深入地了解这个主题,本节将提供更多资源。
- 机器学习中算法和模型的区别
- 机器学习中偏差-方差权衡的温和介绍
- 随机在机器学习中意味着什么?
- 作为搜索问题的应用机器学习的温和介绍
- 为什么用随机权重初始化神经网络?
- 如何用 Python 开发打包套装
- 如何减少最终机器学习模型中的方差
- Python 机器学习随机数生成器介绍
- 统计采样和重采样的简单介绍
- 用于比较机器学习算法的统计显著性测试
在本教程中,您发现了为什么在使用机器学习算法时会出现不同的结果。
具体来说,您了解到:
- 如果训练数据集发生变化,机器学习算法将训练不同的模型。
- 随机机器学习算法在学习过程中使用随机性,确保每次运行都训练不同的模型。
- 开发环境的差异,如软件版本和中央处理器类型,会导致预测和模型评估中的舍入误差差异。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。