当前位置:   article > 正文

AutoML综述_模型设计 算法选型

模型设计 算法选型

论文地址:https://arxiv.org/abs/1810.13306 。

AutoML出现原因

机器学习的应用需要大量的人工干预,这些人工干预表现在:特征提取、模型选择、参数调节等机器学习的各个方面。AutoML视图将这些与特征、模型、优化、评价有关的重要步骤进行自动化地学习,使得机器学习模型无需人工干预即可被应用。

使用AutoML 的好处

  • 市场潜力巨大:到根据Gartner 的数据,2022年,RPA相关的集成运用,将会以每年40%的速度增长。这是为什么这两年即使在资本市场降温的情况下,头部RPA公司例如Uipath, Automation Anywhere的估值一路飙升的原因。
  • 显著提高效率:数据分析有大量重复性的任务,这些任务可以使用AutoML的工具来完成,提高工作效率,让数据科学家可以将精力放在问题的思考,而不是模型实现。
  • 避免人为错误:之前公司的首席数据科学家提到,一个好的数据分析系统,就是要做到,“连猴子也能操作”。只要是人为操作的,就为错误埋下隐患。有些错误不会因此任何问题,但是有些也是致命的。例如,骑士资本集团(Knight Capital Group) 4 亿美元资产、日均交易额超过 210 亿美元的公司,在45分钟内破产的故事。就是因为一次失败的部署

AutoML问题定义

两个角度给出了定义:

  • 从机器学习角度讲,AutoML可以看作是一个在给定数据和任务上学习的泛化能力非常强大的系统。但是它强调必须非常容易使用。

  • 从自动化角度讲,AutoML则可以看作是设计一系列高级的控制系统去操作机器学习模型,使得模型可以自动化地学习到合适的参数和配置而无需人工干预。

一个通用的AutoML定义如下:

AutoML的核心任务:

 

  • Better performance
  • No human assistance
  • Lower computation budgets

目前 AutoML主要分为三类:

  • 自动参数调整(相对基本的类型)
  • 非深度学习的自动机器学习(如:AutoSKlearn)。此类型主要应用于数据预处理,自动特征分析,自动特征检测,自动特征选择和自动模型选择等。
  • 深度学习的自动机器学习(例如Auto-Keras)

AutoML问题构成

AutoML的主要问题可以由三部分构成:特征工程、模型选择、算法选择

特征工程

特征工程在机器学习中有着举足轻重的作用。在AutoML中,自动特征工程的目的是自动地发掘并构造相关的特征,使得模型可以有最优的表现。除此之外,还包含一些特定的特征增强方法,例如特征选择、特征降维、特征生成、以及特征编码等。这些步骤目前来说都没有达到自动化的阶段。

上述这些步骤也伴随着一定的参数搜索空间。第一种搜索空间是方法自带的,例如PCA自带降维参数需要调整。第二种是特征生成时会将搜索空间扩大。

模型选择

模型选择包括两个步骤:选择一个模型,设定它的参数。相应地,AutoML的目的就是自动选择出一个最合适的模型,并且能够设定好它的最优参数。

算法选择

对于算法选择,AutoML的目的是自动地选择出一个优化算法,以便能够达到效率和精度的平衡。常用的优化方法有SGD、L-BFGS、GD等。使用哪个优化算法、对应优化算法的配置,也需要一组搜索空间。

从全局看

将以上三个关键步骤整合起来看,一个完整的AutoML过程可以分成这么两类:一类是将以上的三个步骤整合成一个完整的pipeline;另一类则是network architecture search,能够自动地学习到最优的网络结构。在学习的过程中,对以上三个问题都进行一些优化。

基本的优化策略

一旦搜索空间确定,我们便可以实用优化器(optimizer)进行优化。这里,AutoML主要回答三个问题: - 选择的优化器可以作用在哪个搜索空间上? - 它需要什么样的反馈? - 为了取得一个好的效果,它需要怎样的配置?

简单的优化搜索方式包括grid search和random search。其中grid search被广泛使用。

从样本中进行优化的方法主要包括启发式搜索、derivative-free优化、以及强化学习方法。梯度下降法是一种重要的优化策略。

评价策略

基本评价策略

在设计评价策略时,AutoML主要回答三个问题: - 这种策略能能够快速进行评价吗? - 这种策略能够提供准确的评价吗? - 这种策略需要怎样的反馈?

基本的评价策略包括: - 直接评价。直接在目标数据上进行评价。这是被使用最多的策略。 - 采样。当数据样本量非常大时,采样一些样本进行评价。 - Early stop。当遇到一些极端情况使得网络表现效果不好时,可以考虑进行early stop。 - 参数重用。将之前学习过的参数重复利用在新任务上。这在两种任务配置差不多时可用。 - 共轭评价。对于一些可量化的配置,可以用共轭评价法进行。

高级评价策略

高级评价策略主要包括两种:meta-learning和transfer learning。

  • Meta-learning法。从先前的学习经验中提炼出基本的参数和结构配置。
  • Transfer learning法。从先前的学习经验中提炼出可以重用的一些知识。

常用Auto ML 框架

针对数据分析的不同步骤,已经有大量自动化框架。如果下图所示。这本文中,我们主要关注全流程自动化的框架,分别为:Auto_ml、Auto-SKLearn、TPOT、H2O AutoML、MLBox和ATM。

自动机器学习(AutoML):https://medium.com/georgian-impact-blog/automatic-machine-learning-aml-landscape-survey-f75c3ae3bbf2

特征工程

feature-tools

github地址:https://github.com/Featuretools/featuretools

Featuretools是由Feature Labs公布的开源项目。它擅长于将时间和关系数据集转换为机器学习的特征矩阵。

Featuretools使用一种称为深度特征综合(DFS)的算法,该算法可遍历通过关系数据库的架构描述的关系路径。当DFS遍历这些路径时,它会通过对数据进行运算来生成综合特征,包括求和,平均值和计数。

