使用 Auto-sklearn 开启自动机器学习之旅

2020-05-20 15:12:32 浏览数 (1)

AutoML 之 Auto-sklearn

0AutoML 定义

首先我们来为自动机器学习 AutoML 下一个定义,

定义1 自动机器学习 AutoML: 对于 ,令 表示特征向量, 表示对应的目标值。给定训练数据集

和从与之具有相同数据分布中得出的测试数据集

的特征向量 ,以及资源预算 和损失度量 ,AutoML 问题是自动生成测试集的预测值 ,而 给出了 AutoML 问题的解 的损失值。

使用过 sklearn 的话,对于上面定义应该不难理解。下面再结合一个流程图来进一步理解一下。

Auto-sklearn 改进了一般的 AutoML 方法。自动机器学习框架采用贝叶斯超参数优化方法,这里另外添加了两个组件: 一个用于初始化贝叶斯优化器的元学习(meta-learning)以及优化过程中的自动集成(automated ensemble)方法。

这种元学习方法是贝叶斯优化的补充,用于优化 ML 框架。对于像整个 ML 框架一样大的超参数空间,贝叶斯优化的启动速度很慢。通过基于元学习选择若干个配置来用于种子贝叶斯优化。这种通过元学习的方法可以称为热启动优化方法。再配合多个模型的自动集成方法,使得整个机器学习流程高度自动化,将大大节省用户的时间。从这个流程来看,让机器学习使用者可以有更多的时间来选择数据以及思考要处理的问题本身。

1Auto-sklearn

1Auto-sklearn 简介

Auto-sklearn 提供了开箱即用的监督型自动机器学习。从名字可以看出,auto-sklearn 是基于机器学习库 scikit-learn 构建的,可为新的数据集自动搜索学习算法,并优化其超参数。因此,它将机器学习使用者从繁琐的任务中解放出来,使其有更多时间专注于实际问题。当前版本为 0.6.0,具体信息请查看官网 https://automl.github.io/auto-sklearn/master/。不管官方介绍怎么写,还是实际拿出来溜溜看看效果。

2 安 装

下面展示的是 ubuntu 下的安装步骤,其他操作系统请参考官方网页说明 https://automl.github.io/auto-sklearn/master/installation.html

  • sudo apt-get install build-essential swig
  • conda install gxx_linux-64 gcc_linux-64 swig
  • curl https://raw.githubusercontent.com/automl/auto-sklearn/master/requirements.txt | xargs -n 1 -L 1 pip install
  • pip install auto-sklearn

3 上 手

下面我们来牛刀小试,从回归和分类两个问题来看一下实际使用效果。

2回归问题

以下示例展示了如何使用 Auto-sklearn 来拟合简单的回归模型。

代码语言:javascript复制
import sklearn.model_selection
import sklearn.datasets
import sklearn.metrics

from sklearn.svm import SVR
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestClassifier

import autosklearn.regression

def main():
    X, y = sklearn.datasets.load_boston(return_X_y=True)
    feature_types = (['numerical'] <em> 3)   ['categorical']   (['numerical'] </em> 9)
    X_train, X_test, y_train, y_test = 
        sklearn.model_selection.train_test_split(X, y, random_state=1)

    automl = autosklearn.regression.AutoSklearnRegressor(
        time_left_for_this_task=120,
        per_run_time_limit=30,
        tmp_folder='/tmp/autosklearn_regression_example_tmp',
        output_folder='/tmp/autosklearn_regression_example_out',
    )
    
    automl.fit(X_train, y_train, dataset_name='boston', feat_type=feature_types)

    # print(automl.show_models())
    predictions = automl.predict(X_test)
    print("R2 score:", sklearn.metrics.r2_score(y_test, predictions))

    # 用于比较
    decision = DecisionTreeRegressor()
    svr = SVR()
    rf = RandomForestClassifier(n_estimators = 1000)
    
    decision.fit(X_train, y_train)
    svr.fit(X_train, y_train)
    rf.fit(X_train, y_train.astype('int'))
    
    y_pred_decision = decision.predict(X_test)
    y_pred_svr      =      svr.predict(X_test)
    y_pred_rf       =       rf.predict(X_test)
    
    decision_score = r2_score(y_test, y_pred_decision)
    svr_score      = r2_score(y_test, y_pred_svr)
    rf_score       = r2_score(y_test, y_pred_rf)    

    print("R2 scores of DecisionTree and SRV:", decision_score, svr_score, rf_score) 
    
if __name__ == '__main__':
    main()
代码语言:javascript复制
R2 score: 0.8693107119499301
R2 scores of DecisionTree and SRV: 0.831926997052514 0.1827742886561753 0.7781347015948009

