自动调参——遗传优化算法TPOT

注:转载请注明出处。

  本篇文章主要记录了遗传优化算法TPOT的学习笔记,如果想看自动化调参中的网格调参和遗传优化算法TPOT,请查看我另外两篇文章:网格搜索gridSearchCV贝叶斯优化算法hyperopt

1、简介

TPOT(Tree-based Pipeline Optimisation Technique,树形传递优化技术)是给予遗传算法优化机器学习管道的python自动化学习工具。具体作用就是可以智能地探索数千个可能的pipline,为数据集找到最好的pipeline。

2、功能

  1. 自动完成特征工作(特征选择、特征预处理、特征构建等)
  2. 模型的选择与调优
  3. 完成搜索后,同事提供了python代码,通过导出的代码,得知TPOP活动最优性能时的具体pipeline的内容,便于后期修改。

3、参数

  1. 基本参数
1
2
3
4
5
generation:遗传算法进化次数,可理解为迭代次数
population_size:每次进化中种群大小
num_cv_folds:交叉验证
scoring:也就是评价指标
generation和population_size共同决定TPOT的复杂度。
  1. 重要说明的参数:config_dict
1
2
3
4
5
6
7
8
9
10
#tpot_config = {
# 'sklearn.ensemble.RandomForestClassifier':{
# },
# 'xgboost.XGBClassifier': {
# },
# 'sklearn.linear_model.logistic.LogisticRegression': {
# },
#}
## 注意:如果使用config_dict,则以上代码的注释要去掉。
model= TPOTClassifier(generations=10,population_size=20,verbosity=2,random_state=3,config_dict=tpot_config)
  1. 重要说明的参数:scoring
  • 可以直接设置属性值,可取范围为:
1
2
3
4
5
'accuracy', 'adjusted_rand_score', 'average_precision', 'balanced_accuracy',
'f1','f1_macro', 'f1_micro', 'f1_samples', 'f1_weighted', 'neg_log_loss', 'neg_mean_absolute_error',
'neg_mean_squared_error', 'neg_median_absolute_error', 'precision', 'precision_macro', 'precision_micro',
'precision_samples', 'precision_weighted','r2', 'recall', 'recall_macro', 'recall_micro', 'recall_samples',
'recall_weighted', 'roc_auc', 'my_module.scorer_name*'
  • 可以用户自定义函数
1
2
3
4
5
6
7
8
# Make a custom metric function
def my_scoring_func(y_true, y_pred):
return mean_squared_error(y_true, y_pred)

# Make a custom a scorer from the custom metric function
# Note: greater_is_better=False in make_scorer below would mean that the scoring function should be minimized.
my_scorer = sklearn.metrics.scorer.make_scorer(my_scoring_func,greater_is_better=False)
custom_pipeline_optimezer_regressor =TPOTRegressor(generations=5,population_size=5,cv=5,random_state=20, verbosity=1,scoring=my_scorer)

参考:https://www.cnblogs.com/54hys/p/10740913.html

4、总结

  1. TPOT是在sklearn的基础之上做的封装库。其主要封装了sklearn的模型相关模块、processesing模块和feature_selection模块,所以TPOT的主要功能是集中在使用pipeline的方式完成模型的数据预处理、特征选择和模型选择方面。此外,我们还发现了TPOT已经对xgboost进行了支持。
  2. 虽然TPOT使用遗传算法代替了传统的网格搜索进行超参数选择,但由于默认初始值的随机性,在少量的进化(迭代)次数下,TPOT最终选择的模型往往并不相同。
  3. 计算效率问题。作者在代码中写道:进化(迭代)次数和每一代保留的个体数量值越多,最终得模型得分会越高。但这同样也会导致耗时很长。
  4. 如果使用相当复杂的数据集或运行TPOT短时间,不同的TPOT运行可能会导致不同的流水线推荐。TPOT的优化算法本质上是随机的,这意味着它使用随机性(部分地)来搜索可能的流水线空间。当两个TPOT运行推荐不同的管道时,这意味着TPOT运行由于时间不够而不收敛,或者多个管道在数据集上执行的次数大致相同。这实际上是一个优于固定网格搜索技术的优点:TPOT是一个助手,它通过探索您可能从未考虑过的流水线配置来提供解决如何解决特定机器学习问题的想法,然后将微调留给更受约束的参数调整技术,例如网格搜索。