例如,它可以对来自给定客户ID的交易列表应用总和运算,将其聚合到一列中。虽然这是一项深度操作,但是该算法可以遍历更深层的功能。

pip安装

python -m pip install featuretools

Conda安装

conda install -c conda-forge featuretools

数据

处理的是关系数据集,它包括实体集(EntitySet)关系(Relationship)

实体集(EntitySet):是实体的集合,在FeatureTools一个关系表称为一个实体。

关系:在FeatureTools只描述一对多的关系,一所在的实体为父实体,多所在的实体为子实体,一个父亲可以有多个孩子。例如一个客户可以拥有多个会话,那么客户表就是会话表的父表。关系表示由子实体指向父实体。

下面以带时间戳的客户事务组成的关系数据集为例:

  1. >> import featuretools as ft
  2. >> es = ft.demo.load_mock_customer(return_entityset=True)
  3. >> es.plot()
  4. '''
  5. Entityset: transactions #实体集,数据集是关于客户事务的
  6. Entities: #实体,即四张表,包含实体名称及其表的行和列
  7. transactions [Rows: 500, Columns: 5] #会话的事件列表
  8. products [Rows: 5, Columns: 2] #产品及其关联属性,主键为product_id
  9. sessions [Rows: 35, Columns: 4] #会话及其关联属性,主键为session_id
  10. customers [Rows: 5, Columns: 4] #客户及其关联属性,主键为customer_id
  11. Relationships: #关系,一对多,子->父
  12. transactions.product_id -> products.product_id
  13. transactions.session_id -> sessions.session_id
  14. sessions.customer_id -> customers.customer_id
  15. 注:主键为能唯一地标识表中的每一行的一个列或者多列的组合,通过它可强制表的实体完整性。
  16. '''

DFS(Deep Feature Synthesis)

如果没有自动化的特性工程,数据科学家会编写代码来为客户聚合数据,并应用不同的统计功能(add,average,sum...)来量化客户的行为,工作量巨大。而DFS(深度特征合成)能够自动化这个过程,通过叠加聚合和转换操作来生成不同的深度特征让数据科学家更加直观地了解各种数据并加以选取,大大节省了数据科学家的时间。

DFS有三个关键概念:

  • 特征源于数据集中数据点之间的关系。
  • 对数据库或日志文件中常见的多表和事务数据集进行特征工程,这是因为这种数据格式是公司记录客户数据最常见的类型。
  • 在数据集中,许多特性都是通过使用类似的数学运算得到的。比如我们衡量一个客户的最大购买力需要对他所有的购买金额使用max操作,同样衡量一趟航班的最长延误时间。

注:翻译自Feature Labs

Primitives

DFS能对关系数据集进行各种数学运算并产生我们需要的新表,但是该如何操作才能使得新表的主键及其属性(特征)是我们所需的呢?为此,FeatureTools的dfs函数使用了特征原语(Feature primitives)

原语(primitives)定义了可应用于原始数据集以产生新Features的计算或操作(count,sum等),它只约束输入和输出数据类型,因此可以跨数据集应用。FeatureTools使用了两种类型的原语(Primitive)

  • Aggregation primitives:聚合操作。应用于实体集的父子关系中。例如 “count”, “sum”, “avg_time_between”,需要聚合父子表的特征。以下面的示例为例子,count首先找到客户表(target entity)的客户id,然后根据数据中的关系找到它的子表session,然后计算子表同一客户id的session有多少个,从而生成新的特征。
  • Transform primitives:转换操作。将一个实体的一个或多个变量作为输入,并为该实体输出一个新变量,应用于单个实体,例如:“hour”、“time_since_precious”、“absolute”。同样以下面的例子为例,对于客户表中,只要涉及到有月份的特征,都将它的月份提取出来形成新的特征,新特征是从原表中产生的。

示例

  1. feature_matrix, feature_defs = ft.dfs(entityset=es,
  2. target_entity="customers",
  3. agg_primitives=["count"],
  4. trans_primitives=["month"])
  5. '''
  6. customer_id zip_code COUNT(sessions) MONTH(join_date) MONTH(date_of_birth)
  7. 5 60091 6 7 7
  8. 4 60091 8 4 8
  9. 1 60091 8 4 7
  10. 3 13244 6 8 11
  11. 2 13244 7 4 8
  12. '''

FeatureTools的dfs函数定义了:

  • 处理的数据集对象:entityset
  • 生成新表的主键的来源target_entity
  • Aggregation primitives、Transform primitives

处理时间

当数据科学家想要对时间数据进行特征工程的时候,选取哪一时间段的数据用于计算至关重要。Featuretools 标注了时间索引的实体提供了截取(cutoff) 操作,从而使得它能在计算之前自动地过滤在在设定的截取时间以后的数据。

接下来解释一下时间索引(time index) 和 截取时间(cutoff time)

时间索引(time index):表示表中一行被知道或者发生的时间。例如,对于session表,那么session发生的时间即为它的时间索引,能够用于特征合成。而对于客户表,它可能含有生日以及加入的日期(join date),那么加入日期是时间索引,因为它表示了客户首次在数据集中可用的时间。

截取时间(cutoff time):指定行数据可用于特征计算的最后一个时间点。在此时间点之后的任何数据都将在特征计算或者操作之前过滤掉。

注:时间索引在截取时间后面的行将自动忽略。

示例

预测客户1, 2, 3 在 2014-1-1 04:00 以后会不会做某事,用参数cutoff_time过滤 2014-1-1 04:00以后的数据,同时我们还能设置要使用到截取时间前多长时间内的数据,即时间窗,参数为training_window,以两小时为例:

  1. fm, features = ft.dfs(entityset=es,
  2. target_entity='customers',
  3. cutoff_time=pd.Timestamp("2014-1-1 04:00"),
  4. cutoff_time_in_index=True,
  5. training_window="2 hour")

