Tree-based Pipeline Optimization Tool(TPOT,基于树的管道优化工具)是一个用于在 Python 中执行 AutoML 的开源库。
TPOT 使用基于树的结构来表示预测建模问题的模型管道,包括数据准备和建模算法以及模型超参数。它利用流行的 Scikit-Learn 机器学习库进行数据转换和机器学习算法,并使用遗传编程随机全局搜索过程来有效地发现给定数据集的性能最佳的模型管道。
然后执行优化过程以找到对给定数据集执行最佳的树结构。具体来说,一种遗传编程算法,旨在对表示为树的程序执行随机全局优化。
下图取自 TPOT 论文,展示了管道搜索所涉及的元素,包括数据清洗、特征选择、特征处理、特征构建、模型选择和超参数优化。
TPOT 将通过智能探索数千条可能的管道来为你的数据找到最佳管道,从而自动化机器学习中最繁琐的部分。
pip install tpot
安装后,导入库并打印版本号以确认它已成功安装:
# check tpot version
import tpot
print('tpot: %s' % tpot.__version__)
(1)创建TPOTRegressor 或 TPOTClassifier 类的实例,并做好配置后进行搜索
(2)导出在数据集上找到的最佳性能的模型管道。
涉及两个主要元素。
①如何评估模型
例如:
要使用 neg_mean_absolute_error 作为回归度量,则选用RepeatedKFold用于回归交叉验证。
# 定义了评价步骤
cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
# 定义搜索
model = TPOTRegressor(... scoring='neg_mean_absolute_error', cv=cv)
或者使用 accuracy 作为分类模型的评价指标,则选用RepeatedStratifiedKFold用于分类交叉验证。
# 定义了评价步骤
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# 定义搜索
model = TPOTClassifier(... scoring='accuracy', cv=cv)
②进化计算的参数配置
作为一种进化算法,涉及到较为复杂的配置的设置,例如种群规模、要运行的代数以及潜在的交叉和突变率。前者重要地控制着搜索的范围;如果你对进化搜索算法不熟悉,可以将后者保留设置为默认值。
例如,100 代和5或10代的适度种群规模是一个很好的起点。
# define 搜索
model = TPOTClassifier(generations=5, population_size=50, ...)
此输出最佳模型的管道可以导出为py文件,后期可以将其复制并粘贴到你自己的项目中。
# 输出最佳模型
model.export('tpot_model.py')
声纳数据集是一个标准的机器学习数据集,由 208 行数据和 60 个数字输入变量和一个具有两个类值的目标变量组成,例如二进制分类。
该数据集涉及预测声纳返回是否指示岩石或矿井。
①加载数据
from pandas import read_csv
dataframe = read_csv(data, header=None)
data = dataframe.values
X, y = data[:, :-1], data[:, -1]
print(X.shape, y.shape)
②使用RepeatedStratifiedKFold交叉验证定义评估模型的方法。
# 定义模型评估器
cv = RepeatedStratifiedKFold(n_splits=10,
n_repeats=3,
random_state=1)
③将使用 50 个样本大小进行五折搜索,并设置 n_jobs = -1来使用系统上的所有核。
# 定义搜索
model = TPOTClassifier(generations=5,
population_size=50, cv=cv,
scoring='accuracy', verbosity=2,
random_state=1, n_jobs=-1)
④开始搜索并确保在运行结束时保存性能最佳的模型
# 执行搜索
model.fit(X, y)
# 输出最佳模型
model.export('tpot_sonar_best_model.py')
最后将性能最佳的管道保存到名为 “tpot_sonar_best_model.py ” 的文件中。
# 在声纳数据集上拟合最终模型并做出预测的例子
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.pipeline import make_pipeline
from tpot.builtins import StackingEstimator
from tpot.export_utils import set_param_recursive
# 导入数据集
dataframe = read_csv(data, header=None)
# 拆分为输入变量和输出变量
data = dataframe.values
X, y = data[:, :-1], data[:, -1]
# 以尽量小的内存使用数据集
X = X.astype('float32')
y = LabelEncoder().fit_transform(y.astype('str'))
# 训练集上的交叉验证平均分数为: 0.8667
exported_pipeline = make_pipeline(
StackingEstimator(estimator=GaussianNB()),
GradientBoostingClassifier(learning_rate=0.1, max_depth=7, max_features=0.7000000000000001, min_samples_leaf=15, min_samples_split=10, n_estimators=100, subsample=0.9000000000000001)
)
# 修正了导出管道中所有步骤的随机状态
set_param_recursive(exported_pipeline.steps, 'random_state', 1)
# 训练模型
exported_pipeline.fit(X, y)
# 对新数据行进行预测
row = [0.0200,0.0371,0.0428,0.0207,0.0954,0.0986]
yhat = exported_pipeline.predict([row])
print('Predicted: %.3f' % yhat[0])
汽车保险数据集是一个标准的机器学习数据集,由 63 行数据组成,一个数字输入变量和一个数字目标变量。
过程类似于分类。
# 拟合最终模型并在保险数据集上做出预测的例子
from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.svm import LinearSVR
# 导入数据集
dataframe = read_csv(data, header=None)
# 拆分为输入变量和输出变量
data = dataframe.values
# 以尽量小的内存使用数据集
data = data.astype('float32')
X, y = data[:, :-1], data[:, -1]
# 训练集上的交叉验证平均分数为: -29.1476
exported_pipeline = LinearSVR(C=1.0, dual=False, epsilon=0.0001, loss="squared_epsilon_insensitive", tol=0.001)
# 修正了导出估计器中的随机状态
if hasattr(exported_pipeline, 'random_state'):
setattr(exported_pipeline, 'random_state', 1)
# 模型训练
exported_pipeline.fit(X, y)
# 对新数据行进行预测
row = [108]
yhat = exported_pipeline.predict([row])
print('Predicted: %.3f' % yhat[0])
Pima Indians Diabetes 数据集预测 5 年内糖尿病的患病率
# import the AutoMLpackage after installing tpot.
import tpot
# 导入其他必要的包。
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
from tpot import TPOTClassifier
import os
# 导入数据
file_path = './pima-indians-diabetes.data.csv'
df = pd.read_csv(file_path,header=None)
#可以用你自己的数据集.csv文件名替换
# 将数据帧的值拆分为输入和输出特征
data = df.values
X, y = data[:, :-1], data[:, -1]
print(X.shape, y.shape)
#(768, 8 ) (768,)
X = X.astype('float32')
y = LabelEncoder().fit_transform(y.astype('str'))
#模型评估定义,这里使用10倍StratifiedKFold
cv = StratifiedKFold(n_splits=10)
# 定义 TPOTClassifier
model = TPOTClassifier(generations=5, population_size=50,
cv=cv, score='accuracy',
verbosity=2, random_state=1,
n_jobs=-1)
# 执行最佳拟合搜索
model.fit(X , y)
# 导出最佳模型
model.export('tpot_data.py')
generation: int或None可选(默认值= 100)
运行管道优化过程的迭代次数。它必须是一个正数或无。
Population_size:int,可选(默认为100)
每代保留在基因编程人群中的个体数量。必须为正数。
offspring_size:int,可选(默认=无)
每个基因编程世代中产生的后代数量,正数,默认情况下,后代的数量等于种群数量。
variant_rate:浮点型,可选(默认= 0.9)
遗传编程算法的变异率在[0.0,1.0]范围内。此参数告诉GP算法有几条管道可对每一代应用随机更改,建议使用默认参数,除非您了解突变率如何影响GP算法。
crossover_rate:浮点型,可选(默认= 0.1)。
遗传编程算法的交叉率在[0.0,1.0]范围内。此参数告诉遗传编程算法每一代“繁殖”多少条管道。variant_rate + crossover_rate不能超过1.0。我们建议使用默认参数,除非您了解交叉速率如何影响GP算法
scoring: 字符串或可调用,可选(默认=“准确性”)。
用于评估分类问题的给定管道质量的函数,可以使用以下内置计分功能:
‘accuracy’, ‘adjusted_rand_score’, ‘average_precision’, ‘balanced_accuracy’, ‘f1’, ‘f1_macro’, ‘f1_micro’, ‘f1_samples’, ‘f1_weighted’, ‘neg_log_loss’, ‘precision’ etc. (suffixes apply as with ‘f1’), ‘recall’ etc. (suffixes apply as with ‘f1’), ‘jaccard’ etc. (suffixes apply as with ‘f1’), ‘roc_auc’, ‘roc_auc_ovr’, ‘roc_auc_ovo’, ‘roc_auc_ovr_weighted’, ‘roc_auc_ovo_weighted’
如果您想使用自定义评分器 ,则可以通过评分器(estimator,X,y)传递可调用对象/函数。
cv:int,交叉验证或可迭代的生成器,可选(默认值= 5)
评估管道时使用的交叉验证策略。
subsample: float, optional (default=1.0)
TPOT优化过程中使用的训练样本的分数。必须在(0.0,1.0]范围内。设置subsample= 0.5会告诉TPOT使用一半训练数据的随机子样本,该子样本在整个管道优化过程中将保持不变。
n_jobs:整数,可选(默认值= 1)
在TPOT优化过程中并行用于评估管道的进程数。
设置n_jobs = -1将使用尽可能多的内核。对于小于-1的n_job,将使用(n_cpus +1 + n_jobs)。因此,对于n_jobs = -2,将使用除一个以外的所有CPU。请注意,在同一台计算机上使用多个进程可能会导致大型数据集的内存问题。
max_time_mins:整数或无,可选(默认=无)
TPOT需要多少分钟来优化管道。如果不设置为None,则此设置将允许TPOT运行,直到经过max_time_mins分钟,然后停止。如果generations被设置,则当generations次数被执行完之后,TPOT将提早停止。
max_eval_time_mins:浮点型,可选(默认= 5)
TPOT必须评估多少分钟才能评估一条管道。
将此参数设置为较高的值将使TPOT可以评估更复杂的管道,但也可以使TPOT运行更长的时间。使用此参数可以帮助防止TPOT在评估耗时的管道上浪费时间。
random_state:整数或无,可选(默认=无)
TPOT中使用的伪随机数生成器的种子。使用此参数可确保每次对带有该种子的相同数据集运行TPOT时,TPOT都将提供相同的结果。
config_dict:Python字典,字符串或无,可选(默认=无)
一个配置字典,用于自定义TPOT在优化过程中搜索的运算符和参数。
可能的输入是:
Python字典,TPOT将使用您的自定义配置,
字符串“ TPOT light”,TPOT将使用仅具有快速模型和预处理器的内置配置,或者
字符串“ TPOT MDR”,TPOT将使用专门用于基因组研究的内置配置,或者
字符串“ TPOT sparse”:TPOT将使用带有一键编码器的配置字典,并且TPOT中通常包含的运算符也支持稀疏矩阵,或者无,TPOT将使用默认的TPOTClassifier配置。
warm_start:布尔值,可选(默认= False)
指示TPOT实例是否将重用先前对fit()的调用中的填充的标志。
设置warm_start = True对于在数据集上短时间运行TPOT,检查结果,然后从中断的地方继续运行TPOT很有用。
memory:一个joblib.Memory对象或字符串,可选(默认=无)
如果提供,管道将在调用fit之后缓存每个变压器。如果在优化过程中参数和输入数据与另一个拟合管道相同,则使用此功能可避免计算管道内的拟合变压器。scikit-learn文档中 有关内存缓存的更多详细信息,可能的输入是:字符串“ auto”:TPOT使用带有临时目录的内存缓存,并在关机时清除它,或者缓存目录的路径,TPOT使用提供的目录的内存缓存,并且在关闭时TPOT不会清理缓存目录,或者内存对象,TPOT使用joblib实例.Memory用于内存缓存,并且TPOT在关闭时不会清理缓存目录,或者无,TPOT不使用内存缓存。
use_dask:布尔值,可选(默认:False)
是否使用Dask-ML的管道优化。这样可以避免在同一数据分割上多次重新拟合相同的估算器。使用Dask的分布式调度程序时,还将提供更详细的诊断信息。
period_checkpoint_folder:路径字符串,可选(默认值:无)
如果提供,则是一个文件夹,到目前为止,TPOT会在此文件夹中定期保存管道,同时进行优化。目前,每代一次,但不多于每30秒一次。在多种情况下有用:TPOT可能导致猝死,从而节省了优化的管道;追踪进度;在仍在优化的同时获取管道。
early_stop:整数,可选(默认值:无)
TPOT检查了几代,优化过程是否没有改善。如果给定的世代数没有改善,则结束优化过程。
verbosity:整数,可选(默认= 0)
TPOT在运行时传达多少信息。
可能的输入是:
0,TPOT将不打印任何内容,
1,TPOT将打印最少的信息,
2,TPOT将打印更多信息并提供进度条,或者
3,TPOT将打印所有内容并提供进度条。
disable_update_check:布尔值,可选(默认= False)
指示是否应禁用TPOT版本检查器的标志。更新检查器将告诉您何时发布了新版本的TPOT。
log_file:io.TextIOWrapper或io.StringIO,可选(默认sys.stdout)
将进度内容保存到文件中。
在给定的训练数据上运行TPOT优化过程
使用遗传编程来优化机器学习管道,从而最大程度地提高所提供的功能和目标的得分。此管道优化过程使用内部k折交叉验证来避免对提供的数据进行过度拟合。在管道优化过程的最后,然后对所提供的整个样本集训练最佳管道。
使用优化的管道来预测功能集的类
predict(features)
使用优化的流水线来估计功能集的类概率
注意:该函数仅适用于最终分类器支持predict_proba函数的管道。否则,TPOT会引发错误。
predict_proba(features)
使用用户指定的评分功能,根据给定的测试数据返回优化管道的得分
TPOTClassifier的默认评分功能是“准确性”。
score(testing_features, testing_classes)
将优化的管道导出为Python代码
export(output_file_name, data_file_path)
为上述问题尝试了TPOT ,它仅使用默认配置。其实 AutoML TPOT 还有有许多内置配置。下面列出了这些变体:
在参数非常多的情况下,自动搜索网络架构是相当耗时的,由此我们可以看出TPOT问题——耗时。在默认的TPOT参数下(100 generations with 100 population size),TPOT将在完成前评估1万个管道配置。考虑一个网格搜索1万个超参数组合用于机器学习算法以及网格搜索需要多长时间。用10倍的交叉验证来评估这1万个模型,这意味着大约有10万个模型在一个网格搜索的训练数据中被匹配和评估。这是一个耗时的过程,即使对于像决策树这样的简单模型也是如此。
典型的TPOT运行将需要数小时到数天才能完成(除非是一个小数据集),但是可以中断运行,并看到目前为止最好的结果。TPOT还提供warm_start参数,可以从中断的地方重新启动之前运行的TPOT。
可能的解决方法:
在做数据挖掘问题,可以尝试在数据清洗之后,抽样小部分数据跑一下TPOT,得到一个baseline,效果可能还不错。