最后看到的是可以评估回归模型优劣的决定系数 R2 score。如果 表示第 个样本的预测值, 是对应的真实值, 被定义为:

其中 。最佳可能得分为1.0,并且可能为负(因为模型可能会任意地差)。上面分数显示,自动搜索的模型比决策树和SVR的分数都要高。

3分类问题

auto-sklearn 中,可以通过指定参数 resampling_strategyresampling_strategy_arguments 来使用不同的重采样策略。以下示例展示了 AutoSklearnClassifier 结合交叉验证(cross validation)在 sklearn 自带的乳腺癌数据集上的自动机器学习。

代码语言:javascript复制
import sklearn.model_selection
import sklearn.datasets
import sklearn.metrics

import autosklearn.classification

def main():
    X, y = sklearn.datasets.load_breast_cancer(return_X_y=True)
    X_train, X_test, y_train, y_test = 
        sklearn.model_selection.train_test_split(X, y, random_state=1)

    automl = autosklearn.classification.AutoSklearnClassifier(
        time_left_for_this_task=120,
        per_run_time_limit=30,
        tmp_folder='/tmp/autosklearn_cv_example_tmp',
        output_folder='/tmp/autosklearn_cv_example_out',
        delete_tmp_folder_after_terminate=False,
        resampling_strategy='cv',
        resampling_strategy_arguments={'folds': 5},
    )

    # fit() changes the data in place, but refit needs the original data. We
    # therefore copy the data. In practice, one should reload the data
    automl.fit(X_train.copy(), y_train.copy(), dataset_name='breast_cancer')
    # During fit(), models are fit on individual cross-validation folds. To use
    # all available data, we call refit() which trains all models in the
    # final ensemble on the whole dataset.
    automl.refit(X_train.copy(), y_train.copy())

    print(automl.show_models())

    predictions = automl.predict(X_test)
    print("Accuracy score", sklearn.metrics.accuracy_score(y_test, predictions))


if __name__ == '__main__':
    main()
代码语言:javascript复制
[(0.560000, SimpleClassificationPipeline({'balancing:strategy': 'none', 'categorical_encoding:__choice__': 'one_hot_encoding', 'classifier:__choice__': 'sgd', 'imputation:strategy': 'most_frequent', 'preprocessor:__choice__': 'nystroem_sampler', 'rescaling:__choice__': 'minmax', 'categorical_encoding:one_hot_encoding:use_minimum_fraction': 'False', 'classifier:sgd:alpha': 5.6261158385241367e-05, 'classifier:sgd:average': 'True', 'classifier:sgd:fit_intercept': 'True', 'classifier:sgd:learning_rate': 'constant', 'classifier:sgd:loss': 'perceptron', 'classifier:sgd:penalty': 'elasticnet', 'classifier:sgd:tol': 0.00010235984698480301, 'preprocessor:nystroem_sampler:kernel': 'poly', 'preprocessor:nystroem_sampler:n_components': 67, 'classifier:sgd:eta0': 1.051932200415674e-05, 'classifier:sgd:l1_ratio': 3.0712276747159755e-08, 'preprocessor:nystroem_sampler:coef0': -0.5748850260339962, 'preprocessor:nystroem_sampler:degree': 2, 'preprocessor:nystroem_sampler:gamma': 1.0340462502787229},
dataset_properties={
  'task': 1,
  'sparse': False,
  'multilabel': False,
  'multiclass': False,
  'target_type': 'classification',
  'signed': False})),
(0.440000, SimpleClassificationPipeline({'balancing:strategy': 'weighting', 'categorical_encoding:__choice__': 'one_hot_encoding', 'classifier:__choice__': 'sgd', 'imputation:strategy': 'median', 'preprocessor:__choice__': 'kitchen_sinks', 'rescaling:__choice__': 'standardize', 'categorical_encoding:one_hot_encoding:use_minimum_fraction': 'False', 'classifier:sgd:alpha': 9.178145146151305e-07, 'classifier:sgd:average': 'True', 'classifier:sgd:fit_intercept': 'True', 'classifier:sgd:learning_rate': 'invscaling', 'classifier:sgd:loss': 'log', 'classifier:sgd:penalty': 'l1', 'classifier:sgd:tol': 0.049852803596082323, 'preprocessor:kitchen_sinks:gamma': 0.5276624227374054, 'preprocessor:kitchen_sinks:n_components': 835, 'classifier:sgd:eta0': 4.250999546641075e-05, 'classifier:sgd:power_t': 0.8657935257645124},
dataset_properties={
  'task': 1,
  'sparse': False,
  'multilabel': False,
  'multiclass': False,
  'target_type': 'classification',
  'signed': False})),
]
Accuracy score 0.958041958041958

4用户手册简介