有些数据不仅涉及到时间点,还涉及到时间段。比如一个session能涉及到多个事务,而每个事务的发生时间不一样,有时候session的start time在时间窗之前,但是涉及的事务有在时间窗的。因此Featuretools提供了EntitySet.add_last_time_indexes() 让session表增加了最后发生时间的特征。从而能够找到了在时间窗内所有有关的实体。

boruta-py

github地址:https://github.com/scikit-learn-contrib/boruta_py

boruta_py项目提供了全相关特征选择算法boruta的python实现方式。

是brouta特征缩减策略的一种实现,其中,以“所有相关”的方式来描述,从而算法保留了对模型有重大贡献的所有特征。这与许多特征缩减算法的“最小最佳”特征集不同。它会尝试查找所有带有可用于预测的信息的特征,而不是查找某个分类器误差最小的可能紧凑的特征子集。

boruta方法通过创建一个由目标特征的随机重排序值组成的合成特征来确定特征重要性,然后在原始特征集和目标特征被合成特征替换的特征集上训练一个基于树的简单分类器。
对比性能差异来衡量特征的相对重要性。

算法步骤

  • 创建阴影特征 (shadow feature) : 对每个真实特征R,随机打乱顺序,得到阴影特征矩阵S,拼接到真实特征后面,构成新的特征矩阵N = [R, S].
  • 用新的特征矩阵N作为输入,训练模型,能输出feature_importances_的模型,如RandomForest, lightgbm,xgboost都可以,得到真实特征和阴影特征的feature importances,
  • 取阴影特征feature importance的最大值S_max,真实特征中feature importance大于S_max的,记录一次命中。
  • 用(3)中记录的真实特征累计命中,标记特征重要或不重要。
  • 删除不重要的特征,重复1-4,直到所有特征都被标记。

pip安装

pip install Boruta

Conda安装

conda install -c conda-forge boruta_py

Examples

这个项目模拟scikit-learn接口,因此使用fit、transform 或 fit_tansform 来进行特征选择。

  1. import pandas as pd
  2. from sklearn.ensemble import RandomForestClassifier
  3. from boruta import BorutaPy
  4. # 导入数据
  5. X = pd.read_csv('examples/test_X.csv', index_col=0).values
  6. y = pd.read_csv('examples/test_y.csv', header=None, index_col=0).values
  7. y = y.ravel()
  8. # 定义随机森林分类器
  9. rf = RandomForestClassifier(n_jobs=-1, class_weight='balanced', max_depth=5)
  10. # 设置 Boruta 特征选择的参数
  11. feat_selector = BorutaPy(rf, n_estimators='auto', verbose=2, random_state=1)
  12. # 发现所有相关的特征-5个特征会被选择
  13. feat_selector.fit(X, y)
  14. # 查看前五个选择的特征
  15. feat_selector.support_
  16. # 查看选择的特征的rank
  17. feat_selector.ranking_
  18. # 用 transform() 过滤掉数据x不相关的特征
  19. X_filtered = feat_selector.transform(X)

输出示例

训练结束后,可以输出特征ranking_,表示特征的重要性等级,在特征选择中也是一个很有用的指标。

  1. feat_selector.fit(X, y)
  2. # 拟合的一些信息
  3. '''
  4. BorutaPy finished running.
  5. Iteration: 13 / 100
  6. Confirmed: 5
  7. Tentative: 0
  8. Rejected: 5
  9. BorutaPy(alpha=0.05,
  10. estimator=RandomForestClassifier(bootstrap=True, class_weight='balanced',
  11. criterion='gini', max_depth=5, max_features='auto',
  12. max_leaf_nodes=None, min_impurity_decrease=0.0,
  13. min_impurity_split=None, min_samples_leaf=1,
  14. min_samples_split=2, min_weight_fraction_leaf=0.0,
  15. n_estimators=74, n_jobs=-1, oob_score=False,
  16. random_state=RandomState(MT19937) at 0x226811D5DB0, verbose=0,
  17. warm_start=False),
  18. max_iter=100, n_estimators='auto', perc=100,
  19. random_state=RandomState(MT19937) at 0x226811D5DB0, two_step=True,
  20. verbose=2)
  21. '''
  22. feat_selector.support_
  23. '''
  24. array([ True, True, True, True, True, False, False, False, False, False]) # 筛选后的特征,False代表滤除掉此特征
  25. '''
  26. feat_selector.ranking_
  27. '''
  28. array([1, 1, 1, 1, 1, 2, 4, 6, 3, 5]) # 越高代表越重要
  29. '''
  30. # 用 transform() 过滤掉数据x不相关的特征
  31. X_filtered = feat_selector.transform(X)
  32. '''
  33. array([[ 0. , -0.05193964, -2.0362205 , 0.61377086, 0. ],
  34. [ 1. , 0.58291516, 1.04749347, 1.37545586, 1. ],
  35. [ 1. , 0.72640099, 0.75092816, 1.16757011, 1. ],
  36. ...,
  37. [ 0. , -0.15821768, -2.20124347, 1.27271473, 1. ],
  38. [ 1. , 0.5848914 , -0.99888891, -0.16948063, 2. ],
  39. [ 0. , -0.05607609, 0.03402959, -0.72097011, 0. ]])
  40. '''

categorical-encoding

github地址:https://github.com/scikit-learn-contrib/category_encoders

该软件包扩展了许多分类编码方法,这些方法实现了scikit-learn数据转换接口,支持的输入格式包括numpy数组和pandas数据框。

包括以下15种编码方法,这些编码的功能、参数定义以及属性由官网知悉。

  • Backward Difference Coding
  • BaseN
  • Binary
  • CatBoost Encoder
  • Hashing
  • Helmert Coding
  • James-Stein Encoder
  • Leave One Out
  • M-estimate
  • One Hot
  • Ordinal
  • Polynomial Coding
  • Sum Coding
  • Target Encoder
  • Weight of Evidence

