赞
踩
论文地址:https://arxiv.org/abs/1810.13306 。
机器学习的应用需要大量的人工干预,这些人工干预表现在:特征提取、模型选择、参数调节等机器学习的各个方面。AutoML视图将这些与特征、模型、优化、评价有关的重要步骤进行自动化地学习,使得机器学习模型无需人工干预即可被应用。
两个角度给出了定义:
一个通用的AutoML定义如下:
AutoML的核心任务:
目前 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。
针对数据分析的不同步骤,已经有大量自动化框架。如果下图所示。这本文中,我们主要关注全流程自动化的框架,分别为: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的交易列表应用总和运算,将其聚合到一列中。虽然这是一项深度操作,但是该算法可以遍历更深层的功能。
python -m pip install featuretools
conda install -c conda-forge featuretools
处理的是关系数据集,它包括实体集(EntitySet)和关系(Relationship)。
实体集(EntitySet):是实体的集合,在FeatureTools一个关系表称为一个实体。
关系:在FeatureTools只描述一对多的关系,一所在的实体为父实体,多所在的实体为子实体,一个父亲可以有多个孩子。例如一个客户可以拥有多个会话,那么客户表就是会话表的父表。关系表示由子实体指向父实体。
下面以带时间戳的客户事务组成的关系数据集为例:
- >> import featuretools as ft
- >> es = ft.demo.load_mock_customer(return_entityset=True)
- >> es.plot()
- '''
- Entityset: transactions #实体集,数据集是关于客户事务的
- Entities: #实体,即四张表,包含实体名称及其表的行和列
- transactions [Rows: 500, Columns: 5] #会话的事件列表
- products [Rows: 5, Columns: 2] #产品及其关联属性,主键为product_id
- sessions [Rows: 35, Columns: 4] #会话及其关联属性,主键为session_id
- customers [Rows: 5, Columns: 4] #客户及其关联属性,主键为customer_id
- Relationships: #关系,一对多,子->父
- transactions.product_id -> products.product_id
- transactions.session_id -> sessions.session_id
- sessions.customer_id -> customers.customer_id
- 注:主键为能唯一地标识表中的每一行的一个列或者多列的组合,通过它可强制表的实体完整性。
- '''
如果没有自动化的特性工程,数据科学家会编写代码来为客户聚合数据,并应用不同的统计功能(add,average,sum...)来量化客户的行为,工作量巨大。而DFS(深度特征合成)能够自动化这个过程,通过叠加聚合和转换操作来生成不同的深度特征让数据科学家更加直观地了解各种数据并加以选取,大大节省了数据科学家的时间。
DFS有三个关键概念:
注:翻译自Feature Labs。
Primitives
DFS能对关系数据集进行各种数学运算并产生我们需要的新表,但是该如何操作才能使得新表的主键及其属性(特征)是我们所需的呢?为此,FeatureTools的dfs函数使用了特征原语(Feature primitives)。
原语(primitives)定义了可应用于原始数据集以产生新Features的计算或操作(count,sum等),它只约束输入和输出数据类型,因此可以跨数据集应用。FeatureTools使用了两种类型的原语(Primitive):
示例
- feature_matrix, feature_defs = ft.dfs(entityset=es,
- target_entity="customers",
- agg_primitives=["count"],
- trans_primitives=["month"])
- '''
- customer_id zip_code COUNT(sessions) MONTH(join_date) MONTH(date_of_birth)
- 5 60091 6 7 7
- 4 60091 8 4 8
- 1 60091 8 4 7
- 3 13244 6 8 11
- 2 13244 7 4 8
- '''
FeatureTools的dfs函数定义了:
当数据科学家想要对时间数据进行特征工程的时候,选取哪一时间段的数据用于计算至关重要。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,以两小时为例:
- fm, features = ft.dfs(entityset=es,
- target_entity='customers',
- cutoff_time=pd.Timestamp("2014-1-1 04:00"),
- cutoff_time_in_index=True,
- 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方法通过创建一个由目标特征的随机重排序值组成的合成特征来确定特征重要性,然后在原始特征集和目标特征被合成特征替换的特征集上训练一个基于树的简单分类器。
对比性能差异来衡量特征的相对重要性。
pip install Boruta
conda install -c conda-forge boruta_py
这个项目模拟scikit-learn接口,因此使用fit、transform 或 fit_tansform 来进行特征选择。
- import pandas as pd
- from sklearn.ensemble import RandomForestClassifier
- from boruta import BorutaPy
-
- # 导入数据
- X = pd.read_csv('examples/test_X.csv', index_col=0).values
- y = pd.read_csv('examples/test_y.csv', header=None, index_col=0).values
- y = y.ravel()
-
- # 定义随机森林分类器
- rf = RandomForestClassifier(n_jobs=-1, class_weight='balanced', max_depth=5)
-
- # 设置 Boruta 特征选择的参数
- feat_selector = BorutaPy(rf, n_estimators='auto', verbose=2, random_state=1)
-
- # 发现所有相关的特征-5个特征会被选择
- feat_selector.fit(X, y)
-
- # 查看前五个选择的特征
- feat_selector.support_
-
- # 查看选择的特征的rank
- feat_selector.ranking_
-
- # 用 transform() 过滤掉数据x不相关的特征
- X_filtered = feat_selector.transform(X)
训练结束后,可以输出特征ranking_,表示特征的重要性等级,在特征选择中也是一个很有用的指标。
- feat_selector.fit(X, y)
- # 拟合的一些信息
- '''
- BorutaPy finished running.
- Iteration: 13 / 100
- Confirmed: 5
- Tentative: 0
- Rejected: 5
- BorutaPy(alpha=0.05,
- estimator=RandomForestClassifier(bootstrap=True, class_weight='balanced',
- criterion='gini', max_depth=5, max_features='auto',
- max_leaf_nodes=None, min_impurity_decrease=0.0,
- min_impurity_split=None, min_samples_leaf=1,
- min_samples_split=2, min_weight_fraction_leaf=0.0,
- n_estimators=74, n_jobs=-1, oob_score=False,
- random_state=RandomState(MT19937) at 0x226811D5DB0, verbose=0,
- warm_start=False),
- max_iter=100, n_estimators='auto', perc=100,
- random_state=RandomState(MT19937) at 0x226811D5DB0, two_step=True,
- verbose=2)
- '''
- feat_selector.support_
- '''
- array([ True, True, True, True, True, False, False, False, False, False]) # 筛选后的特征,False代表滤除掉此特征
- '''
- feat_selector.ranking_
- '''
- array([1, 1, 1, 1, 1, 2, 4, 6, 3, 5]) # 越高代表越重要
- '''
- # 用 transform() 过滤掉数据x不相关的特征
- X_filtered = feat_selector.transform(X)
- '''
- array([[ 0. , -0.05193964, -2.0362205 , 0.61377086, 0. ],
- [ 1. , 0.58291516, 1.04749347, 1.37545586, 1. ],
- [ 1. , 0.72640099, 0.75092816, 1.16757011, 1. ],
- ...,
- [ 0. , -0.15821768, -2.20124347, 1.27271473, 1. ],
- [ 1. , 0.5848914 , -0.99888891, -0.16948063, 2. ],
- [ 0. , -0.05607609, 0.03402959, -0.72097011, 0. ]])
- '''
categorical-encoding
github地址:https://github.com/scikit-learn-contrib/category_encoders
该软件包扩展了许多分类编码方法,这些方法实现了scikit-learn数据转换接口,支持的输入格式包括numpy数组和pandas数据框。
包括以下15种编码方法,这些编码的功能、参数定义以及属性由官网知悉。
pip install category_encoders
conda install -c conda-forge category_encoders
- import category_encoders as ce
-
- encoder = ce.BackwardDifferenceEncoder(cols=[...])
- encoder = ce.BaseNEncoder(cols=[...])
- encoder = ce.BinaryEncoder(cols=[...])
- encoder = ce.CatBoostEncoder(cols=[...])
- encoder = ce.HashingEncoder(cols=[...])
- encoder = ce.HelmertEncoder(cols=[...])
- encoder = ce.JamesSteinEncoder(cols=[...])
- encoder = ce.LeaveOneOutEncoder(cols=[...])
- encoder = ce.MEstimateEncoder(cols=[...])
- encoder = ce.OneHotEncoder(cols=[...])
- encoder = ce.OrdinalEncoder(cols=[...])
- encoder = ce.SumEncoder(cols=[...])
- encoder = ce.PolynomialEncoder(cols=[...])
- encoder = ce.TargetEncoder(cols=[...])
- encoder = ce.WOEEncoder(cols=[...])
-
- encoder.fit(X, y)
- X_cleaned = encoder.transform(X_dirty)
一个无监督的例子:
- from category_encoders import *
- import pandas as pd
- from sklearn.datasets import load_boston
-
- # prepare some data
- bunch = load_boston()
- y = bunch.target
- X = pd.DataFrame(bunch.data, columns=bunch.feature_names)
-
- # use binary encoding to encode two categorical features
- enc = BinaryEncoder(cols=['CHAS', 'RAD']).fit(X)
-
- # transform the dataset
- numeric_dataset = enc.transform(X)
有监督的示例:
- from category_encoders import *
- import pandas as pd
- from sklearn.datasets import load_boston
-
- # prepare some data
- bunch = load_boston()
- y_train = bunch.target[0:250]
- y_test = bunch.target[250:506]
- X_train = pd.DataFrame(bunch.data[0:250], columns=bunch.feature_names)
- X_test = pd.DataFrame(bunch.data[250:506], columns=bunch.feature_names)
-
- # use target encoding to encode two categorical features
- enc = TargetEncoder(cols=['CHAS', 'RAD'])
-
- # transform the datasets
- training_numeric_dataset = enc.fit_transform(X_train, y_train)
- testing_numeric_dataset = enc.transform(X_test)
tsfresh
github地址:https://github.com/blue-yonder/tsfresh
该库专注于根据时间序列数据生成特征。tsfresh还与pandas和sklearn兼容。
TSFRESH自动从时间序列中提取100多个特征。这些特征描述了时间序列的基本特征,例如峰值数量,平均值或最大值,或更复杂的特征(例如时间反向对称统计量)。同时通过假设检验来将特征消减到最能解释趋势的特征,称为去相关性。然后,可以使用这些特征集在时间序列上构造统计或机器学习模型,例如在回归或分类任务中使用。
pip install tsfresh
给定一个机器人故障的数据集,其中每个机器人记录六个不同传感器的时间序列。
任务是:对于每个由不同id表示的样本,我们将对机器人是否报告故障进行分类。从机器学习的角度来看,我们的目标是对每组时间序列进行分类
- # 导入数据
- from tsfresh.examples.robot_execution_failures import download_robot_execution_failures, load_robot_execution_failures
- download_robot_execution_failures()
- timeseries, y = load_robot_execution_failures()
- print(timeseries.head())
- '''
- id time F_x F_y F_z T_x T_y T_z
- 0 1 0 -1 -1 63 -3 -1 0
- 1 1 1 0 0 62 -3 -1 0
- 2 1 2 -1 -1 61 -3 0 0
- 3 1 3 -1 -1 63 -2 -1 0
- 4 1 4 -1 -1 63 -3 -1 0
- '''
- # 第一列是数据表索引,没有任何意义。对于不同的传感器有六个不同的时间序列(a-f)。不同的机器人由id列表示。
- print(y) # 0代表没有故障
- '''
- 1 0
- 2 0
- 3 0
- 4 0
- 5 0
- '''
- # 提取所有特征
- from tsfresh import extract_features
- extracted_features = extract_features(timeseries, column_id="id", column_sort="time")
-
- # 最终得到一个数据表extracted_features,其中包含所有超过1200个不同的提取特性。
- # 我们现在将删除所有NaN值(由特征计算器创建的值,不能用于给定的数据,例如,因为它的统计量太低),然后只选择相关的特征:
- from tsfresh import select_features # 导入数据包
- from tsfresh.utilities.dataframe_functions import impute
-
- impute(extracted_features)
- features_filtered = select_features(extracted_features, y) # 选择特征
- # 最终只会剩余大约300个特征被分类为足够相关。
Trane
github地址:https://github.com/HDI-Project/Trane
Trane是一个软件包,用于自动生成预测问题并生成用于监督学习的标签。
在数据科学中,人们通常有一个实体的一些记录,并且想要预测这个实体将来会发生什么。Trane的设计目的是生成与时间相关的预测问题。Trane将数据元信息转换为相关预测问题和截止时间的列表。截断时间定义为用于训练分类器的数据中的最后时间。截断时间后的数据用于评价分类器的准确性。截断时间对于防止分类器训练测试数据是必要的。
对于每个预测问题,Trane输出(实体,截止量,标签)的元组。将预测问题应用于实体数据以生成标签。来自Trane的数据可以直接输入到功能工具中以执行功能工程。
pip install Trane
在这里下载一个合成的出租车数据集。解压该文件并获得包含原始数据synthetic_taxi_data.csv和表元数据taxi_meta.json的文件夹。将taxi_data文件夹放在Trane中,或者在下面的单元格中设置正确的路径。
- # 首先导入Trane和其他软件包,设置数据路径和其他参数。
- import trane
- import json
-
- multiple_csv = ["taxi_data/synthetic_taxi_data.csv"] # csv数据路径
- table_meta_json = "taxi_data/taxi_meta.json" # metadata路径
-
- entity_id_column = 'taxi_id' # Trane将在entity_id_column中为每个实体生成一个标签。
- label_generating_column = 'fare' # Trane将使用label_generating_column中的数据来生成labels.
- time_column = 'trip_id' # 用于截止时间(cutoff time)的time_column.
- # 加载metadata,然后创建一个PredictionProblemGenerator。
- table_meta = trane.TableMeta(json.loads(open(table_meta_json).read()))
- generator = trane.PredictionProblemGenerator(table_meta, entity_id_column, label_generating_column, time_column)
- # 使用生成器生成3个预测问题。
- probs = []
- for idx, prob in enumerate(generator.generate()):
- probs.append(prob)
- if idx + 1 == 3:
- break
- # 将预测问题保存到prediction_problems.json中
- prediction_problems_json = trane.prediction_problems_to_json_file(probs, table_meta, entity_id_column, label_generating_column, time_column, "prediction_problems.json")
- trane.generate_nl_description(probs, table_meta, entity_id_column, label_generating_column, time_column, trane.ConstantIntegerCutoffTimes(0))
结果
- ['For each taxi_id, predict the first fare, after trip_id 0.',
- 'For each taxi_id, predict the first fare, after trip_id 0.',
- 'For each taxi_id, predict the first fare, after trip_id 0.']
加载问题并生成标签
- denormalized_dataframe = trane.csv_to_df(multiple_csv)
- entity_to_data_dict = trane.df_group_by_entity_id(denormalized_dataframe, entity_id_column)
- print(entity_to_data_dict[0].head(5))
结果
- vendor_id taxi_id trip_id distance duration fare num_passengers
- 0 0 0 0 4.97 16.53 46.80 3
- 1 0 0 1 6.00 16.82 49.60 4
- 2 0 0 2 0.68 11.70 27.87 1
- 3 0 0 3 7.75 11.69 43.12 1
- 4 0 0 4 6.05 13.32 42.71 4
采用cutoff策略。简单地使用固定的切断时间。所有实体的截止时间为0。
- entity_to_data_and_cutoff_dict = trane.ConstantIntegerCutoffTimes(0).generate_cutoffs(entity_to_data_dict)
- # 创建一个标签器并生成标签。
- labeler = trane.Labeler()
- output = labeler.execute(entity_to_data_and_cutoff_dict, "prediction_problems.json")
- print(output)
输出三个问题的标签,在上面的生成当中,三个问题一样(可人为调整内容),即在第一趟以后预测下一趟的收费。
- {0: ([49.6, 49.6, 49.6], 0),
- 1: ([20.45, 20.45, 20.45], 0),
- 2: ([61.6, 61.6, 61.6], 0),
- 3: ([58.52, 58.52, 58.52], 0),
- 4: ([42.1, 42.1, 42.1], 0),
- 5: ([58.66, 58.66, 58.66], 0),
- 6: ([34.5, 34.5, 34.5], 0),
- 7: ([34.05, 34.05, 34.05], 0),
- 8: ([54.3, 54.3, 54.3], 0),
- 9: ([44.55, 44.55, 44.55], 0),
- 10: ([62.88, 62.88, 62.88], 0),
- ...}
最终会获得生成的预测问题的对应的标签!
FeatureHub
github地址:https://github.com/HDI-Project/FeatureHub
Skopt
官方文档:https://scikit-optimize.github.io/stable/auto_examples/hyperparameter-optimization.html
Skopt是超参数优化实现的库,包括随机搜索,贝叶斯搜索,决策林和梯度提升树。该软件包包含经过充分研究和可靠的优化方法,但是,这些模型在较小的搜索空间和良好的初始估计的情况下表现最佳。
下面给出了优化SVC(支持向量机分类器)的超参数的最小示例。
- from skopt import BayesSearchCV
- from sklearn.datasets import load_digits
- from sklearn.svm import SVC
- from sklearn.model_selection import train_test_split
-
- X, y = load_digits(10, True)
- X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.75, test_size=.25, random_state=0)
-
- # log-uniform: understand as search over p = exp(x) by varying x
- opt = BayesSearchCV(
- SVC(),
- {
- 'C': (1e-6, 1e+6, 'log-uniform'),
- 'gamma': (1e-6, 1e+1, 'log-uniform'),
- 'degree': (1, 8), # integer valued parameter
- 'kernel': ['linear', 'poly', 'rbf'], # categorical parameter
- },
- n_iter=32,
- cv=3
- )
-
- opt.fit(X_train, y_train)
- print("val. score: %s" % opt.best_score_)
- print("test score: %s" % opt.score(X_test, y_test))
- '''
- val. score: 0.991833704528582
- test score: 0.9933333333333333
- '''
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数据集的完整例子。
- from hpsklearn import HyperoptEstimator, any_classifier, any_preprocessing
- from sklearn.datasets import load_iris
- from hyperopt import tpe
- import numpy as np
-
- # Download the data and split into training and test sets
- iris = load_iris()
-
- X = iris.data
- y = iris.target
-
- test_size = int(0.2 * len(y))
- np.random.seed(13)
- indices = np.random.permutation(len(X))
- X_train = X[indices[:-test_size]]
- y_train = y[indices[:-test_size]]
- X_test = X[indices[-test_size:]]
- y_test = y[indices[-test_size:]]
- # Instantiate a HyperoptEstimator with the search space and number of evaluations
- estim = HyperoptEstimator(classifier=any_classifier('my_clf'),
- preprocessing=any_preprocessing('my_pre'),
- algo=tpe.suggest,
- max_evals=100,
- trial_timeout=120)
- # Search the hyperparameter space based on the data
- estim.fit(X_train, y_train)
- # Show the results
- print(estim.score(X_test, y_test))
- # 1.0
- print(estim.best_model())
- '''
- {'learner': ExtraTreesClassifier(bootstrap=False, class_weight=None, criterion='gini',
- max_depth=3, max_features='log2', max_leaf_nodes=None,
- min_impurity_decrease=0.0, min_impurity_split=None,
- min_samples_leaf=1, min_samples_split=2,
- min_weight_fraction_leaf=0.0, n_estimators=13, n_jobs=1,
- oob_score=False, random_state=1, verbose=False,
- warm_start=False), 'preprocs': (), 'ex_preprocs': ()}
- '''
simple(x)
github地址:https://github.com/chrisstroemel/Simple
Simple(x)是一个优化库,实现了贝叶斯优化的算法替代方案。像贝叶斯搜索一样,simple(x)尝试使用尽可能少的样本数进行优化,但同时也将计算复杂度从n³降低到log(n),使其对大型搜索空间极为有用。
Wu,Ozdamar和Kumar于2005年首次提出了一种使用局部简化插值和双重细分进行优化的方法。
该库使用单纯形(n维三角形)代替搜索超多维数据集(n维多维数据集)来对搜索空间建模,从而避免了贝叶斯优化所使用的计算量大的高斯过程。
通过将全局优化问题转换为动态规划问题,Simple在贝叶斯优化上实现了如此巨大的加速。
- from Simple import SimpleTuner
-
- objective_function = lambda vector: -((vector[0] - 0.2) ** 2.0 + (vector[1] - 0.3) ** 2.0) ** 0.5
- optimization_domain_vertices = [[0.0, 0.0], [0, 1.0], [1.0, 0.0]]
- number_of_iterations = 30
- exploration = 0.05 # optional, default 0.15
-
- tuner = SimpleTuner(optimization_domain_vertices, objective_function, exploration_preference=exploration)
- tuner.optimize(number_of_iterations)
- best_objective_value, best_coords = tuner.get_best()
-
- print('Best objective value ', best_objective_value)
- print('Found at sample coords ', best_coords)
- tuner.plot() # only works in 2D
- # The resulting output is then:
- '''
- Best objective value -0.00823447695587
- Found at sample coords [ 0.19285289 0.29591033]
- '''
github地址:https://github.com/ray-project/ray/tree/master/python/ray/tune
Paper:https://arxiv.org/abs/1807.05118
Ray.tune是一个超参数优化库,主要针对深度学习和强化学习模型。它结合了许多最先进的算法,些都在Ray分布式计算平台上运行,这使其具有极大的可扩展性。
官方文档:https://medium.com/georgian-impact-blog/automatic-machine-learning-aml-landscape-survey-f75c3ae3bbf2
Chocolate是一个完全异步的(支持并行运行的计算集群)超参数优化库,该库使用公共数据库来联合执行各个任务。它支持网格搜索,随机搜索,准随机搜索,贝叶斯搜索和协方差矩阵适应进化策略。它的独特功能包括对受限搜索空间的支持以及优化多个损失函数(多个目标优化)。
- import chocolate as choco
-
- def objective_function(condition, x=None, y=None):
- """An objective function returning ``1 - x`` when *condition* is 1 and
- ``y - 6`` when *condition* is 2.
- Raises:
- ValueError: If condition is different than 1 or 2.
- """
- if condition == 1:
- return 1 - x
- elif condition == 2:
- return y - 6
- raise ValueError("condition must be 1 or 2, got {}.".format(condition))
-
- # Define the conditional search space
- space = [
- {"condition": 1, "x": choco.uniform(low=1, high=10)},
- {"condition": 2, "y": choco.log(low=-2, high=2, base=10)}
- ]
- # Establish a connection to a SQLite local database
- conn = choco.SQLiteConnection("sqlite:///my_db.db")
- # Construct the optimizer
- sampler = choco.Bayes(conn, space)
- # Sample the next point
- token, params = sampler.next()
- # Calculate the loss for the sampled point (minimized)
- loss = objective_function(**params)
- # Add the loss to the database
- sampler.update(token, loss)
GPflowOpt是使用GPflow进行贝叶斯优化的,并使用Tensorflow在GPU上运行高斯过程任务的库。如果需要贝叶斯优化并且GPU计算资源可用,这使GpFlowOpt成为理想的优化器。
FAR-HO是一个库,其中包含一组在tensorflow上运行的基于梯度的优化器,其中包括Reverse-HG和Forward-HG。
基于TensorFlow的基于梯度的超参数优化,实现了本文 基于正向和反向梯度的超参数优化中介绍的算法。
该库的目的是在Tensorflow中实施基于梯度的超参数优化技术,从而允许在GPU或其他针对深度学习模型进行张量优化的计算环境中进行模型训练和超参数优化。
- import far_ho as far
- import tensorflow as tf
-
- model = create_model(...)
-
- lambda1 = far.get_hyperparameter('lambda1', ...)
- lambda1 = far.get_hyperparameter('lambda2', ...)
- io, oo = create_objective(...)
-
- inner_problem_optimizer = far.GradientDescentOptimizer(lr=far.get_hyperparameter('lr', 0.1))
- outer_problem_optimizer = tf.train.AdamOptimizer()
-
- farho = far.HyperOptimizer()
- ho_step = farho.minimize(oo, outer_problem_optimizer,
- io, inner_problem_optimizer)
-
- T = 100
- with tf.Session().as_default():
- for _ in range(100):
- ho_step(T)
github地址:https://github.com/reiinakano/xcessiv
Xcessiv是用于大规模模型开发,执行和集成的框架。它的强大功能来自于在单个GUI中管理大量机器学习模型的训练,执行和评估的能力。它还具有用于组合这些模型的多个集成工具,以实现最佳性能。它包含一个贝叶斯搜索参数优化器,该优化器支持高度的并行性,还支持与TPOT集成。
github地址:https://github.com/ilija139/HORD
HORD是用于超参数优化的独立算法(动态坐标搜索)。HORD通过动态坐标搜索为黑盒模型生成替代函数,并使用该函数生成可能接近理想值的“理想的”超参数,以减少对完整模型的评估。与parzen估计器,SMAC和高斯过程树相比,它更具一致性和低错误率。
github地址:https://github.com/carpedm20/ENAS-pytorch
Paper: https://arxiv.org/abs/1802.03268
ENAS-pytorch在pytorch中实现了有效的神经体系结构搜索,以进行深度学习。它使用参数共享来最快地实现最高效的网络,使其适合于深度学习架构搜索。
1. Auto_ml
第一个框架是auto_ml。这个框架是为项目的生产环境设计的,功能涉及整个机器学习过程的自动化,具体包括:
使用例子
- # 数据导入
- from auto_ml import Predictor
- from auto_ml.utils import get_boston_dataset
- df_train, df_test = get_boston_dataset() # 样本数据如下图所示
- column_descriptions = {
- 'MEDV': 'output',
- 'CHAS': 'categorical'} # 说明MEDV为因变量,CHAS为类别数据
- ml_predictor = Predictor(type_of_estimator='regressor', column_descriptions=column_descriptions)
- ml_predictor.train(df_train) # 按照官方文档模式的参数设置进行训练
默认的方法为:GradientBoostingRegressor,同时,也给了关于变量的一些分析结果。例如,Importance :GradientBoostingRegressor中feature importance, 说明每个自变量对MEDV的变动的解释程度。
调整参数,我们可以在这个基础上做一些调整,包括 perform_feature_selection(只保留贡献率最大的变量),改变模型为'RandomForestRegressor'(默认为GradientBoostingRegressor),将cross-validation 改为 10-fold。
- ml_predictor.train(df_train,perform_feature_selection=True,cv=10,model_names='RandomForestRegressor')
- 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
(...))使用例子
- import autosklearn.classification
- import sklearn.model_selection
- import sklearn.datasets
- import sklearn.metrics
- X, y = sklearn.datasets.load_digits(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()
- automl.fit(X_train, y_train)
- y_hat = automl.predict(X_test)
3. TPOT
TPOT定位为数据科学的助手,完成最终模型分析前很多繁杂的工作。使用的是遗传编程的技术。遗传编程与传统机器学习的区别:机器学习主要是在一个参数空间上,通过调整参数获得最佳的预测结果,重点在找参数。遗传编程可以理解为一个能构造算法的算法,重点在找算法。
所以,基于遗传编程,我们就比较好理解TPOT官方文档的说明,如下图,TPOT其实就是在寻找一个最优的路径,从原始数据,到数据清洗,特征工程,模型选址,参数最优化,模型验证,中间可以有各自各样的组合。TPOT是帮助数据科学家找出最优的一条路径。当然,在TPOT中,除了寻找出最优的算法,也会给出最优的参数。
使用例子
同样使用波士顿房价的例子:
- from tpot import TPOTRegressor
- from sklearn.datasets import load_boston
- from sklearn.model_selection import train_test_split
-
- housing = load_boston()
- 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)
-
- tpot = TPOTRegressor(generations=5, population_size=50, verbosity=2, random_state=42)
- tpot.fit(X_train, y_train)
运行上面的代码,结果如下,TPOT会产生选出最优的过程:LassoLarsCV。
- # 将模型导出:这会生成一个python的脚本
- tpot.export('tpot_boston_pipeline.py')
脚本如下:
这已经完成了模型分析前大量的探索的工作。现在需要做的,就是对这个脚本做一个简单的编辑,就可以完成最终的模型训练了。
4. H2O AutoML
H2O.ai是美国的一个AI创业公司。为客户提供自动化模型整合、训练以及部署的服务。2019年8月份刚获得高盛和平安领投7250万美金的投资。
AutoML是H2O其中的一项功能。AutoML可自动构建大量模型,在无需任何知识背景的情况下,挑选出最佳的模型支持R和Python。
使用例子(h2o通过接口的数据请求总是有问题!)
- import h2o
- from h2o.automl import H2OAutoML, get_leaderboard
- h2o.init()
- # Import a sample binary outcome train/test set into H2O
- train = h2o.import_file("https://s3.amazonaws.com/erin-data/higgs/higgs_train_10k.csv")
- test = h2o.import_file("https://s3.amazonaws.com/erin-data/higgs/higgs_test_5k.csv")
-
- # Identify predictors and response
- x = train.columns
- y = "response"
- x.remove(y)
-
- # For binary classification, response should be a factor
- train[y] = train[y].asfactor()
- test[y] = test[y].asfactor()
-
- # Run AutoML for 20 base models (limited to 1 hour max runtime by default)
- aml = H2OAutoML(max_models=20, seed=1)
- aml.train(x=x, y=y, training_frame=train)
-
- # AutoML Leaderboard
- lb = aml.leaderboard
-
- # Optionally edd extra model information to the leaderboard
- lb = get_leaderboard(aml, extra_columns='ALL')
-
- # 获取所有的模型排名
- lb.head(rows=lb.nrows)
使用最优模型进行预测
- # 使用最优的模型进行预测
- preds = aml.predict(test)
- # 或者
- preds = aml.leader.predict(test)
5. Auto-Keras
最后,我们介绍一下开源的自动深度学习框架:AutoKeras。Auto-Keras是一个基于Keras的自动学习框架,由Texas A&M的Data Lab开发。AutoKeras是一个出色的开源项目,具备很多开源项目的特点:快速安装,易于运行,示例众多,易于修改等等。
- # 导入数据深度学习的'hello world'数据,mnist,手写数字数据(非常的慢)
- from tensorflow.keras.datasets import mnist
- (x_train, y_train), (x_test, y_test) = mnist.load_data()
训练模型
- import autokeras as ak
-
- # Initialize the image classifier.
- clf = ak.ImageClassifier(max_trials=1) # It tries 10 different models.
- # Feed the image classifier with training data.
- clf.fit(x_train, y_train,epochs=3)
使用最终的模型进行预测
- # Predict with the best model.
- predicted_y = clf.predict(x_test)
- 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。