4用户手册地址

下面我们从几个方面来解读一下用户手册 https://automl.github.io/auto-sklearn/master/manual.html#manual

5时间和内存限制

auto-sklearn的一个关键功能是限制允许scikit-learn算法使用的资源(内存和时间)。特别是对于大型数据集(算法可能需要花费几个小时并进行机器交换),重要的是要在一段时间后停止评估,以便在合理的时间内取得进展。因此,设置资源限制是优化时间和可以测试的模型数量之间的权衡。

尽管auto-sklearn减轻了手动超参数调整的速度,但用户仍然必须设置内存和时间限制。对于大多数数据集而言,大多数现代计算机上的3GB或6GB内存限制已足够。对于时间限制,很难给出明确的指导原则。如果可能的话,一个很好的默认值是总时限为一天,单次运行时限为30分钟。

可以在auto-sklearn/issues/142中找到更多准则。

6限制搜索空间

除了使用所有可用的估计器外,还可以限制 auto-sklearn 的搜索空间。下面示例展示了如何排除所有预处理方法并将配置空间限制为仅使用随机森林

代码语言:javascript复制
import autosklearn.classification

automl = autosklearn.classification.AutoSklearnClassifier(
    include_estimators=["random_forest", ], exclude_estimators=None,
    include_preprocessors=["no_preprocessing", ], exclude_preprocessors=None)

automl.fit(X_train, y_train)
predictions = automl.predict(X_test)

注意: 用于标识估计器和预处理器的字符串是不带 .py 的文件名。

7关闭预处理

auto-sklearn 中的预处理分为数据预处理和特征预处理。数据预处理包括分类特征的独热编码,缺失值插补以及特征或样本的归一化。这些步骤目前无法关闭。特征预处理是单个特征变换器,可实现例如特征选择或将特征变换到不同空间(如PCA)。如上例所示,特征预处理可以通过设置include_preprocessors=["no_preprocessing"] 将其关闭。

8重采样策略

可以在 auto-sklearn/examples/ 中找到使用维持数据集和交叉验证的示例。

9结果检查

auto-sklearn 允许用户检查训练的结果和产看相关的统计信息。以下示例展示了如何打印不同的统计信息以进行相应检查。

代码语言:javascript复制
import autosklearn.classification

automl = autosklearn.classification.AutoSklearnClassifier()

automl.fit(X_train, y_train)

automl.cv_results_
automl.sprint_statistics()
automl.show_models()
  • cv_results_ 返回一个字典,其中的键作为列标题,值作为列,可以将其导入到 pandas 的一个 DataFrame 类型数据中。
  • sprint_statistics() 可以打印出数据集名称、使用的度量以及通过运行 auto-sklearn 获得的最佳验证分数。此外,它还会打印成功和不成功算法的运行次数。
  • 通过调用 show_models(),可以打印最终集成模型产生的结果。

10并行计算

auto-sklearn支持通过共享文件系统上的数据共享来并行执行。在这种模式下,SMAC算法通过在每次迭代后将其训练数据写入磁盘来共享其模型的训练数据。在每次迭代的开始,SMAC都会加载所有新发现的数据点。我们提供了一个实现scikit-learn的n_jobs功能的示例,以及一个有关如何手动启动多个auto-sklearn实例的示例。

在默认模式下,auto-sklearn已使用两个核心。第一个用于模型构建,第二个用于在每次新的机器学习模型完成训练后构建整体。序列示例显示了如何以一次仅使用一个内核的方式顺序运行这些任务。

此外,根据scikit-learn和numpy的安装,模型构建过程最多可以使用所有内核。这种行为是auto-sklearn所不希望的,并且很可能是由于从pypi安装了numpy作为二进制轮子(请参见此处)。执行export OPENBLAS_NUM_THREADS=1应该禁用这种行为,并使numpy一次仅使用一个内核。

11Vanilla auto-sklearn

auto-sklearn 主要是基于 scikit-learn 的封装。因此,可以遵循 scikit-learn 中的持久化示例。

为了获得在资料 Efficient and Robust Automated Machine Learning 中使用的 vanilla auto-sklearn,设置ensemble_size = 1initial_configurations_via_metalearning=0

代码语言:javascript复制
import autosklearn.classification

automl = autosklearn.classification.AutoSklearnClassifier(
    ensemble_size=1, initial_configurations_via_metalearning=0)

集成的大小设为 1 将导致始终选择在验证集上的测试性能最佳的单一模型。将初始配置的元学习设置为 0,将使得 auto-sklearn 使用常规的 SMAC 算法来设置新的超参数配置。

好了,上面是对 auto-sklearn 的简单介绍,下次我们将会使用 auto-sklearn 实战,尽情期待。

0 人点赞