pip安装

pip install category_encoders

Conda安装

conda install -c conda-forge category_encoders

使用示例

  1. import category_encoders as ce
  2. encoder = ce.BackwardDifferenceEncoder(cols=[...])
  3. encoder = ce.BaseNEncoder(cols=[...])
  4. encoder = ce.BinaryEncoder(cols=[...])
  5. encoder = ce.CatBoostEncoder(cols=[...])
  6. encoder = ce.HashingEncoder(cols=[...])
  7. encoder = ce.HelmertEncoder(cols=[...])
  8. encoder = ce.JamesSteinEncoder(cols=[...])
  9. encoder = ce.LeaveOneOutEncoder(cols=[...])
  10. encoder = ce.MEstimateEncoder(cols=[...])
  11. encoder = ce.OneHotEncoder(cols=[...])
  12. encoder = ce.OrdinalEncoder(cols=[...])
  13. encoder = ce.SumEncoder(cols=[...])
  14. encoder = ce.PolynomialEncoder(cols=[...])
  15. encoder = ce.TargetEncoder(cols=[...])
  16. encoder = ce.WOEEncoder(cols=[...])
  17. encoder.fit(X, y)
  18. X_cleaned = encoder.transform(X_dirty)

一个无监督的例子:

  1. from category_encoders import *
  2. import pandas as pd
  3. from sklearn.datasets import load_boston
  4. # prepare some data
  5. bunch = load_boston()
  6. y = bunch.target
  7. X = pd.DataFrame(bunch.data, columns=bunch.feature_names)
  8. # use binary encoding to encode two categorical features
  9. enc = BinaryEncoder(cols=['CHAS', 'RAD']).fit(X)
  10. # transform the dataset
  11. numeric_dataset = enc.transform(X)

有监督的示例:

  1. from category_encoders import *
  2. import pandas as pd
  3. from sklearn.datasets import load_boston
  4. # prepare some data
  5. bunch = load_boston()
  6. y_train = bunch.target[0:250]
  7. y_test = bunch.target[250:506]
  8. X_train = pd.DataFrame(bunch.data[0:250], columns=bunch.feature_names)
  9. X_test = pd.DataFrame(bunch.data[250:506], columns=bunch.feature_names)
  10. # use target encoding to encode two categorical features
  11. enc = TargetEncoder(cols=['CHAS', 'RAD'])
  12. # transform the datasets
  13. training_numeric_dataset = enc.fit_transform(X_train, y_train)
  14. testing_numeric_dataset = enc.transform(X_test)

tsfresh

github地址:https://github.com/blue-yonder/tsfresh

该库专注于根据时间序列数据生成特征。tsfresh还与pandas和sklearn兼容。

TSFRESH自动从时间序列中提取100多个特征。这些特征描述了时间序列的基本特征,例如峰值数量,平均值或最大值,或更复杂的特征(例如时间反向对称统计量)。同时通过假设检验来将特征消减到最能解释趋势的特征,称为去相关性。然后,可以使用这些特征集在时间序列上构造统计或机器学习模型,例如在回归或分类任务中使用。

安装

pip install tsfresh

示例

给定一个机器人故障的数据集,其中每个机器人记录六个不同传感器的时间序列。

任务是:对于每个由不同id表示的样本,我们将对机器人是否报告故障进行分类。从机器学习的角度来看,我们的目标是对每组时间序列进行分类

  1. # 导入数据
  2. from tsfresh.examples.robot_execution_failures import download_robot_execution_failures, load_robot_execution_failures
  3. download_robot_execution_failures()
  4. timeseries, y = load_robot_execution_failures()
  5. print(timeseries.head())
  6. '''
  7. id time F_x F_y F_z T_x T_y T_z
  8. 0 1 0 -1 -1 63 -3 -1 0
  9. 1 1 1 0 0 62 -3 -1 0
  10. 2 1 2 -1 -1 61 -3 0 0
  11. 3 1 3 -1 -1 63 -2 -1 0
  12. 4 1 4 -1 -1 63 -3 -1 0
  13. '''
  14. # 第一列是数据表索引,没有任何意义。对于不同的传感器有六个不同的时间序列(a-f)。不同的机器人由id列表示。
  15. print(y) # 0代表没有故障
  16. '''
  17. 1 0
  18. 2 0
  19. 3 0
  20. 4 0
  21. 5 0
  22. '''
  23. # 提取所有特征
  24. from tsfresh import extract_features
  25. extracted_features = extract_features(timeseries, column_id="id", column_sort="time")
  26. # 最终得到一个数据表extracted_features,其中包含所有超过1200个不同的提取特性。
  27. # 我们现在将删除所有NaN值(由特征计算器创建的值,不能用于给定的数据,例如,因为它的统计量太低),然后只选择相关的特征:
  28. from tsfresh import select_features # 导入数据包
  29. from tsfresh.utilities.dataframe_functions import impute
  30. impute(extracted_features)
  31. features_filtered = select_features(extracted_features, y) # 选择特征
  32. # 最终只会剩余大约300个特征被分类为足够相关。

Trane

github地址:https://github.com/HDI-Project/Trane

Trane是一个软件包,用于自动生成预测问题并生成用于监督学习的标签。

在数据科学中,人们通常有一个实体的一些记录,并且想要预测这个实体将来会发生什么。Trane的设计目的是生成与时间相关的预测问题。Trane将数据元信息转换为相关预测问题和截止时间的列表。截断时间定义为用于训练分类器的数据中的最后时间。截断时间后的数据用于评价分类器的准确性。截断时间对于防止分类器训练测试数据是必要的。

对于每个预测问题,Trane输出(实体,截止量,标签)的元组。将预测问题应用于实体数据以生成标签。来自Trane的数据可以直接输入到功能工具中以执行功能工程。