5、使用前应注意(0.9.5):

  1. 在使用TPOT进行建模前需要对数据进行必要的清洗和特征工程操作。
  2. TPOT目前只能做有监督学习。
  3. TPOT目前支持的分类器主要有贝叶斯、决策树、集成树、SVM、KNN、线性模型、xgboost。
  4. TPOT目前支持的回归器主要有决策树、集成树、线性模型、xgboost。
  5. TPOT会对输入的数据做进一步处理操作,例如二值化、聚类、降维、标准化、正则化、独热编码操作
  6. 根据模型效果,TPOT会对输入特征做特征选择操作,包括基于树模型、基于方差、基于F-值的百分比。
  7. 可以通过export()方法把训练过程导出为形式为sklearn pipeline的.py文件

6、应用

  1. 调用TPOT进行模型预选。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from tpot import TPOTClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import logistic
import xgboost
# 导入数据
df = pd.read_csv('D:/pywork/jiandu/sklearn/data/titannic/train.csv')
# 查看数据
df.head()
df.info()
# 选取一些特征作为我们划分的依据
x= df[['Pclass', 'Age', 'Sex','SibSp','Parch','Fare','Embarked']]
# 标签
y=df['Survived']
# 填充缺失值
x['Age'].fillna(x['Age'].mean(),inplace=True)
x['Embarked'].fillna("S",inplace=True)
x["Fare"].fillna(x["Fare"].median,inplace=True)

#数据集划分
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=0)
dt=DictVectorizer(sparse=False)
x_train=dt.fit_transform(x_train.to_dict(orient="record"))
x_test=dt.fit_transform(x_test.to_dict(orient="record"))## 模型调用

## 参数选择参数设置
#tpot_config = {
# 'sklearn.ensemble.RandomForestClassifier':{
# },
# 'xgboost.XGBClassifier': {
# },
# 'sklearn.linear_model.logistic.LogisticRegression': {
# },
#}
## 注意:如果使用config_dict,则以上代码的注释要去掉。
model= TPOTClassifier(generations=10,population_size=20,verbosity=2,random_state=3,config_dict=tpot_config)
model.fit(x_train,y_train)
y_predict=model.predict(x_test)
model.score(x_test,y_test)
auc=roc_auc_score(y_test,y_predict)
print(auc)
print(model.export("tpot_mnist_pipeline1.py"))
  1. 导出的文件
    说明:其实此文件可以直接修改后(如文件名),作为模型代码,但是实际上,由于这部分对于数据没有做处理,只包含很简单的模型调用步骤,直接使用原有数据可能不适用。

所以应用方式:使用此文件的模型部分代码,替换掉模型预选的代码(步骤一的代码)的模型调用部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline, make_union
from tpot.builtins import StackingEstimator

# NOTE: Make sure that the class is labeled 'target' in the data file
tpot_data = pd.read_csv('PATH/TO/DATA/FILE', sep='COLUMN_SEPARATOR', dtype=np.float64)
features = tpot_data.drop('target', axis=1).values
training_features, testing_features, training_target, testing_target = \
train_test_split(features, tpot_data['target'].values, random_state=3)

# Average CV score on the training set was:0.8234273425499232
exported_pipeline = make_pipeline(
StackingEstimator(estimator=RandomForestClassifier(bootstrap=True, criterion="entropy", max_features=0.25, min_samples_leaf=13, min_samples_split=11, n_estimators=100)),
RandomForestClassifier(bootstrap=True, criterion="entropy", max_features=0.7000000000000001, min_samples_leaf=12, min_samples_split=6, n_estimators=100)
)

