常见问题¶
通用¶
哪里可以找到使用 auto-sklearn 的示例?
我们提供了在多种用例中使用 auto-sklearn 的示例,范围从简单的分类到高级用法,例如特征重要性、并行运行和自定义。它们可以在示例中找到。
auto-sklearn 可以解决哪种类型的任务?
auto-sklearn* 可以接受以下任务的目标(更多详情请参见 Sklearn 算法)
二元分类
多类别分类
多标签分类
回归
多输出回归
您可以向 auto-sklearn* 提供特征和目标训练对(X_train/y_train),以拟合一组 pipeline,如下一节所述。此 X_train/y_train 数据集必须属于支持的格式之一:np.ndarray、pd.DataFrame、scipy.sparse.csr_matrix 和 python 列表。您还可以选择通过提供可选的测试对(X_test/Y_test)来衡量此拟合模型泛化到未见数据的能力。有关更多详细信息,请参阅示例 随时间变化的性能曲线图。
关于特征,有几点需要考虑
提供带有可选标志 `feat_type` 的 X_train/X_test numpy 数组。有关更多详细信息,请查看示例 特征类型。
您可以提供列格式正确的 pandas DataFrame。如果列的数据类型是数值,*auto-sklearn* 不会对其进行编码,会直接传递给 scikit-learn。*auto-sklearn* 支持分类或字符串作为列类型。请确保为您的任务使用正确的数据类型。默认情况下,*auto-sklearn* 将 object 和 string 列视为字符串,并使用 sklearn.feature_extraction.text.CountVectorizer 对数据进行编码。
如果您的数据包含分类值(在特征或目标中),请确保明确将其标记为分类类型。标记为分类类型的数据会使用 sklearn.preprocessing.LabelEncoder 对一维数据进行编码,并使用 sklearn.preprodcessing.OrdinalEncoder 对多维数据进行编码。
有关如何正确编码数据的更多详细信息,您可以查看 Pandas 示例 使用分类数据)。如果您正在处理时间序列,建议您遵循这种方法 使用时间数据。
如果您完全不想使用字符串选项,可以禁用此选项。在这种情况下,对象、字符串和分类列都被编码为分类类型。
import autosklearn.classification
automl = autosklearn.classification.AutoSklearnClassifier(allow_string_features=False)
automl.fit(X_train, y_train)
关于目标(y_train/y_test),如果任务涉及分类问题,则这些特征将自动编码。建议在 fit 期间同时提供 y_train 和 y_test,以便在这些分割之间创建共同的编码(如果在 fit 期间只提供 y_train,则分类编码器将无法处理 y_test 中独有的新类别)。如果任务是回归,则不对目标进行编码。
在科学出版物中如何引用 auto-sklearn?
如果您在科学出版物中使用了 auto-sklearn,我们将非常感谢您的引用。
@inproceedings{feurer-neurips15a,
title = {Efficient and Robust Automated Machine Learning},
author = {Feurer, Matthias and Klein, Aaron and Eggensperger, Katharina Springenberg, Jost and Blum, Manuel and Hutter, Frank},
booktitle = {Advances in Neural Information Processing Systems 28 (2015)},
pages = {2962--2970},
year = {2015}
}
或者如果您在工作中使用了 auto-sklearn 2.0,请引用此项
@article{feurer-arxiv20a,
title = {Auto-Sklearn 2.0: Hands-free AutoML via Meta-Learning},
author = {Feurer, Matthias and Eggensperger, Katharina and Falkner, Stefan and Lindauer, Marius and Hutter, Frank},
booktitle = {arXiv:2007.04074 [cs.LG]},
year = {2020}
}
我想做贡献。我能做些什么?
听起来很棒。请查看我们的贡献指南。
我有一个这里没有回答的问题。我应该怎么办?
非常感谢。我们会定期使用问题追踪器中的问题来更新本节。所以请使用问题追踪器。
资源管理¶
如何设置时间和内存限制?
虽然 auto-sklearn* 减轻了手动超参数调整的工作,但用户仍然需要设置内存和时间限制。对于大多数数据集,现代计算机上的 3GB 或 6GB 内存限制就足够了。对于时间限制,很难给出明确的指导方针。如果可能,一个好的默认值是总时间限制一天,单个运行的时间限制 30 分钟。
更多指导可以在 auto-sklearn/issues/142 中找到。
auto-sklearn 默认使用多少 CPU 核心?
默认情况下,auto-sklearn* 使用**一个核心**。另请参阅关于如何配置此设置的 并行计算。
如何并行运行 auto-sklearn?
然而,auto-sklearn* 也通过使用 Dask.distributed 支持并行贝叶斯优化。通过在 estimator 构造时提供参数 n_jobs
,可以控制 *auto-sklearn* 可用的核心数量(如示例 在单台机器上并行使用 所示)。通过向 *auto-sklearn* 提供自定义客户端对象,也支持分布式进程,如示例所示:并行使用:从命令行生成 worker。当有多个核心可用时,*auto-sklearn* 将为每个核心创建一个 worker,并使用可用的 worker 来搜索更好的机器学习模型,以及与它们一起构建集成,直到时间资源耗尽。
注意: auto-sklearn* 要求所有 worker 都能访问共享文件系统来存储训练数据和模型。
auto-sklearn* 使用 threadpoolctl 来控制 numpy 或 scikit-learn 等科学计算库使用的线程数。这仅在模型构建过程中进行,不在推理过程中进行。特别是,*auto-sklearn* 允许每个 pipeline 在训练期间最多使用 1 个线程。在预测和评分时,*auto-sklearn* 不强制执行此限制。您可以通过在运行 *auto-sklearn* 之前在环境中设置以下变量来控制 pipeline 使用的资源数量:
$ export OPENBLAS_NUM_THREADS=1
$ export MKL_NUM_THREADS=1
$ export OMP_NUM_THREADS=1
有关 scikit-learn 如何处理多进程的更多信息,请查看该库的文档:并行性、资源管理和配置。
Auto-sklearn 在顺序设置下非常占用内存
Auto-sklearn 可能看起来非常占用内存(即对于小数据集需要大量内存),这是由于在顺序模式下运行时使用 fork
创建新进程(如果在并行设置下发生这种情况或传递了自己的 dask 客户端,则是由于其他问题,请参阅下面的其他问题)。
让我们深入了解更多细节并讨论如何解决它:Auto-sklearn 在自己的进程中执行每个机器学习算法,以便应用内存限制和时间限制。要启动这样的进程,Python 提供了三种选项:fork
、forkserver
和 spawn
。默认的 fork
会将整个进程内存复制到子进程中。如果主进程已经使用了 1.5GB 主存,并且我们对 Auto-sklearn 应用 3GB 内存限制,则执行机器学习 pipeline 被限制为最多使用 1.5GB。我们本想将 forkserver
或 spawn
用作默认选项,它们都只将相关数据复制到子进程中,从而缓解占用大量主存的问题(并且不像 fork
那样会发生潜在的死锁,请参阅此处),但它们的缺点是代码必须由 if __name__ == "__main__"
保护或在 notebook 中执行,我们决定默认不要求这样做。
现在有两种可能的解决方案
并行使用 Auto-sklearn:如果您并行使用 Auto-sklearn,它默认使用
forkserver
,因为并行化机制本身要求 Auto-sklearn 代码被保护。请在以下两个示例中找到有关如何执行此操作的更多信息注意
这要求所有代码都受到
if __name__ == "__main__"
的保护。传递一个 dask 客户端。如果用户传递了 dask 客户端,Auto-sklearn 就不能再假定它以顺序模式运行,并将使用
forkserver
来启动新进程。注意
这要求所有代码都受到
if __name__ == "__main__"
的保护。
因此,我们建议默认使用上述设置之一。
Auto-sklearn 在并行设置下非常占用内存
在并行设置下运行 Auto-sklearn 时,它会使用 forkserver
机制启动新进程来评估机器学习模型。主脚本中未受到 if __name__ == "__main__"
保护的代码将针对每个子进程执行。例如,如果您在受保护代码之外加载数据集,则数据集将在每次评估机器学习算法时被加载,从而占用您的 RAM。
因此,我们建议将所有代码移至函数内部或主代码块中。
结果、日志文件和输出¶
如何获取运行统计信息的概览?
sprint_statistics()
是一个方法,它打印数据集名称、使用的指标以及运行 *auto-sklearn* 获得的最佳验证分数。它还会打印成功和不成功的算法运行次数。
随时间变化的性能如何?
performance_over_time_
返回一个 DataFrame,其中包含模型随时间变化的性能数据,可以直接用于绘图(这里有一个示例:随时间变化的性能曲线图)。
automl.performance_over_time_.plot(
x='Timestamp',
kind='line',
legend=True,
title='Auto-sklearn accuracy over time',
grid=True,
)
plt.show()
评估了哪些模型?
您可以使用 automl.leaderboard(ensemble_only=False)
查看所有评估的模型。
最终集成中包含哪些模型?
使用 automl.leaderboard(ensemble_only=True)
或 automl.show_models()
还有其他数据可以查看吗?
cv_results_
返回一个字典,其中键是列标题,值是列数据,可以导入到 pandas DataFrame 中,例如 df = pd.DataFrame(automl.cv_results_)
Auto-sklearn 默认将文件输出到哪里?
Auto-sklearn* 大量使用硬盘来存储临时数据、模型和日志文件,这些文件可用于检查 Auto-sklearn 的行为。Auto-sklearn 的每次运行都需要自己的目录。如果用户未提供,*Auto-sklearn* 会向 Python 请求一个临时目录,该目录默认位于 /tmp
下,并以 autosklearn_tmp_
加上一个随机字符串开头。默认情况下,当 *Auto-sklearn* 对象完成拟合时,此目录会被删除。如果您想保留这些文件,可以将参数 delete_tmp_folder_after_terminate=True
传递给 *Auto-sklearn* 对象。
The autosklearn.classification.AutoSklearnClassifier
和所有其他 *auto-sklearn* 的 estimator 都接受参数 tmp_folder
,它改变了此类输出的写入位置。
还有一个额外的参数 output_directory
可以传递给 *Auto-sklearn*,它控制如果将测试集传递给 fit()
,集成模型的测试预测结果存储在哪里。
Auto-sklearn 的日志文件占满了我的磁盘空间。我该怎么办?
Auto-sklearn* 大量使用硬盘来存储临时数据、模型和日志文件,这些文件可用于检查 Auto-sklearn 的行为。默认情况下,*Auto-sklearn* 在硬盘上存储 50 个模型及其在验证数据上的预测结果(在 holdout 情况下是训练数据的子集,在交叉验证情况下是完整的训练数据)。冗余模型及其预测(即模型数量超过 50 个时)会在集成构建器完成每次迭代时被移除,这意味着如果在集成构建器运行时有模型输出,则存储在磁盘上的模型数量可能会暂时更高。
因此,可以通过向 *Auto-sklearn* 传递 max_models_on_disc
参数的整数值来改变存储在磁盘上的模型数量,例如,如果您遇到空间问题,可以减少存储在磁盘上的模型数量。
由于模型数量仅是已使用磁盘空间的指标,因此也可以将模型允许使用的内存(以 MB 为单位)作为 float
类型传递(同样通过 max_models_on_disc
参数)。如上所述,这更多是一个关于内存使用量的指导,因为冗余模型只有在集成构建器完成一次迭代时才从磁盘中移除。
注意
尤其是在并行运行时,可能在集成构建器的一次运行中构建多个模型,因此 *Auto-sklearn* 可能会超出给定的限制。
注意
这些限制仅适用于模型及其预测,不适用于临时目录中存储的其他文件,例如日志文件。
搜索空间¶
如何限制搜索空间?
下面展示了如何排除所有预处理方法并将配置空间限制为仅随机森林的示例。
import autosklearn.classification automl = autosklearn.classification.AutoSklearnClassifier( include = { 'classifier': ["random_forest"], 'feature_preprocessor': ["no_preprocessing"] }, exclude=None ) automl.fit(X_train, y_train) predictions = automl.predict(X_test)注意:用于标识 estimator 和 preprocessor 的字符串是文件名(不包含 .py)。
如需完整列表,请查看源代码(位于 autosklearn/pipeline/components/)
我们还提供了一个示例,说明如何将分类器限制为仅搜索可解释模型。
如何关闭数据预处理?
数据预处理包括分类特征的独热编码(One-Hot encoding)、缺失值填充(imputation)以及特征或样本的归一化(normalization)。这些步骤确保输入到 sklearn 模型的数据格式良好且可用于训练模型。
尽管这通常是必需的,但如果您想禁用此步骤,请参考此示例。
如何关闭特征预处理?
特征预处理是一个单独的转换器(transformer),它实现了例如特征选择或将特征转换到不同空间(例如 PCA)的功能。
可以通过设置 include={'feature_preprocessor'=["no_preprocessing"]}
来关闭,如上面的示例所示。
非 scikit-learn 模型会被添加到 Auto-sklearn 中吗?
简短的回答:不会。
更详细的回答则微妙一些:维护 Auto-sklearn 需要大量时间和精力,如果依赖更多库,工作量会更大。此外,添加更多库将要求我们更频繁地生成元数据。最后,更多的选择并不能保证大多数用户获得更好的性能,因为更多的选择需要更长的搜索时间来找到好的模型,并且可能导致过拟合。
然而,任何人仍然可以通过遵循如何扩展 Auto-sklearn 的示例,将他们喜欢的模型添加到 Auto-sklearn 的搜索空间中。
如果对创建包含第三方模型的 Auto-sklearn-contrib 仓库感兴趣,请为此提出一个 issue。
集成¶
关于集成构建过程,我能配置什么?
以下超参数控制集成的构建方式
ensemble_class
是一个实现了autosklearn.ensembles.AbstractEnsemble
的类对象,将由 auto-sklearn* 的集成构建器实例化。ensemble_kwargs
是在实例化ensemble_class
时传递的关键字参数。请参阅下面的示例参数。ensemble_nbest
允许用户直接指定集成中考虑的模型数量。此超参数可以是一个整数 n,这样最终集成中仅使用最佳的 n 个模型。如果提供的是一个介于 0.0 和 1.0 之间的浮点数,ensemble_nbest
将被解释为一个分数,表示在集成构建过程中使用的模型百分比(即,如果 ensemble_nbest 是浮点数,则库剪枝(library pruning)将按 Caruana 等人 (2006) 中描述的方式实现)。max_models_on_disc
定义了磁盘上保留的最大模型数量,作为控制 *auto-sklearn* 消耗的磁盘空间量的机制。在整个 automl 过程中,优化不同的个体模型,它们的预测(以及其他元数据)存储在磁盘上。用户可以设置可接受保留在磁盘上的模型数量上限,但此变量在集成构建器使用的模型数量定义中具有优先权(即,ensemble_size
、ensemble_nbest
和max_models_on_disc
的最小值决定了集成中使用的最大模型数量)。如果设置为 None,此功能将被禁用。
Auto-sklearn 的默认方法是 autosklearn.ensembles.EnsembleSelection
,它具有参数 ensemble_size
,该参数决定了集成的最大大小。模型可以重复添加,因此不同模型的数量通常小于 ensemble_size
。
最终集成中包含哪些模型?
通过调用 show_models()
或 leaderboard()
可以打印最终集成获得的结果。*auto-sklearn* 集成由 scikit-learn 模型组成,可以按照示例 获取运行信息 中所示进行检查。
我是否也可以只事后拟合集成?
可以事后构建集成。如何执行此操作(首先搜索单个模型,然后从它们构建集成)的示例可以在顺序使用中看到。
配置搜索过程¶
我可以改变重采样策略吗?
使用 holdout 和交叉验证的示例可以在示例中找到。
如果使用带有预定义分割的自定义重采样策略,您可能需要禁用对特别大的数据集执行的子采样(subsampling),或者在使用较小的 memory_limit
时禁用子采样。请参阅手册中关于资源限制的部分 AutoSklearnClassifier(dataset_compression=...)
,以获取更多详细信息。
我可以使用自定义指标吗
使用自定义指标的示例可以在示例中找到。
元学习¶
问题和调试¶
如何限制模型评估次数以进行调试?
在某些情况下,例如调试时,限制模型评估次数可能会有所帮助。我们在 API 中不提供此参数,因为我们认为在实践中不应使用它,而用户应该提供时间限制。有关如何将要尝试的模型数量添加为额外停止条件的示例可以在此 github issue 中找到。请注意,Auto-sklearn 将在达到时间限制或模型数量终止条件时停止。
为什么最终集成只包含一个 dummy 模型?
这是 Auto-sklearn 启动的所有运行都失败的问题症状。通常,问题在于运行时或内存限制设置得太紧。请检查 sprint_statistics()
的输出,查看运行失败的原因分布。如果大多数是崩溃的运行,请检查日志文件以获取更多详细信息。如果大多数是超出内存或时间限制的运行,请增加相应的限制并重新运行优化。
Auto-sklearn 没有使用指定的资源量?
Auto-sklearn 包装了 scikit-learn,因此继承了其并行性实现。简而言之,scikit-learn 使用两种模式来并行化计算:
通过使用 joblib 在多个核心上分发独立的函数调用。
通过使用 OpenMP 和 numpy 等底层库来分发更细粒度的计算。
这意味着 Auto-sklearn 可以使用比用户预期更多的资源。出于技术原因,我们只能控制第一种并行执行方式,而不能控制第二种。因此,用户需要确保底层并行化库仅使用分配的核心数(在运行单个 Auto-sklearn 副本的笔记本电脑或工作站上可能无需调整,但在使用计算集群时,需要将并行设置与请求的 CPU 数量对齐)。这可以通过设置以下环境变量来完成:MKL_NUM_THREADS
, OPENBLAS_NUM_THREADS
, BLIS_NUM_THREADS
和 OMP_NUM_THREADS
。
更多详细信息可在scikit-learn 文档中找到。
其他¶
模型持久化
auto-sklearn* 主要是一个包装 scikit-learn 的工具。因此,可以遵循 scikit-learn 的持久化示例。
Vanilla auto-sklearn
为了获得高效且稳健的自动化机器学习中使用的 *vanilla auto-sklearn*,请设置 ensemble_class=autosklearn.ensembles.SingleBest
和 initial_configurations_via_metalearning=0
import autosklearn.classification
import autosklearn.ensembles
automl = autosklearn.classification.AutoSklearnClassifier(
ensemble_class=autosklearn.ensembles.SingleBest,
initial_configurations_via_metalearning=0
)
这将始终根据验证集选择最佳模型。将通过元学习找到的初始配置设置为零,使 *auto-sklearn* 使用常规的 SMAC 算法来建议新的超参数配置。