安装

pip install Trane

在Trane中,我们使用四种操作生成预测问题:

  • 过滤操作(Filter Operations)
  • 行操作 (Row Operations)
  • 转换操作 (Transformation Operations)
  • 聚合操作 (Aggregation Operations)
    过滤器操作应用于过滤行。而行、转换和聚合操作应用于产生标签。

工作流程

  • 数据科学家写一个meta.json来描述新数据库中的列和数据类型。
  • PredictionProblemGenerator读取metadata并生成可能的预测问题。预测问题保存为problems.json。
  • 数据科学家可以修改problems.json中的预测问题的参数。
  • labeler对数据应用problems.json中的预测问题。

使用示例

这里下载一个合成的出租车数据集。解压该文件并获得包含原始数据synthetic_taxi_data.csv和表元数据taxi_meta.json的文件夹。将taxi_data文件夹放在Trane中,或者在下面的单元格中设置正确的路径。

生成预测问题

  1. # 首先导入Trane和其他软件包,设置数据路径和其他参数。
  2. import trane
  3. import json
  4. multiple_csv = ["taxi_data/synthetic_taxi_data.csv"] # csv数据路径
  5. table_meta_json = "taxi_data/taxi_meta.json" # metadata路径
  6. entity_id_column = 'taxi_id' # Trane将在entity_id_column中为每个实体生成一个标签。
  7. label_generating_column = 'fare' # Trane将使用label_generating_column中的数据来生成labels.
  8. time_column = 'trip_id' # 用于截止时间(cutoff time)的time_column.
  9. # 加载metadata,然后创建一个PredictionProblemGenerator。
  10. table_meta = trane.TableMeta(json.loads(open(table_meta_json).read()))
  11. generator = trane.PredictionProblemGenerator(table_meta, entity_id_column, label_generating_column, time_column)
  12. # 使用生成器生成3个预测问题。
  13. probs = []
  14. for idx, prob in enumerate(generator.generate()):
  15. probs.append(prob)
  16. if idx + 1 == 3:
  17. break
  18. # 将预测问题保存到prediction_problems.json中
  19. prediction_problems_json = trane.prediction_problems_to_json_file(probs, table_meta, entity_id_column, label_generating_column, time_column, "prediction_problems.json")
  20. trane.generate_nl_description(probs, table_meta, entity_id_column, label_generating_column, time_column, trane.ConstantIntegerCutoffTimes(0))

结果

  1. ['For each taxi_id, predict the first fare, after trip_id 0.',
  2. 'For each taxi_id, predict the first fare, after trip_id 0.',
  3. 'For each taxi_id, predict the first fare, after trip_id 0.']

加载问题并生成标签

  1. denormalized_dataframe = trane.csv_to_df(multiple_csv)
  2. entity_to_data_dict = trane.df_group_by_entity_id(denormalized_dataframe, entity_id_column)
  3. print(entity_to_data_dict[0].head(5))

结果

  1. vendor_id taxi_id trip_id distance duration fare num_passengers
  2. 0 0 0 0 4.97 16.53 46.80 3
  3. 1 0 0 1 6.00 16.82 49.60 4
  4. 2 0 0 2 0.68 11.70 27.87 1
  5. 3 0 0 3 7.75 11.69 43.12 1
  6. 4 0 0 4 6.05 13.32 42.71 4

采用cutoff策略。简单地使用固定的切断时间。所有实体的截止时间为0。

  1. entity_to_data_and_cutoff_dict = trane.ConstantIntegerCutoffTimes(0).generate_cutoffs(entity_to_data_dict)
  2. # 创建一个标签器并生成标签。
  3. labeler = trane.Labeler()
  4. output = labeler.execute(entity_to_data_and_cutoff_dict, "prediction_problems.json")
  5. print(output)

输出三个问题的标签,在上面的生成当中,三个问题一样(可人为调整内容),即在第一趟以后预测下一趟的收费。

  1. {0: ([49.6, 49.6, 49.6], 0),
  2. 1: ([20.45, 20.45, 20.45], 0),
  3. 2: ([61.6, 61.6, 61.6], 0),
  4. 3: ([58.52, 58.52, 58.52], 0),
  5. 4: ([42.1, 42.1, 42.1], 0),
  6. 5: ([58.66, 58.66, 58.66], 0),
  7. 6: ([34.5, 34.5, 34.5], 0),
  8. 7: ([34.05, 34.05, 34.05], 0),
  9. 8: ([54.3, 54.3, 54.3], 0),
  10. 9: ([44.55, 44.55, 44.55], 0),
  11. 10: ([62.88, 62.88, 62.88], 0),
  12. ...}

最终会获得生成的预测问题的对应的标签!

FeatureHub

github地址:https://github.com/HDI-Project/FeatureHub

超参数优化器

Skopt

官方文档:https://scikit-optimize.github.io/stable/auto_examples/hyperparameter-optimization.html

Skopt是超参数优化实现的库,包括随机搜索,贝叶斯搜索,决策林和梯度提升树。该软件包包含经过充分研究和可靠的优化方法,但是,这些模型在较小的搜索空间和良好的初始估计的情况下表现最佳。

下面给出了优化SVC(支持向量机分类器)的超参数的最小示例。

  1. from skopt import BayesSearchCV
  2. from sklearn.datasets import load_digits
  3. from sklearn.svm import SVC
  4. from sklearn.model_selection import train_test_split
  5. X, y = load_digits(10, True)
  6. X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.75, test_size=.25, random_state=0)
  7. # log-uniform: understand as search over p = exp(x) by varying x
  8. opt = BayesSearchCV(
  9. SVC(),
  10. {
  11. 'C': (1e-6, 1e+6, 'log-uniform'),
  12. 'gamma': (1e-6, 1e+1, 'log-uniform'),
  13. 'degree': (1, 8), # integer valued parameter
  14. 'kernel': ['linear', 'poly', 'rbf'], # categorical parameter
  15. },
  16. n_iter=32,
  17. cv=3
  18. )
  19. opt.fit(X_train, y_train)
  20. print("val. score: %s" % opt.best_score_)
  21. print("test score: %s" % opt.score(X_test, y_test))
  22. '''
  23. val. score: 0.991833704528582
  24. test score: 0.9933333333333333
  25. '''