exported_pipeline.fit(training_features, training_target)
results = exported_pipeline.predict(testing_features)
  1. 使用选出的最好的模型进行模型训练输出。
  • 复杂的模型(模型融合)
    从输出文件中,复制make_pipeline函数,并导入对应的包即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from tpot import TPOTClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import logistic
from sklearn.pipeline import make_pipeline, make_union
from tpot.builtins import StackingEstimator
import xgboost
# 导入数据
df = pd.read_csv('D:/pywork/jiandu/sklearn/data/titannic/train.csv')
# 查看数据
df.head()
df.info()
# 选取一些特征作为我们划分的依据
x= df[['Pclass', 'Age', 'Sex','SibSp','Parch','Fare','Embarked']]
# 标签
y=df['Survived']
# 填充缺失值
x['Age'].fillna(x['Age'].mean(),inplace=True)
x['Embarked'].fillna("S",inplace=True)
x["Fare"].fillna(x["Fare"].median,inplace=True)

#数据集划分
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=0)
dt=DictVectorizer(sparse=False)
x_train=dt.fit_transform(x_train.to_dict(orient="record"))
x_test=dt.fit_transform(x_test.to_dict(orient="record"))
## 模型调用
model=make_pipeline(
StackingEstimator(estimator=RandomForestClassifier(bootstrap=True, criterion="entropy", max_features=0.25, min_samples_leaf=13, min_samples_split=11, n_estimators=100)),
RandomForestClassifier(bootstrap=True, criterion="entropy", max_features=0.7000000000000001, min_samples_leaf=12, min_samples_split=6, n_estimators=100)
)
model.fit(x_train,y_train)
y_predict=model.predict(x_test)
model.score(x_test,y_test)
auc=roc_auc_score(y_test,y_predict)
print(auc)
print(model.export("tpot_mnist_pipeline1.py"))
  • 简单模型
    将输出模型中的input_matrix删除,直接放到模型调用部分即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import logistic
import xgboost
# 导入数据
df = pd.read_csv('D:/pywork/jiandu/sklearn/data/titannic/train.csv')
# 查看数据
df.head()
df.info()
# 选取一些特征作为我们划分的依据
x= df[['Pclass', 'Age', 'Sex','SibSp','Parch','Fare','Embarked']]
# 标签
y=df['Survived']
# 填充缺失值
x['Age'].fillna(x['Age'].mean(),inplace=True)
x['Embarked'].fillna("S",inplace=True)
x["Fare"].fillna(x["Fare"].median,inplace=True)
#数据集划分
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=0)
dt=DictVectorizer(sparse=False)
x_train=dt.fit_transform(x_train.to_dict(orient="record"))
x_test=dt.fit_transform(x_test.to_dict(orient="record"))

## 模型调用--将输出模型中的input_matrix删除。
model=xgboost.XGBClassifier(learning_rate=0.1, max_depth=9, min_child_weight=6, n_estimators=100, nthread=1, subsample=0.8)
model.fit(x_train,y_train)
y_predict=model.predict(x_test)
model.score(x_test,y_test)
auc=roc_auc_score(y_test,y_predict)
print(auc)
print(model.export("tpot_mnist_pipeline1.py"))

7、原理与源码解读

参看:https://blog.csdn.net/hgy0403/article/details/81291307

8、参考

  1. https://www.jianshu.com/p/2d7f1bbf2af2
  2. https://blog.csdn.net/anshuai_aw1/article/details/82498947
  3. https://blog.csdn.net/Tony_Stark_Wang/article/details/79858905
  4. http://epistasislab.github.io/tpot/examples/
  5. anaconda中安装:https://blog.csdn.net/Tony_Stark_Wang/article/details/79858556
  6. “总结”与“使用前应注意”部分摘自:https://www.bbsmax.com/A/1O5EYEv357/
  7. https://blog.csdn.net/anshuai_aw1/article/details/82498947#2.5%C2%A0NOTE