Hyperopt

github地址:https://github.com/hyperopt/hyperopt-sklearn

Komer B., Bergstra J., and Eliasmith C. "Hyperopt-Sklearn: automatic hyperparameter configuration for Scikit-learn" Proc. SciPy 2014. http://conference.scipy.org/proceedings/scipy2014/pdfs/komer.pdf

Hyperopt是一个超参数优化库,针对难处理的条件或约束搜索空间进行了调整,其中包括随机搜索和parzen估计树等算法。

该库由hyperopt-sklearn和hyperas实现,这两个模型选择和优化库分别基于scikit-learn和keras构建。

使用Iris数据集的完整例子。

  1. from hpsklearn import HyperoptEstimator, any_classifier, any_preprocessing
  2. from sklearn.datasets import load_iris
  3. from hyperopt import tpe
  4. import numpy as np
  5. # Download the data and split into training and test sets
  6. iris = load_iris()
  7. X = iris.data
  8. y = iris.target
  9. test_size = int(0.2 * len(y))
  10. np.random.seed(13)
  11. indices = np.random.permutation(len(X))
  12. X_train = X[indices[:-test_size]]
  13. y_train = y[indices[:-test_size]]
  14. X_test = X[indices[-test_size:]]
  15. y_test = y[indices[-test_size:]]
  16. # Instantiate a HyperoptEstimator with the search space and number of evaluations
  17. estim = HyperoptEstimator(classifier=any_classifier('my_clf'),
  18. preprocessing=any_preprocessing('my_pre'),
  19. algo=tpe.suggest,
  20. max_evals=100,
  21. trial_timeout=120)
  22. # Search the hyperparameter space based on the data
  23. estim.fit(X_train, y_train)
  24. # Show the results
  25. print(estim.score(X_test, y_test))
  26. # 1.0
  27. print(estim.best_model())
  28. '''
  29. {'learner': ExtraTreesClassifier(bootstrap=False, class_weight=None, criterion='gini',
  30. max_depth=3, max_features='log2', max_leaf_nodes=None,
  31. min_impurity_decrease=0.0, min_impurity_split=None,
  32. min_samples_leaf=1, min_samples_split=2,
  33. min_weight_fraction_leaf=0.0, n_estimators=13, n_jobs=1,
  34. oob_score=False, random_state=1, verbose=False,
  35. warm_start=False), 'preprocs': (), 'ex_preprocs': ()}
  36. '''

simple(x)

github地址:https://github.com/chrisstroemel/Simple

 Simple(x)是一个优化库,实现了贝叶斯优化的算法替代方案。像贝叶斯搜索一样,simple(x)尝试使用尽可能少的样本数进行优化,但同时也将计算复杂度从n³降低到log(n),使其对大型搜索空间极为有用。

Wu,Ozdamar和Kumar于2005年首次提出了一种使用局部简化插值和双重细分进行优化的方法。

该库使用单纯形(n维三角形)代替搜索超多维数据集(n维多维数据集)来对搜索空间建模,从而避免了贝叶斯优化所使用的计算量大的高斯过程。

通过将全局优化问题转换为动态规划问题,Simple在贝叶斯优化上实现了如此巨大的加速。

  1. from Simple import SimpleTuner
  2. objective_function = lambda vector: -((vector[0] - 0.2) ** 2.0 + (vector[1] - 0.3) ** 2.0) ** 0.5
  3. optimization_domain_vertices = [[0.0, 0.0], [0, 1.0], [1.0, 0.0]]
  4. number_of_iterations = 30
  5. exploration = 0.05 # optional, default 0.15
  6. tuner = SimpleTuner(optimization_domain_vertices, objective_function, exploration_preference=exploration)
  7. tuner.optimize(number_of_iterations)
  8. best_objective_value, best_coords = tuner.get_best()
  9. print('Best objective value ', best_objective_value)
  10. print('Found at sample coords ', best_coords)
  11. tuner.plot() # only works in 2D
  12. # The resulting output is then:
  13. '''  
  14. Best objective value -0.00823447695587
  15. Found at sample coords [ 0.19285289 0.29591033]
  16. '''

Ray.tune

github地址:https://github.com/ray-project/ray/tree/master/python/ray/tune

Paper:https://arxiv.org/abs/1807.05118

Ray.tune是一个超参数优化库,主要针对深度学习和强化学习模型。它结合了许多最先进的算法,些都在Ray分布式计算平台上运行,这使其具有极大的可扩展性。

Chocolate

官方文档:https://medium.com/georgian-impact-blog/automatic-machine-learning-aml-landscape-survey-f75c3ae3bbf2

Chocolate是一个完全异步的(支持并行运行的计算集群)超参数优化库,该库使用公共数据库来联合执行各个任务。它支持网格搜索,随机搜索,准随机搜索,贝叶斯搜索和协方差矩阵适应进化策略。它的独特功能包括对受限搜索空间的支持以及优化多个损失函数(多个目标优化)。

  1. import chocolate as choco
  2. def objective_function(condition, x=None, y=None):
  3. """An objective function returning ``1 - x`` when *condition* is 1 and
  4. ``y - 6`` when *condition* is 2.
  5. Raises:
  6. ValueError: If condition is different than 1 or 2.
  7. """
  8. if condition == 1:
  9. return 1 - x
  10. elif condition == 2:
  11. return y - 6
  12. raise ValueError("condition must be 1 or 2, got {}.".format(condition))
  13. # Define the conditional search space
  14. space = [
  15. {"condition": 1, "x": choco.uniform(low=1, high=10)},
  16. {"condition": 2, "y": choco.log(low=-2, high=2, base=10)}
  17. ]
  18. # Establish a connection to a SQLite local database
  19. conn = choco.SQLiteConnection("sqlite:///my_db.db")
  20. # Construct the optimizer
  21. sampler = choco.Bayes(conn, space)
  22. # Sample the next point
  23. token, params = sampler.next()
  24. # Calculate the loss for the sampled point (minimized)
  25. loss = objective_function(**params)
  26. # Add the loss to the database
  27. sampler.update(token, loss)

GpFlowOpt

GPflowOpt是使用GPflow进行贝叶斯优化的,并使用Tensorflow在GPU上运行高斯过程任务的库。如果需要贝叶斯优化并且GPU计算资源可用,这使GpFlowOpt成为理想的优化器。

FAR-HO

FAR-HO是一个库,其中包含一组在tensorflow上运行的基于梯度的优化器,其中包括Reverse-HG和Forward-HG。

基于TensorFlow的基于梯度的超参数优化,实现了本文 基于正向和反向梯度的超参数优化中介绍的算法

该库的目的是在Tensorflow中实施基于梯度的超参数优化技术,从而允许在GPU或其他针对深度学习模型进行张量优化的计算环境中进行模型训练和超参数优化。

  1. import far_ho as far
  2. import tensorflow as tf
  3. model = create_model(...)
  4. lambda1 = far.get_hyperparameter('lambda1', ...)
  5. lambda1 = far.get_hyperparameter('lambda2', ...)
  6. io, oo = create_objective(...)
  7. inner_problem_optimizer = far.GradientDescentOptimizer(lr=far.get_hyperparameter('lr', 0.1))
  8. outer_problem_optimizer = tf.train.AdamOptimizer()
  9. farho = far.HyperOptimizer()
  10. ho_step = farho.minimize(oo, outer_problem_optimizer,
  11. io, inner_problem_optimizer)
  12. T = 100
  13. with tf.Session().as_default():
  14. for _ in range(100):
  15. ho_step(T)

Xcessiv

github地址:https://github.com/reiinakano/xcessiv

Xcessiv是用于大规模模型开发,执行和集成的框架。它的强大功能来自于在单个GUI中管理大量机器学习模型的训练,执行和评估的能力。它还具有用于组合这些模型的多个集成工具,以实现最佳性能。它包含一个贝叶斯搜索参数优化器,该优化器支持高度的并行性,还支持与TPOT集成。

HORD

github地址:https://github.com/ilija139/HORD

HORD是用于超参数优化的独立算法(动态坐标搜索)。HORD通过动态坐标搜索为黑盒模型生成替代函数,并使用该函数生成可能接近理想值的“理想的”超参数,以减少对完整模型的评估。与parzen估计器,SMAC和高斯过程树相比,它更具一致性和低错误率。

ENAS-pytorch

github地址:https://github.com/carpedm20/ENAS-pytorch

Paperhttps://arxiv.org/abs/1802.03268

 ENAS-pytorch在pytorch中实现了有效的神经体系结构搜索,以进行深度学习。它使用参数共享来最快地实现最高效的网络,使其适合于深度学习架构搜索。

全自动化Pipeline

1. Auto_ml

第一个框架是auto_ml。这个框架是为项目的生产环境设计的,功能涉及整个机器学习过程的自动化,具体包括:

  • 变量分析: 导入数据,auto_ml会分析变量之间的关系;
  • 特征工程:特别是针对日期;
  • 数据稳健性处理:在考虑数据异常值和矩阵稀缺性的情况下,将变量值转换为0到1范围;
  • 特征选择:仅保留有实际作用的变量;
  • 数据格式化:将字典转换为稀疏矩阵,对分类变量进行独热编码(one-hot encoding),对回归变量取对数;
  • 模型选择:选择针对问题的最优模型;
  • 超参数优化:选择适合模型的超参;
  • 组合次预测器:自动训练模型以预测元问题中的较小问题;
  • 整合弱训练器:训练弱模型并组合到一起;

使用例子

  1. # 数据导入
  2. from auto_ml import Predictor
  3. from auto_ml.utils import get_boston_dataset
  4. df_train, df_test = get_boston_dataset() # 样本数据如下图所示
  5. column_descriptions = {
  6. 'MEDV': 'output',
  7. 'CHAS': 'categorical'} # 说明MEDV为因变量,CHAS为类别数据

  1. ml_predictor = Predictor(type_of_estimator='regressor', column_descriptions=column_descriptions)
  2. ml_predictor.train(df_train) # 按照官方文档模式的参数设置进行训练

默认的方法为:GradientBoostingRegressor,同时,也给了关于变量的一些分析结果。例如,Importance :GradientBoostingRegressor中feature importance, 说明每个自变量对MEDV的变动的解释程度。

 

 

调整参数,我们可以在这个基础上做一些调整,包括 perform_feature_selection(只保留贡献率最大的变量),改变模型为'RandomForestRegressor'(默认为GradientBoostingRegressor),将cross-validation 改为 10-fold。

  1. ml_predictor.train(df_train,perform_feature_selection=True,cv=10,model_names='RandomForestRegressor')
  2. ml_predictor.train(df_train,perform_feature_selection=True,cv=10,model_names='RandomForestRegressor')

结果如下,可以看到,现在模型为'RandomForestRegressor',而且,只保留了10个贡献率最大的特征,不是'GradientBoostingRegressor'中14个特征全部保留。

 

最后,我们可以使用测试集来计算各种关键的得分

ml_predictor.score(df_test, df_test.MEDV)

 

 

2. Auto-SKLearn

Auto-Sklearn是基于sklearn的一个自动机器学习框架,可支撑分类和回归问题的分析。Auto-Sklearn 的核心思想是组合算法选择和超参数优化(CASH: Combined Algorithm Selection and Hyperparameter optimization):同时考虑学习算法以及算法的超参选择。Auto-Sklearn的分析步骤如下:在数据导入后,加上一个元学习步骤(meta-learning);在模型训练后,通过贝叶斯方法更新数据处理和特征选择;最终,在模型训练完成之后,将模型进行组合(build ensemble)以得到最优的估计。

 

Auto-Sklearn包含两个主模块:

  • 分类任务(autosklearn.classification.AutoSklearnClassifier(...))
  • 回归任务(autosklearn.regression.AutoSklearnRegressor(...))

使用例子

  1. import autosklearn.classification
  2. import sklearn.model_selection
  3. import sklearn.datasets
  4. import sklearn.metrics
  5. X, y = sklearn.datasets.load_digits(return_X_y=True)
  6. X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(X, y, random_state=1)
  7. automl = autosklearn.classification.AutoSklearnClassifier()
  8. automl.fit(X_train, y_train)
  9. y_hat = automl.predict(X_test)

3. TPOT

 

TPOT定位为数据科学的助手,完成最终模型分析前很多繁杂的工作。使用的是遗传编程的技术。遗传编程与传统机器学习的区别:机器学习主要是在一个参数空间上,通过调整参数获得最佳的预测结果,重点在找参数。遗传编程可以理解为一个能构造算法的算法,重点在找算法。

所以,基于遗传编程,我们就比较好理解TPOT官方文档的说明,如下图,TPOT其实就是在寻找一个最优的路径,从原始数据,到数据清洗,特征工程,模型选址,参数最优化,模型验证,中间可以有各自各样的组合。TPOT是帮助数据科学家找出最优的一条路径。当然,在TPOT中,除了寻找出最优的算法,也会给出最优的参数。

 

使用例子

同样使用波士顿房价的例子:

  1. from tpot import TPOTRegressor
  2. from sklearn.datasets import load_boston
  3. from sklearn.model_selection import train_test_split
  4. housing = load_boston()
  5. X_train, X_test, y_train, y_test = train_test_split(housing.data, housing.target, train_size=0.75, test_size=0.25, random_state=42)
  6. tpot = TPOTRegressor(generations=5, population_size=50, verbosity=2, random_state=42)
  7. tpot.fit(X_train, y_train)

运行上面的代码,结果如下,TPOT会产生选出最优的过程:LassoLarsCV。

 

  1. # 将模型导出:这会生成一个python的脚本
  2. tpot.export('tpot_boston_pipeline.py')

脚本如下:

 

这已经完成了模型分析前大量的探索的工作。现在需要做的,就是对这个脚本做一个简单的编辑,就可以完成最终的模型训练了。

4. H2O AutoML

H2O.ai是美国的一个AI创业公司。为客户提供自动化模型整合、训练以及部署的服务。2019年8月份刚获得高盛和平安领投7250万美金的投资。

AutoML是H2O其中的一项功能。AutoML可自动构建大量模型,在无需任何知识背景的情况下,挑选出最佳的模型支持R和Python。

使用例子(h2o通过接口的数据请求总是有问题!)

  1. import h2o
  2. from h2o.automl import H2OAutoML, get_leaderboard
  3. h2o.init()
  4. # Import a sample binary outcome train/test set into H2O
  5. train = h2o.import_file("https://s3.amazonaws.com/erin-data/higgs/higgs_train_10k.csv")
  6. test = h2o.import_file("https://s3.amazonaws.com/erin-data/higgs/higgs_test_5k.csv")
  7. # Identify predictors and response
  8. x = train.columns
  9. y = "response"
  10. x.remove(y)
  11. # For binary classification, response should be a factor
  12. train[y] = train[y].asfactor()
  13. test[y] = test[y].asfactor()
  14. # Run AutoML for 20 base models (limited to 1 hour max runtime by default)
  15. aml = H2OAutoML(max_models=20, seed=1)
  16. aml.train(x=x, y=y, training_frame=train)
  17. # AutoML Leaderboard
  18. lb = aml.leaderboard
  19. # Optionally edd extra model information to the leaderboard
  20. lb = get_leaderboard(aml, extra_columns='ALL')
  21. # 获取所有的模型排名
  22. lb.head(rows=lb.nrows)

使用最优模型进行预测

  1. # 使用最优的模型进行预测
  2. preds = aml.predict(test)
  3. # 或者
  4. preds = aml.leader.predict(test)

5. Auto-Keras

最后,我们介绍一下开源的自动深度学习框架:AutoKeras。Auto-Keras是一个基于Keras的自动学习框架,由Texas A&M的Data Lab开发。AutoKeras是一个出色的开源项目,具备很多开源项目的特点:快速安装,易于运行,示例众多,易于修改等等。

  1. # 导入数据深度学习的'hello world'数据,mnist,手写数字数据(非常的慢)
  2. from tensorflow.keras.datasets import mnist
  3. (x_train, y_train), (x_test, y_test) = mnist.load_data()

训练模型

  1. import autokeras as ak
  2. # Initialize the image classifier.
  3. clf = ak.ImageClassifier(max_trials=1) # It tries 10 different models.
  4. # Feed the image classifier with training data.
  5. clf.fit(x_train, y_train,epochs=3)

使用最终的模型进行预测

  1. # Predict with the best model.
  2. predicted_y = clf.predict(x_test)
  3. print(predicted_y)

 


参考:

分享一篇比较全面的AutoML综述 - 知乎:https://zhuanlan.zhihu.com/p/48642938

【一文读懂】自动化机器学习(Auto ML) - 知乎:https://zhuanlan.zhihu.com/p/113433660

萝萝 - 知乎:https://www.zhihu.com/people/kong-ya-jing-61/posts

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/741871
推荐阅读
相关标签
  

闽ICP备14008679号