HyperGBM

DataCanvas

HyperGBM is an open source project created by DataCanvas .

内容:

概览

关于HyperGBM

HyperGBM是一款全Pipeline自动机器学习工具,可以端到端的完整覆盖从数据清洗、预处理、特征加工和筛选以及模型选择和超参数优化的全过程,是一个真正的结构化数据AutoML工具包。

大部分的自动机器学习工具主要解决的是算法的超参数优化问题,而HyperGBM是将从数据清洗到算法优化整个的过程放入同一个搜索空间中统一优化。这种端到端的优化过程更接近于SDP(Sequential Decision Process)场景,因此HyperGBM采用了强化学习、蒙特卡洛树搜索等算法并且结合一个meta-leaner来更加高效的解决全Pipeline优化的问题,并且取得了非常出色的效果。

正如名字中的含义,HyperGBM中的机器学习算法使用了目前最流行的几种GBM算法(更准确的说是梯度提升树模型),目前包括XGBoost、LightGBM、CatBoost和HistGridientBoosting。同时,HyperGBM也引入了Hypernets的CompeteExperiment在数据清洗、特征工程、模型融合等环节的很多高级特性。

HyperGBM中的优化算法和搜索空间表示技术以及CompeteExperiment由 Hypernets项目提供支撑。

值得强调的是,HyperGBM还支持全Pipeline的GPU加速,包括所有的数据处理和模型训练环节,在我们的实验环境中可得到最多超过50倍的性能提升 !更重要的是,使用GPU训练的模型可以部署到没有GPU硬件和软件(CUDA)的环境中,大大降低模型上线的成本。

功能特性

HyperGBM有4中运行模式,分别为:

  • 单机模式:在一台服务器上运行,使用Pandas和Numpy数据结构

  • 单机GPU模式:在一台服务器上运行,使用cuDF和cupy数据结构

  • 单机分布式:在一台服务器上运行,使用Dask数据结构,在运行HyperGBM之前需要创建运行在单机上的Dask集群

  • 多机分布式:在多台服务器上运行,使用Dask数据结构,在运行HyperGBM之前需要创建能管理多台服务器资源的Dask集群

不同运行模式的功能特性支持稍有差异,HyperGBM的功能特性清单及各种的运行模式的支持情况如下表:

功能特性

单机模式

单机GPU模式

单机分布式

多机分布式

数据清洗

特殊空值字符处理

自动识别类别列

列类型校正

常量列清理

重复列清理

删除标签列为空的样本

非法值替换

id列清理

数据集拆分

按比例拆分

对抗验证

特征工程

特征衍生

特征降维

数据预处理

SimpleImputer

SafeOrdinalEncoder

TargetEncoder

SafeOneHotEncoder

TruncatedSVD

StandardScaler

MinMaxScaler

MaxAbsScaler

RobustScaler

数据不平衡处理

ClassWeight

降采样(Nearmiss,Tomekslinks,Random)

过采样(SMOTE,ADASYN,Random)

搜索算法

蒙特卡洛树算法

进化算法

随机搜索

NSGA-II

R-NSGA-II

MOEA/D

历史回放

提前停止策略

最大用时间提前停止

n次搜索都不再提升,提前停止

expected_reward

trail discriminator

建模算法

XGBoost

LightGBM

CatBoost

HistGridientBoosting

评估方法

交叉验证(Cross-Validation)

Train-Validation-Holdout验证

高级特性

自动任务类型推断

自动内存适配

共线性特征检测

数据漂移检测

特征筛选

特征筛选(二阶段)

伪标签(二阶段)

通过降采样进行预搜索

模型融合

安装HyperGBM

推荐使用condapip命令来安装HyperGBM(请提前准备好Python3.6以上版本的环境);如果您有Docker环境,也可以在Docker容器中安装并运行HyperGBM。

使用Conda

可以从 conda-forge 安装HyperGBM:

conda install -c conda-forge hypergbm

使用Pip

基本的,使用如下pip命令安装HyperGBM:

pip install hypergbm

可选的, 如果您希望在JupyterLab中使用HyperGBM, 可通过如下命令安装HyperGBM:

pip install hypergbm[notebook]

可选的, 如果您希望在DASK集群中运行HyperGBM, 可通过如下命令安装HyperGBM:

pip install hypergbm[dask]

可选的, 如果您希望在特征衍生时支持中文字符, 可通过如下命令安装HyperGBM:

pip install hypergbm[zhcn]

可选的, 如果您希望使用基于Web的实验可视化,可通过如下命令安装HyperGBM:

pip install hypergbm[board]

可选的, 如果您希望安装HyperGBM以及所有依赖包,则可通过如下形式安装:

pip install hypergbm[all]

使用Docker

HyperGBM支持在Docker容器中运行,您可在Dockerfile中通过 pip 安装HyperGBM,然后使用。

我们在Docker Hub中发布了一个参考镜像,可直接下载使用,该镜像中包括:

  • Python 3.8

  • HyperGBM及其依赖包

  • JupyterLab

Docker镜像tag命名规则:

  • <hypergbm_version>:Python + JupyterLab + HyperGBM + HyperGBM的notebook插件

  • <hypergbm_version>-cuda<cuda_version>-cuml<cuml_version>:上述 + CUDA toolkit + cuML

  • <hypergbm_version>-cuda<cuda_version>-cuda<cuml_version>-lgbmgpu:上述 + 支持GPU的LightGBM

下载镜像:

docker pull datacanvas/hypergbm

运行镜像:

docker run -ti -e NotebookToken="your-token" -p 8888:8888 datacanvas/hypergbm

打开浏览器,访问http://<your-ip>:8888,输入您设置的token即可开始使用。

安装 GPU 加速的依赖包

  • cuML and cuDF

HyperGBM利用NVIDIA RAPIDS中的 cuML 和 cuDF对数据处理进行加速,所以如果要利用GPU对HyperGBM进行加速的话,您需要在运行HyperGBM之前安装这两个软件。这两个软件的安装方法请参考 NVIDIA RAPIDS官网 https://rapids.ai/start.html#get-rapids .

  • 支持 GPU 的 LightGBM

通过默认方式安装的LightGBM并不能利用GPU进行训练,所以您需要自己编译和安装能够支持GPU的LightGBM。建议您在安装HyperGBM之前就安装好支持GPU的LightGMB,HyperGBM 安装程序会复用已经存在的软件包。关于如何在LightGBM中开启GPU支持的方法请参考其官网文档 LightGBM GPU Tutorial

  • 支持GPU的 XGBoost 和 CatBoost

通过默认方式安装的 XGBoost 和 CatBoost已经内置了对GPU的支持,所以您不要再做其他的动作。但是,如果您希望自己手动从源代码中编译和安装这两个软件的话,请开启他们支持GPU的选项。

快速开始

本章介绍HyperGBM主要功能,假设您已经知道机器学习的基本知识(加载数据、模型训练、预测、评估等),如果您还没安装请参照[安装文档](installation.md)来安装HyperGBM。 您可以通过Python和命令行工具来使用HyperGBM。

通过Python使用HyperGBM

HyperGBM基于Python开发,推荐利用Python工具 make_experiment 创建实验并进行训练得到模型。

通过 make_experiment 训练模型的基本步骤:

  • 准备数据集(pandas 或 dask DataFrame)

  • 通过工具 make_experiment 创建实验

  • 执行实验 .run() 方法进行训练得到模型

  • 利用模型进行数据预测或Python工具 pickle 存储模型

准备数据集

可以根据实际业务情况通过pandas或dask加载数据,得到用于模型训练的DataFrame。

以sklearn内置数据集 breast_cancer 为例,可如下处理得到数据集:

import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split

X,y = datasets.load_breast_cancer(as_frame=True,return_X_y=True)
X_train,X_test,y_train,y_test = train_test_split(X,y,train_size=0.7,random_state=335)
train_data = pd.concat([X_train,y_train],axis=1)

其中 train_data 用于模型训练(包括目标列),X_testy_test 用于模型评价。

创建实验并进行训练

假设希望最终模型有比较好的precision,为前面准备的训练数据集创建实验并开始训练模型如下:

from hypergbm import make_experiment


experiment = make_experiment(train_data, target='target', reward_metric='precision')
estimator = experiment.run()

其中 estimator 就是训练所得到的模型。

输出模型

推荐利用 pickle 存储HyperGBM模型,如下:

import pickle
with open('model.pkl','wb') as f:
  pickle.dump(estimator, f)
评价模型

可利用sklearn提供的工具进行模型评价,如下:

from sklearn.metrics import classification_report

y_pred=estimator.predict(X_test)
print(classification_report(y_test, y_pred, digits=5))

输出:

              precision    recall  f1-score   support

           0    0.96429   0.93103   0.94737        58
           1    0.96522   0.98230   0.97368       113

    accuracy                        0.96491       171
   macro avg    0.96475   0.95667   0.96053       171
weighted avg    0.96490   0.96491   0.96476       171
更多信息

关于 make_experiment 的更多信息,您可以查看该工具的docstring,如:

print(make_experiment.__doc__)

如果您正在Notebook或IPython中使用HyperGBM, 可以通过如下方式获取 make_experiment 的更多信息:

make_experiment?

通过命令行使用HyperGBM

HyperGBM提供了命令行工具 hypergbm 进行模型训练、评估和预测数据,查看命令行帮助:

hypergm -h

usage: hypergbm [-h] [--log-level LOG_LEVEL] [-error] [-warn] [-info] [-debug]
                [--verbose VERBOSE] [-v] [--enable-dask ENABLE_DASK] [-dask]
                [--overload OVERLOAD]
                {train,evaluate,predict} ...

hypergbm提供三个子命令:trainevaluatepredict,可通过hypergbm <子命令> -h获取更多信息,如:

hypergbm train -h
usage: hypergbm train [-h] --train-data TRAIN_DATA [--eval-data EVAL_DATA]
                      [--test-data TEST_DATA]
                      [--train-test-split-strategy {None,adversarial_validation}]
                      [--target TARGET]
                      [--task {binary,multiclass,regression}]
                      [--max-trials MAX_TRIALS] [--reward-metric METRIC]
                      [--cv CV] [-cv] [-cv-] [--cv-num-folds NUM_FOLDS]
                      [--pos-label POS_LABEL]
                      ...
准备数据

使用命令行工具训练模型时,训练数据必须是csv或parquet格式的文件,并以 .csv.parquet结尾;输出模型是pickle格式,以.pkl结尾。

以训练数据Bank Marketing为例子,可准备数据如下:

from hypernets.tabular.datasets import dsutils
from sklearn.model_selection import train_test_split

df = dsutils.load_bank().head(10000)
df_train, df_test = train_test_split(df, test_size=0.3, random_state=9527)
df_train.to_csv('bank_train.csv', index=None)
df_test.to_csv('bank_eval.csv', index=None)

df_test.pop('y')
df_test.to_csv('bank_to_pred.csv', index=None)

其中:

  • bank_train.csv:用于模型训练

  • bank_eval.csv:用于模型评价

  • bank_to_pred.csv:是没有目标列的数据,用于模拟待预测数据

模型训练

在准备好训练数据之后,可通过命令进行模型训练:

hypergbm train --train-data bank_train.csv --target y --model-file model.pkl

等待命令结束,可看到模型文件:model.pkl

ls -l model.pkl

rw-rw-r-- 1 xx xx 9154959    17:09 model.pkl
模型评价

在模型训练之后,可利用评价数据对所得到的模型进行评价:

hypergbm evaluate --model model.pkl --data bank_eval.csv --metric f1 recall auc

{'f1': 0.7993779160186626, 'recall': 0.7099447513812155, 'auc': 0.9705420982746849}
数据预测

在模型训练之后,可利用所得到的模型进行数据预测:

hypergbm predict --model model.pkl --data bank_to_pred.csv --output bank_output.csv

预测结果会保存到文件bank_output.csv 中。

如果您希望将预测数据的某一列数据(如”id”)与预测结果一起写到输出文件,则可通过参数 --with-data 指定,如:

hypergbm predict --model model.pkl --data bank_to_pred.csv --output bank_output.csv --with-data id
head bank_output.csv

id,y
1563,no
124,no
218,no
463,no
...

如果,您希望输出文件除了包含预测结果之外,还希望有预测数据的所有列,则可将参数 --with-data 设置为”*”,如:

hypergbm predict --model model.pkl --data bank_to_pred.csv --output bank_output.csv --with-data '*'
head bank_output.csv

id,age,job,marital,education,default,balance,housing,loan,contact,day,month,duration,campaign,pdays,previous,poutcome,y
1563,55,entrepreneur,married,secondary,no,204,no,no,cellular,14,jul,455,13,-1,0,unknown,no
124,51,management,single,tertiary,yes,-55,yes,no,cellular,11,may,281,2,266,6,failure,no
218,49,blue-collar,married,primary,no,305,yes,yes,telephone,10,jul,834,10,-1,0,unknown,no
463,35,blue-collar,divorced,secondary,no,3102,yes,no,cellular,20,nov,138,1,-1,0,unknown,no
2058,50,management,divorced,tertiary,no,201,yes,no,cellular,24,jul,248,1,-1,0,unknown,no
...

通过Hyperctl使用HyperGBM

Hyperctl 是一个批量任务管理工具,可以使用它来运行HyperGBM的训练实验。 HyperGBM提供了脚本hypergbm/job.pyhypergbm/gpu_job.py(用来使用gpu训练)用来读取hyperctl中的任务参数并创建实验来运行。 它把读取的参数送给方法hypergbm.make_experiment去构建实验并运行实验。

值得注意的点:

  1. hypergbm.make_experiment的参数train_data, eval_data, test_data需要的是DataFrame数据对象,在配置文件中 我们需要把这几个参数替换成数据文件地址,数据文件可以是csv或者parquet格式。

  2. 在job中配置的参数run_kwargs 是用来运行实验而非构建实验,也就是会送给方法hypernets.experiment.compete.CompeteExperiment.run

使用Hyperctl训练HyerGBM实验

这一节演示如何使用Hyperctl调用HyperGBM训练一个二分类数据集。

首先创建一个目录,后续的操作在此目录中进行:

mkdir /tmp/hyperctl-example
cd /tmp/hyperctl-example

下载训练用到的数据集heart-disease-uci 文件:

# curl -O heart-disease-uci.csv https://raw.githubusercontent.com/DataCanvasIO/Hypernets/master/hypernets/tabular/datasets/heart-disease-uci.csv
python -c "from hypernets.tabular.datasets.dsutils import load_heart_disease_uci;load_heart_disease_uci().to_csv('heart-disease-uci.csv', index=False)"

创建hyperctl任务配置文件 batch.json 并写入以下配置:

{
    "jobs": [
        {
            "params": {
                "train_data": "/tmp/hyperctl-example/heart-disease-uci.csv",
                "target": "target",
                "log_level": "info",
                "run_kwargs": {
                  "max_trials": 10
                }
            },
            "execution": {
                "command": "python -m hypergbm.job"
            }
        }
    ]
}

运行任务:

hyperctl run --config ./batch.json

通过Notebook使用HyperGBM

HyperGBM与HyperBoard 整合使您在notebook使用使用HyperGBM时可以:

  1. 查看实验配置信息

  2. 查看实验数据集信息

  3. 查看实验运行信息

注意,这些特性依赖HyperBoard并且是可选的,如果要使用请确认您已经安装过了notebook相关依赖,如果没有您可以通过以下命令补充安装:

pip install hboard-widget
可视化HyperGBM的实验

这是一个例子是关于如何在Jupyter Notebook 使用HyperGBM实验可视化。

  1. 导入模块

import warnings
warnings.filterwarnings('ignore')

from hypernets.utils import logging

from sklearn.model_selection import train_test_split

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils
  1. 构建实验并可视化实验配置

df = dsutils.load_bank()

df_train, df_test = train_test_split(df, test_size=0.8, random_state=42)

experiment = make_experiment(df_train, target='y')
experiment

_images/hypergbm_experiment_config.png

  1. 可视化实验数据集信息

experiment.plot_dataset()

_images/hypergbm_experiment_dataset.png

  1. 可视化实验运行信息

experiment.run(max_trials=20)

_images/hypergbm_experiment_process.png

这个Notebook的例子在72.hypegbm_experiment_notebook_visualization.ipynb

使用示例

基础应用

本节通过示例讲解如何使用实验进行模型训练,示例中使用数据集blood,该数据集中的目标列Class,数据如下:

Recency,Frequency,Monetary,Time,Class
2,50,12500,98,1
0,13,3250,28,1
1,16,4000,35,1
2,20,5000,45,1
1,24,6000,77,0
4,4,1000,4,0

...

本节示例从hypernets.tabular中加载该数据集。

以缺省配置创建并运行实验

利用工具make_experiment可快速创建一个可运行的实验对象,执行该实验对象的run方法即可开始训练并得到模型。使用该工具时只有实验数据train_data是必须的,其它都是可选项。数据的目标列如果不是y的话,需要通过参数target设置。

示例代码:

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

train_data = dsutils.load_blood()
experiment = make_experiment(train_data, target='Class')
estimator = experiment.run()
print(estimator)

输出:

Pipeline(steps=[('data_clean',
                 DataCleanStep(...),
                ('estimator',
                 GreedyEnsemble(...)])

可以看出,训练得到的是一个Pipeline,最终模型是由多个模型构成的融合模型。

如果您的训练数据是csv或parquet格式,而且数据文件的扩展名是“.csv”或“.parquet”的话,可以直接使用文件路径创建实验,make_experiment会自动将数据加载为DataFrame,如:

from hypergbm import make_experiment

train_data = '/path/to/mydata.csv'
experiment = make_experiment(train_data, target='my_target')
estimator = experiment.run()
print(estimator)
设置最大搜索次数(max_trials)

缺省情况下,make_experiment所创建的实验最多搜索10种参数便会停止搜索。实际使用中,建议将最大搜索次数设置为30以上。

from hypergbm import make_experiment

train_data = ...
experiment = make_experiment(train_data, max_trials=50)
...
交叉验证

可通过参数cv指定是否启用交叉验证。当cv设置为False时表示禁用交叉验证并使用经典的train_test_split方式进行模型训练;当cv设置为True时表示开启交叉验证,折数可通过参数num_folds设置(默认:3)。

启用交叉验证的示例代码:

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

train_data = dsutils.load_blood()
experiment = make_experiment(train_data, target='Class', cv=True, num_folds=5)
estimator = experiment.run()
print(estimator)
指定验证数据集(eval_data)

在禁用交叉验证时,模型训练除了需要训练数据集,还需要评估数据集,您可在make_experiment时通过eval_data指定评估集,如:

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils
from sklearn.model_selection import train_test_split

train_data = dsutils.load_blood()
train_data,eval_data=train_test_split(train_data,test_size=0.3)
experiment = make_experiment(train_data, target='Class', eval_data=eval_data, cv=False)
estimator = experiment.run()
print(estimator)

在禁用交叉验证时,如果您未指定eval_data,实验对象将从train_data中拆分部分数据作为评估集,拆分大小可通过eval_size设置,如:

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

train_data = dsutils.load_blood()

experiment = make_experiment(train_data, target='Class', cv=False, eval_size=0.2)
estimator = experiment.run()
print(estimator)
指定模型的评价指标

使用make_experiment创建实验时,分类任务默认的模型评价指标是accuracy,回归任务默认的模型评价指标是rmse,可通过参数reward_metric指定,如:

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

train_data = dsutils.load_blood()
experiment = make_experiment(train_data, target='Class', reward_metric='auc')
estimator = experiment.run()
print(estimator)
设置搜索次数和早停(Early Stopping)策略

使用make_experiment时,可通过参数early_stopping_roundsearly_stopping_time_limitearly_stopping_reward设置实验的早停策略。

将搜索时间设置为最多3小时的示例代码:

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

train_data = dsutils.load_blood()

experiment = make_experiment(train_data, target='Class', max_trials=300, early_stopping_time_limit=3600 * 3)
estimator = experiment.run()
print(estimator)
指定搜索算法(Searcher)

HyperGBM通过Hypernets中的搜索算法进行参数搜索,包括:EvolutionSearcher(缺省)、MCTSSearcher、RandomSearch,在make_experiment时可通过参数searcher指定,可以指定搜索算法的类名(class)、搜索算法的名称(str)。

示例代码:

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

train_data = dsutils.load_blood()

experiment = make_experiment(train_data, target='Class', searcher='random')
estimator = experiment.run()
print(estimator)

您也可以自己创建searcher对象,然后用所创建的对象创建实验,如:

from hypergbm import make_experiment
from hypergbm.search_space import search_space_general
from hypernets.searchers import MCTSSearcher
from hypernets.tabular.datasets import dsutils

my_searcher = MCTSSearcher(lambda: search_space_general(n_estimators=100),
                           max_node_space=20,
                           optimize_direction='max')

train_data = dsutils.load_blood()

experiment = make_experiment(train_data, target='Class', searcher=my_searcher)
estimator = experiment.run()
print(estimator)
启用trial库

在利用HyperGBM进行实验时,可在优化搜索时将每个trial的信息保存到trial库中;对于相同数据集,后续实验在优化过程中如果遇到相同参数的trial时,HyperGBM会直接复用之前训练的结果而不需要重新训练模型。 使用 make_experiment 创建实验时可通过 trial_store 指定trail库的存储路径。

train_data = ...
experiment = make_experiment(train_data, trial_store='/tmp/trial_store', ...)
模型融合

为了获取较好的模型效果,make_experiment创建实验时默认开启了模型融合的特性,并使用效果最好的20个模型进行融合,可通过参数ensemble_size指定参与融合的模型的数量。当ensemble_size设置为0时则表示禁用模型融合。

调整参与融合的模型数量的示例代码:

train_data = ...
experiment = make_experiment(train_data, ensemble_size=10, ...)
调整并行度

在并行计算的环节,HyperGBM 默认将会使用所有CPU进行计算。在使用 make_experiment 创建实验时可通过参数 n_jobs 控制 HyperGBM 的线程数(或进程数)。

train_data = ...
experiment = make_experiment(train_data, n_jobs=10, ...)
调整日志级别

如果希望在训练过程中看到使用进度信息的话,可通过log_level指定日志级别,可以是strint。关于日志级别的详细定义可参考python的logging包。 另外,如果将verbose设置为1的话,可以得到更详细的信息。

将日志级别设置为INFO的示例代码如下:

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

train_data = dsutils.load_blood()
experiment = make_experiment(train_data, target='Class', log_level='INFO', verbose=1)
estimator = experiment.run()
print(estimator)

输出:

14:24:33 I hypernets.tabular.u._common.py 30 - 2 class detected, {0, 1}, so inferred as a [binary classification] task
14:24:33 I hypergbm.experiment.py 699 - create experiment with ['data_clean', 'drift_detection', 'space_search', 'final_ensemble']
14:24:33 I hypergbm.experiment.py 1262 - make_experiment with train data:(748, 4), test data:None, eval data:None, target:Class
14:24:33 I hypergbm.experiment.py 716 - fit_transform data_clean
14:24:33 I hypergbm.experiment.py 716 - fit_transform drift_detection
14:24:33 I hypergbm.experiment.py 716 - fit_transform space_search
14:24:33 I hypernets.c.meta_learner.py 22 - Initialize Meta Learner: dataset_id:7123e0d8c8bbbac8797ed9e42352dc59
14:24:33 I hypernets.c.callbacks.py 192 - 
Trial No:1
--------------------------------------------------------------
(0) estimator_options.hp_or:                                0
(1) numeric_imputer_0.strategy:                 most_frequent
(2) numeric_scaler_optional_0.hp_opt:                    True


...

14:24:35 I hypergbm.experiment.py 716 - fit_transform final_ensemble
14:24:35 I hypergbm.experiment.py 737 - trained experiment pipeline: ['data_clean', 'estimator']
Pipeline(steps=[('data_clean',
                 DataCleanStep(...),
                ('estimator',
                 GreedyEnsemble(...)
实验可视化

如果希望在训练过程中看到实验可视化信息,可通过webui打开实验可视化服务,可以是TrueFalse。 还可以通过webui_options参数设置web服务的端口、实验可视化数据持久化目录、是否退出web进程当训练完毕后。

注意:使用该功能时请确保您是通过pip install hypergbm[board] 安装的hypergbm。

开启基于web的实验可视化示例代码如下:

from sklearn.model_selection import train_test_split

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

df = dsutils.load_bank()
df_train, df_test = train_test_split(df, test_size=0.8, random_state=42)

experiment = make_experiment(df_train, target='y', webui=True)
estimator = experiment.run(max_trials=10)

print(estimator)

输出:

02-17 19:08:48 I hypernets.t.estimator_detector.py 85 - EstimatorDetector error: GPU Tree Learner was not enabled in this build.
Please recompile with CMake option -DUSE_GPU=1
...
server is running at: 0.0.0.0:8888 
...

02-17 19:08:55 I hypernets.t.metrics.py 153 - calc_score ['auc', 'accuracy'], task=binary, pos_label=yes, classes=['no' 'yes'], average=None
final result:{'auc': 0.8913467492260062, 'accuracy': 0.8910699474702792}

这时候您可以打开浏览器访问http://localhost:8888 查看实验运行情况:

_images/experiment-web-visualization.png

以将开启训练可视化,并把端口设置为8888,持久化目录设置为./events,实验结束后退出web进程设置为False 的代码示例如下:

...
webui_options = {
    'event_file_dir': "./events",  # persist experiment running events log to './events'
    'server_port': 8888, # http server port
    'exit_web_server_on_finish': False  # exit http server after experiment finished
}
experiment = make_experiment(df_train, target='y', webui=True, webui_options=webui_options)
...

高级应用

HyperGBM make_experiment 所创建的是 Hypernets 的 CompeteExeriment 实例,CompeteExeriment 具备很多建模的高级特性,本章逐一介绍。

flowchart LR da[数<br/>据<br/>适<br/>配] dc[数<br/>据<br/>清<br/>洗] fg[特征衍生] cd[共线性检测] dd[漂移检测] fs[特征筛选] s1[优化搜索] pi[二阶段<br/>特征筛选] pl[伪标签] s2[二阶段<br/>优化搜索] em[模<br/>型<br/>融<br/>合] op2[op] subgraph 一阶段 direction LR subgraph op direction TB cd-->dd dd-->fs end fg-->op op-->s1 end subgraph 二阶段 direction LR subgraph op2 direction TB pi-->pl end op2-->s2 end da-->dc-->一阶段-->二阶段-->em style 二阶段 stroke:#6666,stroke-width:2px,stroke-dasharray: 5, 5; style 二阶段 stroke:#6666,stroke-width:2px,stroke-dasharray: 5, 5;
数据适配

此步骤仅当输入数据是pandas或cudf的数据类型时生效,该步骤检测是否有足够的系统内存容纳输入数据进行建模,如果发现内存不足则尝试对输入数据进行缩减。可通过如下参数对数据适配的细节进行调整:

  • data_adaption:(default True),是否开启数据适配

  • data_adaption_memory_limit:(default 0.05),将输入数据缩减到系统可用内存的多大比例

  • data_adaption_min_cols:(default 0.3),如果需要缩减数据的话,至少保留多少列

  • data_adaption_target:(default None),此选项仅当输入数据是pandas DataFrame时生效,将此选项设置为’cuml’或’cuda’则会利用主机的CPU和MEM对数据进行缩减,然后转换为cudf.DataFrame,使得后续实验步骤在GPU中运行

数据清洗

CompeteExeriment 利用Hypernets的DataCleaner进行数据清洗,此步骤不可禁用,但可通过参数对DataCleaner的行为进行调整,包括:

  • nan_chars: value or list, (default None), 将哪些值字符替换为np.nan

  • correct_object_dtype: bool, (default True), 是否尝试修正数据类型

  • drop_constant_columns: bool, (default True), 是否删除常量列

  • drop_duplicated_columns: bool, (default False), 是否删除重复列

  • drop_idness_columns: bool, (default True), 是否删除id列

  • drop_label_nan_rows: bool, (default True), 是否删除目标列为np.nan的行

  • replace_inf_values: (default np.nan), 将np.inf替换为什么值

  • drop_columns: list, (default None), 强行删除哪些列

  • reserve_columns: list, (default None), 数据清洗时保留哪些列不变

  • reduce_mem_usage: bool, (default False), 是否尝试降低对内存的需求

  • int_convert_to: bool, (default ‘float’), 将int列转换为何种类型,None表示不转换

调用 make_expperiment 时,可通过参数 data_cleaner_args 对DataCleaner的配置进行调整。

假设,训练数据中用字符’\N’表示nan,希望在数据清洗阶段将其替换为np.nan,则可如下设置:

from hypergbm import make_experiment

train_data = ...
experiment = make_experiment(train_data, target='...',
                            data_cleaner_args={'nan_chars': r'\N'})
...
特征衍生

CompeteExeriment 中提供了特征衍生的能力, 在通过 make_experiment 创建实验时设置 feature_generation=True 即可,与之匹配的选项包括:

  • feature_generation_continuous_cols:list (default None)), 参与特征衍生的初始连续型特征,如果为None则依据训练数据的特征类型自行推断。

  • feature_generation_categories_cols:list (default None)), 参与特征衍生的初始类别型特征,需要明确指定,CompeteExeriment 不会自行推断参与特征衍生的初始类别型特征。

  • feature_generation_datetime_cols:list (default None), 参与特征衍生的初始日期型特征,如果为None则依据训练数据的特征类型自行推断。

  • feature_generation_latlong_cols:list (default None), 参与特征衍生的经纬度特征,如果为None则依据训练数据自行推断。说明:经纬度特征列的数据格式必须是 tuple(lat,long)

  • feature_generation_text_cols:list (default None), 参与特征衍生的初始文本性特征,如果为None则依据训练数据自行推断。

  • feature_generation_trans_primitives:list (default None), 用于特征衍生的算子,如果为None则依据特征类型自行推断所采用的算子。

当feature_generation_trans_primitives=None时,CompeteExeriment 依据参与特征衍生的初始特征自行推断所采用的算子,针对不同类型的特征采取不同算子,如下:

  • continuous_cols: 无(需自行指定)。

  • categories_cols: cross_categorical。

  • datetime_cols: month、week、day、hour、minute、second、weekday、is_weekend。

  • latlong_cols: haversine、geohash

  • text_cols:tfidf

启用特征衍生的示例代码:

from hypergbm import make_experiment

train_data = ...
experiment = make_experiment(train_data,
                           feature_generation=True,
                           ...)
...

关于特征衍生的更多信息请参考 [featuretools](https://docs.featuretools.com/).

共线性检测

有时训练数据中会出现一些相关度很高的特征,这些并没有提供太多的信息量,相反,数据集拥有更多的特征意味着更容易收到噪声的影响,更容易收到特征偏移的影响等等。

CompeteExeriment 中提供了删除发生共线性的特征的能力, 在通过 make_experiment 创建实验时设置 collinearity_detection=True 即可。

启用共线性检测的示例代码:

from hypergbm import make_experiment

train_data = ...
experiment = make_experiment(train_data, target='...', collinearity_detection=True)
...
漂移检测

数据漂移是建模过程中的一个主要挑战。当数据的分布随着时间在不断的发现变化时,模型的表现会越来越差,CompeteExeriment 中引入了对抗验证的方法专门处理数据漂移问题。这个方法会自动的检测是否发生漂移,并且找出发生漂移的特征并删除他们,以保证模型在真实数据上保持良好的状态。

为了开启飘逸检测,使用 make_experiment 创建实验时需要设置 drift_detection=True (缺省)并提供测试集 test_data

漂移检测相关的参数包括:

  • drift_detection_remove_shift_variable : bool, (default=True),是否首先检查每一列数据的稳定性。

  • drift_detection_variable_shift_threshold : float, (default=0.7),稳定性指标高于该阈值的列将被删除

  • drift_detection_threshold : float, (default=0.7),检测指标高于该阈值的列将被删除。

  • drift_detection_remove_size : float, (default=0.1),每一轮检测所删除的列占总列数的比例。

  • drift_detection_min_features : int, (default=10),至少保留多少列。

  • drift_detection_num_folds : int, (default=5),在漂移检测阶段训练模型时的cv折数。

需要注意的是,启用漂移检测时必须指定 test_data (不包含目标列), 示例代码:

from io import StringIO
import pandas as pd
from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils

test_data = """
Recency,Frequency,Monetary,Time
2,10,2500,64
4,5,1250,23
4,9,2250,46
4,5,1250,23
4,8,2000,40
2,12,3000,82
11,24,6000,64
2,7,1750,46
4,11,2750,61
1,7,1750,57
2,11,2750,79
2,3,750,16
4,5,1250,26
2,6,1500,41
"""

train_data = dsutils.load_blood()
test_df = pd.read_csv(StringIO(test_data))
experiment = make_experiment(train_data, test_data=test_df,
                             drift_detection=True,
                             ...)

...
特征筛选

进行特征筛选也是建模过程中的一个重要环节,CompeteExeriment 通过训练一个常规模型对训练数据的特征重要性进行评估,进而筛选出最重要的特征参与到后续模型训练中。

在通过 make_experiment 创建实验时设置 feature_selection=True 可开启特征筛选,与之匹配的选项包括:

  • feature_selection_strategy:str, 筛选策略(default threshold), 可用的策略包括 thresholdnumberquantile

  • feature_selection_threshold:float, (default 0.1), 当策略为 threshold 时的筛选阈值,重要性高于该阈值的特征会被选择。

  • feature_selection_quantile:float, (default 0.2), 当策略为 quantile 时的筛选阈值,重要性分位高于该阈值的特征会被选择。

  • feature_selection_number:int or float, (default 0.8), 当策略为 number 时,筛选的特征数量。

启用特征筛选的示例代码:

from hypergbm import make_experiment

train_data=...
experiment = make_experiment(train_data,
                             feature_selection=True,
                             feature_selection_strategy='quantile',
                             feature_selection_quantile=0.3,
                             ...)
降采样预搜索

通常,在进行模型参数优化搜索时是使用全部训练数据进行模型训练的,当数据量较大时使用全部训练数据进行模型训练会消耗较长的时间,为此可通过降采样减少参与模型训练的数据量,进行预搜索,以便在相同的时间内尝试更多的模型参数;然后从预搜索结果中挑选表现较好的参数再利用全量数据进行训练和评估,进一步筛选最佳的模型参数。

通过 make_experiment 创建实验时,设置 down_sample_search=True 可开启预搜索,与之相关的选项包括:

  • down_sample_search_size:int, float(0.0~1.0) or dict (default 0.1), 参与预搜索的样本数量。对于分类任务,可通过dict指定每个类别数据的采样数量。

  • down_sample_search_time_limit:int, (default early_stopping_time_limit*0.33), 预搜索的时间限制。

  • down_sample_search_max_trials:int, (default max_trials*3), 预搜索的最大尝试次数。

启用预搜索的示例代码:

from hypergbm import make_experiment

train_data=...
experiment = make_experiment(train_data,
                             down_sample_search=True,
                             down_sample_search_size=0.2,
                             ...)
二阶段特征筛选

CompeteExperiment 支持在模型参数优化搜索之后,利用得到的模型对训练数据进行处理,然后再次进行模型参数优化搜索,即 二阶段搜索。目前 CompeteExperiment 支持的第二阶段数据处理方式包括二阶段特征筛选和伪标签,本章余下的两个小节中分别介绍。

CompeteExperiment 中,二阶段特征筛选是指从第一阶段选择若干表现较好的模型,进行 permutation_importance 评估,然后筛选出重要的特征。

通过 make_experiment 创建实验时,设置 feature_reselection=True 可开启二阶段特征筛选,与之相关的配置项包括:

  • feature_reselection_estimator_size:int, (default=10), 用于评估特征重要性的模型数量(在一阶段搜索中表现最好的n个模型)。

  • feature_reselection_strategy:str, 筛选策略(default threshold), 可用的策略包括 thresholdnumberquantile

  • feature_reselection_threshold:float, (default 1e-5), 当策略为 threshold 时的筛选阈值,重要性高于该阈值的特征会被选择。

  • feature_reselection_quantile:float, (default 0.2), 当策略为 quantile 时的筛选阈值,重要性分位高于该阈值的特征会被选择。

  • feature_reselection_number:int or float, (default 0.8), 当策略为 number 时,筛选的特征数量。

启用二阶段特征筛选的示例代码:

from hypergbm import make_experiment

train_data=...
experiment = make_experiment(train_data,
                             feature_reselection=True,
                             ...)

关于 permutation_importance 的更多信息请参考 [scikit-learn](https://scikit-learn.org/stable/modules/permutation_importance.html)

伪标签

伪标签是一种半监督学习技术,将测试集中未观测标签列的特征数据通过一阶段训练的模型预测标签后,将置信度高于一定阈值的样本添加到训练数据中重新训练模型,有时候可以进一步提升模型在新数据上的拟合效果。

在通过 make_experiment 创建实验时设置 pseudo_labeling=True 可开启伪标签训练,与之相关的配置项包括:

  • pseudo_labeling_strategy:str, 筛选策略(default threshold), 可用的策略包括 thresholdnumberquantile

  • pseudo_labeling_proba_threshold:float(default 0.8), 当策略为 threshold 时的筛选阈值,置信度高于该阈值的样本会被选择。

  • pseudo_labeling_proba_quantile:float(default 0.8), 当策略为 quantile 时的筛选阈值,置信度分位高于该阈值的样本会被选择。

  • pseudo_labeling_sample_number:float(0.0~1.0) or int (default 0.2), 当策略为 number 时,对样本按置信度高低排序后选择的样本数(top n)。

  • pseudo_labeling_resplit:bool(default=False), 添加新的伪标签数据后是否重新分割训练集和评估集. 如果为False, 直接把所有伪标签数据添加到训练集中重新训练模型,否则把训练集、评估集及伪标签数据合并后重新分割。

启用伪标签技术的示例代码:

from hypergbm import make_experiment

train_data=...
test_data=...
experiment = make_experiment(train_data,
                             test_data=test_data,
                             pseudo_labeling=True,
                             ...)

说明: 伪标签 仅对分类任务有效。

处理不平衡数据

数据不平衡也是业务建模过程中的一个重要挑战,数据的不平衡往往会导致建模效果不理想。HyperGBM 在建模时支持两种类型的不平衡数据处理方式,下面分别介绍。

利用ClassWeight建模

在利用底层建模算法(如lightgbm等)建模时,首先计算样本分布比例,然后利用底层算法对模型进行优化。

为了利用ClassWeight建模,在调用make_experiment时,设置参数class_balancing=‘ClassWeight’即可,示例如下:

from hypergbm import make_experiment

train_data = ...
experiment = make_experiment(train_data,
                             class_balancing='ClassWeight',
                             ...)

欠采样或过采样

在建模之前,通过欠采样或过采样技术调整样本数据,然后再利用调整后的数据进行建模,以得到表现较好的模型。目前支持的采样策略包括:RandomOverSamplerSMOTEADASYNRandomUnderSamplerNearMissTomekLinksEditedNearestNeighbours

为了利用欠采样或过采样技建模,在调用make_experiment时,设置参数class_balancing=‘<采用策略>’即可,示例如下:

from hypergbm import make_experiment

train_data = ...
experiment = make_experiment(train_data,
                             class_balancing='SMOTE',
                             ...)

关于欠采样或过采样技术的更多信息,请参考 imbalanced-learn

自定义SearchSpace

make_experiment缺省使用的搜索空间是search_space_general,定义如下:

search_space_general = GeneralSearchSpaceGenerator(n_estimators=200)
自定义搜索空间(SearchSpace)

在调用make_experiment时可通过参数search_space指定自定义的搜索空间。如:指定xgboostmax_depth=20

from hypergbm import make_experiment
from hypergbm.search_space import GeneralSearchSpaceGenerator

my_search_space = \
    GeneralSearchSpaceGenerator(n_estimators=200, xgb_init_kwargs={'max_depth': 20})

train_data = ...

experiment = make_experiment(train_data,
                             search_space=my_search_space,
                             ...)

如果您希望自定义的参数是可搜索的,推荐定义GeneralSearchSpaceGenerator的一个子类,比如:指定xgboostmax_depth在10、20、30之间搜索:

from hypergbm import make_experiment
from hypergbm.search_space import GeneralSearchSpaceGenerator
from hypernets.core.search_space import Choice

class MySearchSpace(GeneralSearchSpaceGenerator):
    @property
    def default_xgb_init_kwargs(self):
        return { **super().default_xgb_init_kwargs,
                'max_depth': Choice([10, 20 ,30]),
        }

my_search_space = MySearchSpace()
train_data = ...

experiment = make_experiment(train_data, 
                             search_space=my_search_space,
                             ...)
自定义建模算法

HyperGBM实现了对XGBoost、LightGBM、CatBoost和HistGridientBoosting的支持,并作为SearchSpace的一部分在建模优化时进行搜索。如果您需要增加对其他算法的支持,则需要:

  • 将您选择的算法封装为HyperEstimator的子类

  • 将封装后的算法增加到SearchSpace中,并定义搜索参数

  • 在make_experiment中年使用您自定义的SearchSpace

示例:

from sklearn import svm

from hypergbm import make_experiment
from hypergbm.estimators import HyperEstimator
from hypergbm.search_space import GeneralSearchSpaceGenerator
from hypernets.core.search_space import Choice, Int, Real
from hypernets.tabular.datasets import dsutils


class SVMEstimator(HyperEstimator):
    def __init__(self, fit_kwargs, C=1.0, kernel='rbf', gamma='auto', degree=3, random_state=666, probability=True,
                 decision_function_shape=None, space=None, name=None, **kwargs):
        if C is not None:
            kwargs['C'] = C
        if kernel is not None:
            kwargs['kernel'] = kernel
        if gamma is not None:
            kwargs['gamma'] = gamma
        if degree is not None:
            kwargs['degree'] = degree
        if random_state is not None:
            kwargs['random_state'] = random_state
        if decision_function_shape is not None:
            kwargs['decision_function_shape'] = decision_function_shape
        kwargs['probability'] = probability
        HyperEstimator.__init__(self, fit_kwargs, space, name, **kwargs)

    def _build_estimator(self, task, kwargs):
        if task == 'regression':
            hsvm = SVMRegressorWrapper(**kwargs)
        else:
            hsvm = SVMClassifierWrapper(**kwargs)
        hsvm.__dict__['task'] = task
        return hsvm


class SVMClassifierWrapper(svm.SVC):
    def fit(self, X, y=None, **kwargs):
        return super().fit(X, y)


class SVMRegressorWrapper(svm.SVC):
    def fit(self, X, y=None, **kwargs):
        return super().fit(X, y)


class GeneralSearchSpaceGeneratorPlusSVM(GeneralSearchSpaceGenerator):
    def __init__(self, enable_svm=True, **kwargs):
        super(GeneralSearchSpaceGeneratorPlusSVM, self).__init__(**kwargs)
        self.enable_svm = enable_svm

    @property
    def default_svm_init_kwargs(self):
        return {
            'C': Real(0.1, 5, 0.1),
            'kernel': Choice(['rbf', 'poly', 'sigmoid']),
            'degree': Int(1, 5),
            'gamma': Real(0.0001, 5, 0.0002)
        }

    @property
    def default_svm_fit_kwargs(self):
        return {}

    @property
    def estimators(self):
        r = super().estimators
        if self.enable_svm:
            r['svm'] = (SVMEstimator, self.default_svm_init_kwargs, self.default_svm_fit_kwargs)
        return r


my_search_space = GeneralSearchSpaceGeneratorPlusSVM()

train_data = dsutils.load_blood()
experiment = make_experiment(train_data, target='Class',
                             search_space=my_search_space)
estimator = experiment.run()
print(estimator)

GPU加速

为了使用 NVIDIA GPU 加速 HyperGBM 训练过程,您需要安装 NVIDIA RAPIDS 中的 cuML 和 cuDF , 同时也需要安装支持 GPU 的LightGBM、XGBoost、CatBoost, 关于软件安装的信息请参考 安装HyperGBM

加速实验

为了在HyperGBM训练中启用GPU加速,您只需要将数据加载为cudf的DataFrame,然后将将其作为参数train_dataeval_datatest_data传递给工具方法 make_experiment,该方法会自动检测数据类型并配置适合使用GPU训练的实验。

示例:

import cudf

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils


def train():
    train_data = cudf.from_pandas(dsutils.load_blood())

    experiment = make_experiment(train_data, target='Class')
    estimator = experiment.run()
    print(estimator)


if __name__ == '__main__':
    train()

输出:

LocalizablePipeline(steps=[('data_clean',
                            DataCleanStep(cv=True,
                                          name='data_cle...
                            CumlGreedyEnsemble(weight=[...]))])

需要注意的是,此时训练得到的estimator是一个 LocalizablePipeline 而不是常见的sklearn Pipeline。LocalizablePipeline支持使用cudf DataFrame作为输入数据进行 predict 和 predict_proba。同时在生产环境部署 LocalizablePipeline 时需要安装与训练环境相同的软件,包括cuML、cuDF等。

如果您希望在没有cuML、cuDF的环境中部署模型的话,可调用 LocalizablePipelineas_local方法将其转化为sklearn Pipeline,示例:

import cudf

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils


def train():
    train_data = cudf.from_pandas(dsutils.load_blood())

    experiment = make_experiment(train_data, target='Class')
    estimator = experiment.run()
    print(estimator)

    print('-' * 20)
    estimator = estimator.as_local()
    print('localized estimator:\n', estimator)


if __name__ == '__main__':
    train()

输出:

LocalizablePipeline(steps=[('data_clean',
                            DataCleanStep(cv=True,
                                          name='data_cle...
                            CumlGreedyEnsemble(weight=[...]))])
--------------------
localized estimator:
 Pipeline(steps=[('data_clean',
                 DataCleanStep(cv=True,
                               name='data_clean')),
                ('est...
                 GreedyEnsemble(weight=[...]))])

自定义搜索空间

在启用GPU加速时,自定义的搜索空间中所有Transformer和Estimator都要求能够同时支持pandas和cudf的DataFrame,您可以以hypergbm.cuml中的 earch_space_generalCumlGeneralSearchSpaceGenerator 为基础定义自己的搜索空间。

示例:

import cudf

from hypergbm import make_experiment
from hypergbm.cuml import search_space_general
from hypernets.tabular.datasets import dsutils


def my_search_space():
    return search_space_general(n_estimators=100)


def train():
    train_data = cudf.from_pandas(dsutils.load_blood())

    experiment = make_experiment(train_data, target='Class', searcher='mcts', search_space=my_search_space)
    estimator = experiment.run()
    print(estimator)


if __name__ == '__main__':
    train()

分布式训练

快速实验

HyperGBM支持使用Dask进行分布式训练,在运行实验之前您需要部署Dask集群并初始化Dask客户端Client对象; 然后使用dask提供的方法将数据加载为Dask DataFrame然后创建实验。

示例代码(以单节点为例,假设您的训练数据文件是‘/opt/data/my_data.csv’):

from dask import dataframe as dd
from dask.distributed import LocalCluster, Client

from hypergbm import make_experiment


def train():
    cluster = LocalCluster(processes=True)
    client = Client(cluster)

    train_data_file = '/opt/data/my_data.csv'
    train_data = dd.read_csv(train_data_file)
    train_data = train_data.persist()
    
    experiment = make_experiment(train_data, target='...')
    estimator = experiment.run()
    print(estimator)


if __name__ == '__main__':
    train()

对于大规模数据,为了加速数据的加载过程,建议您将数据拆分为多个文件并保存在一个目录下(如:/opt/data/my_data/),然后使用目录下的文件创建实验,如:

from dask import dataframe as dd
from dask.distributed import LocalCluster, Client

from hypergbm import make_experiment


def train():
    cluster = LocalCluster(processes=True)
    client = Client(cluster)

    train_data_files = '/opt/data/my_data/*.parquet'
    train_data = dd.read_parquet(train_data_files)
    train_data = train_data.persist()
    
    experiment = make_experiment(train_data, target='...')
    estimator = experiment.run()
    print(estimator)


if __name__ == '__main__':
    train()

关于使用Dask DataFrame的更多信息请参考Dask官方文档中的 Create DataFrames

自定义SearchSpace

在Dask环境下运行实验时,搜索空间中使用的Transformer和Estimator必须都支持Dask数据类型,您可以参考或基于HyperGBM内置的支持Dask的搜索空间定义自己的搜索空间。

from dask import dataframe as dd
from dask.distributed import LocalCluster, Client

from hypergbm import make_experiment
from hypergbm.dask.search_space import search_space_general
from hypernets.tabular.datasets import dsutils


def my_search_space():
    return search_space_general(n_estimators=100)


def train():
    cluster = LocalCluster(processes=False)
    client = Client(cluster)

    train_data = dd.from_pandas(dsutils.load_blood(), npartitions=1)

    experiment = make_experiment(train_data, target='Class', searcher='mcts', search_space=my_search_space)
    estimator = experiment.run()
    print(estimator)


if __name__ == '__main__':
    train()


Multi-objectives optimization

优化算法和内置优化目标:

NSGA-II Searcher example

This is an example about how using NSGAIISearcher for multi-objectives optimization.

1. Import modules and prepare data
[1]:
from hypernets.utils import logging as hyn_logging
from hypernets.searchers.nsga_searcher import RNSGAIISearcher

from hypergbm import make_experiment

from hypernets.tabular import get_tool_box
from hypernets.tabular.datasets import dsutils
from hypernets.core.random_state import get_random_state

#hyn_logging.set_level(hyn_logging.WARN)
random_state = get_random_state()

df = dsutils.load_bank().head(1000)
tb = get_tool_box(df)
df_train, df_test = tb.train_test_split(df, test_size=0.2, random_state=9527)
2. Run an experiment within NSGAIISearcher
[2]:
experiment = make_experiment(df_train,
                             eval_data=df_test.copy(),
                             callbacks=[],
                             random_state=1234,
                             search_callbacks=[],
                             target='y',
                             searcher='nsga2',  # available MOO searcher: moead, nsga2, rnsga2
                             searcher_options={'population_size': 10},
                             reward_metric='logloss',
                             objectives=['nf'],
                             early_stopping_rounds=10)

estimators = experiment.run(max_trials=10)
hyper_model = experiment.hyper_model_
hyper_model.searcher
[2]:
NSGAIISearcher(objectives=[PredictionObjective(name=logloss, scorer=make_scorer(log_loss, needs_proba=True), direction=min), NumOfFeatures(name=nf, sample_size=1000, direction=min)], recombination=SinglePointCrossOver(random_state=RandomState(MT19937))), mutation=SinglePointMutation(random_state=RandomState(MT19937), proba=0.7)), survival=<hypernets.searchers.nsga_searcher._RankAndCrowdSortSurvival object at 0x000002177944F6A0>), random_state=RandomState(MT19937)
3. Summary trails
[3]:
df_trials = hyper_model.history.to_df().copy().drop(['scores', 'reward'], axis=1)
df_trials[df_trials['non_dominated'] == True]
[3]:
trial_no succeeded elapsed non_dominated model_index reward_logloss reward_nf
0 1 True 0.461761 True 0.0 0.256819 0.3750
3 4 True 3.794317 True 1.0 0.540632 0.0000
4 5 True 0.321852 True 2.0 0.217409 0.6875
7 8 True 1.844163 True 3.0 0.164959 0.9375
8 9 True 1.606298 True 4.0 0.190964 0.8750
9 10 True 0.716679 True 5.0 0.218916 0.4375
4. Plot pareto font

We can pick model accord to Decision Maker’s preferences from the pareto plot, the number in the figure indicates the index of pipeline models.

[4]:
fig, ax  = hyper_model.history.plot_best_trials()
fig.show()
_images/examples_61.NSGAII_example_8_0.png
5. Plot population
[5]:
fig, ax  = hyper_model.searcher.plot_population()
fig.show()
_images/examples_61.NSGAII_example_10_0.png
6. Evaluate the selected model
[6]:
print(f"Number of pipeline: {len(estimators)} ")

pipeline_model = estimators[0]  # selection the first pipeline model
X_test = df_test.copy()
y_test = X_test.pop('y')

preds = pipeline_model.predict(X_test)
proba = pipeline_model.predict_proba(X_test)

tb.metrics.calc_score(y_test, preds, proba, metrics=['auc', 'accuracy', 'f1', 'recall', 'precision'], pos_label="yes")
Number of pipeline: 6
[6]:
{'auc': 0.826357886904762,
 'accuracy': 0.84,
 'f1': 0.23809523809523808,
 'recall': 0.15625,
 'precision': 0.5}
[ ]:

RNSGA-II Searcher example

This is an example about how using RNSGAIISearcher for multi-objectives optimization.

1. Import modules and prepare data
[1]:
from hypernets.core.random_state import set_random_state
set_random_state(1234)



from hypernets.utils import logging as hyn_logging
from hypernets.examples.plain_model import PlainModel, PlainSearchSpace
from hypergbm import make_experiment

from hypernets.tabular import get_tool_box
from hypernets.tabular.datasets import dsutils
from hypernets.tabular.sklearn_ex import MultiLabelEncoder

#hyn_logging.set_level(hyn_logging.WARN)
df = dsutils.load_bank().head(1000)
tb = get_tool_box(df)
df_train, df_test = tb.train_test_split(df, test_size=0.2, random_state=9527)
2. Run an experiment within NSGAIISearcher
[2]:
import numpy as np


experiment = make_experiment(df_train,
                             eval_data=df_test.copy(),
                             callbacks=[],
                             random_state=1234,
                             search_callbacks=[],
                             target='y',
                             searcher='rnsga2',  # available MOO searchers: moead, nsga2, rnsga2
                             searcher_options=dict(ref_point=np.array([0.1, 2 ]), weights=np.array([0.1, 2]), population_size=10),
                             reward_metric='logloss',
                             objectives=['nf'],
                             early_stopping_rounds=30,
                             drift_detection=False)

estimators = experiment.run(max_trials=30)
hyper_model = experiment.hyper_model_
hyper_model.searcher
[2]:
RNSGAIISearcher(objectives=[PredictionObjective(name=logloss, scorer=make_scorer(log_loss, needs_proba=True), direction=min), NumOfFeatures(name=nf, sample_size=1000, direction=min)], recombination=SinglePointCrossOver(random_state=RandomState(MT19937))), mutation=SinglePointMutation(random_state=RandomState(MT19937), proba=0.7)), survival=_RDominanceSurvival(ref_point=[0.1 2. ], weights=[0.1 2. ], threshold=0.3, random_state=RandomState(MT19937))), random_state=RandomState(MT19937)
3. Summary trails
[3]:
df_trials = hyper_model.history.to_df().copy().drop(['scores', 'reward'], axis=1)
df_trials[df_trials['non_dominated'] == True]
[3]:
trial_no succeeded elapsed non_dominated model_index reward_logloss reward_nf
4 5 True 0.386380 True 0.0 0.217409 0.625
9 10 True 0.798336 True 1.0 0.218916 0.4375
11 12 True 0.682108 True 2.0 0.287458 0.0
14 15 True 0.455569 True 3.0 0.221304 0.375
26 28 True 0.568367 True 4.0 0.045741 0.9375
28 30 True 0.407018 True 5.0 0.141022 0.6875
4. Plot pareto font

We can pick model accord to Decision Maker’s preferences from the pareto plot, the number in the figure indicates the index of pipeline models.

[4]:
fig, ax  = hyper_model.history.plot_best_trials()
fig.show()
_images/examples_62.RNSGAII_example_8_0.png
5. Plot population
[5]:
fig, ax  = hyper_model.searcher.plot_population()
fig.show()
_images/examples_62.RNSGAII_example_10_0.png
6. Evaluate the selected model
[6]:
print(f"Number of pipeline: {len(estimators)} ")

pipeline_model = estimators[0]  # selection the first pipeline model
X_test = df_test.copy()
y_test = X_test.pop('y')

preds = pipeline_model.predict(X_test)
proba = pipeline_model.predict_proba(X_test)

tb.metrics.calc_score(y_test, preds, proba, metrics=['auc', 'accuracy', 'f1', 'recall', 'precision'], pos_label="yes")
Number of pipeline: 6
[6]:
{'auc': 0.8417038690476191,
 'accuracy': 0.855,
 'f1': 0.17142857142857143,
 'recall': 0.09375,
 'precision': 1.0}
MOEA/D Searcher example

This is an example about how using MOEADSearcher for multi-objectives optimization.

1. Import modules and prepare data
[1]:
from hypernets.core.random_state import set_random_state
set_random_state(1234)

from hypernets.utils import logging as hyn_logging
from hypernets.examples.plain_model import PlainModel, PlainSearchSpace
from hypernets.searchers.nsga_searcher import RNSGAIISearcher

from hypergbm import make_experiment

from hypernets.tabular import get_tool_box
from hypernets.tabular.datasets import dsutils
from hypernets.tabular.sklearn_ex import MultiLabelEncoder


hyn_logging.set_level(hyn_logging.WARN)

df = dsutils.load_bank().head(1000)
tb = get_tool_box(df)
df_train, df_test = tb.train_test_split(df, test_size=0.2, random_state=9527)
2. Run an experiment within NSGAIISearcher
[2]:
experiment = make_experiment(df_train,
                             eval_data=df_test.copy(),
                             callbacks=[],
                             random_state=1234,
                             search_callbacks=[],
                             target='y',
                             searcher='moead',  # available MOO searcher: moead, nsga2, rnsga2
                             reward_metric='logloss',
                             objectives=['nf'],
                             drift_detection=False,
                             early_stopping_rounds=30)

estimators = experiment.run(max_trials=30)
hyper_model = experiment.hyper_model_
hyper_model.searcher
[2]:
MOEADSearcher(objectives=[PredictionObjective(name=logloss, scorer=make_scorer(log_loss, needs_proba=True), direction=min), NumOfFeatures(name=nf, sample_size=1000, direction=min)], n_neighbors=2, recombination=SinglePointCrossOver(random_state=RandomState(MT19937)), mutation=SinglePointMutation(random_state=RandomState(MT19937), proba=0.7), population_size=6)
3. Summary trails
[3]:
df_trials = hyper_model.history.to_df().copy().drop(['scores', 'reward'], axis=1)
df_trials[df_trials['non_dominated'] == True]
[3]:
trial_no succeeded elapsed non_dominated model_index reward_logloss reward_nf
4 5 True 0.446323 True 0.0 0.217409 0.625
6 7 True 4.100305 True 1.0 0.537368 0.0
8 9 True 4.796208 True 2.0 0.253515 0.125
9 10 True 1.060251 True 3.0 0.246395 0.5625
22 30 True 0.366623 True 4.0 0.177716 0.75
4. Plot pareto font

We can pick model accord to Decision Maker’s preferences from the pareto plot, the number in the figure indicates the index of pipeline models.

[4]:
fig, ax  = hyper_model.history.plot_best_trials()
fig.show()
_images/examples_63.MOEAD_example_8_0.png
5. Plot population
[5]:
fig, ax  = hyper_model.searcher.plot_population()
fig.show()
_images/examples_63.MOEAD_example_10_0.png
6. Evaluate the selected model
[6]:
print(f"Number of pipeline: {len(estimators)} ")

pipeline_model = estimators[0]  # selection the first pipeline model
X_test = df_test.copy()
y_test = X_test.pop('y')

preds = pipeline_model.predict(X_test)
proba = pipeline_model.predict_proba(X_test)

tb.metrics.calc_score(y_test, preds, proba, metrics=['auc', 'accuracy', 'f1', 'recall', 'precision'], pos_label="yes")
Number of pipeline: 5
[6]:
{'auc': 0.8417038690476191,
 'accuracy': 0.855,
 'f1': 0.17142857142857143,
 'recall': 0.09375,
 'precision': 1.0}
Automatically convert metric to negatives for minimize
[7]:
experiment = make_experiment(df_train,
                             eval_data=df_test.copy(),
                             callbacks=[],
                             random_state=1234,
                             search_callbacks=[],
                             target='y',
                             pos_label="yes",
                             searcher='moead',
                             reward_metric='accuracy',
                             objectives=['precision'],
                             drift_detection=False,
                             early_stopping_rounds=30)

estimators = experiment.run(max_trials=30)
hyper_model = experiment.hyper_model_
hyper_model.history.to_df().copy().drop(['scores', 'reward'], axis=1)[:5]
[7]:
trial_no succeeded elapsed non_dominated model_index reward_accuracy reward_precision
0 1 True 0.645476 False NaN -0.91 -0.777778
1 2 True 0.752835 False NaN -0.8975 -0.0
2 3 True 0.779298 False NaN -0.8975 -0.0
3 4 True 0.737511 False NaN -0.905 -0.625
4 5 True 0.498275 False NaN -0.90625 -0.733333
[ ]:

Objectives example
Import modules and prepare data
[1]:
from hypernets.core.random_state import set_random_state
set_random_state(1234)

from hypernets.utils import logging as hyn_logging
from hypergbm import make_experiment

from hypernets.tabular import get_tool_box
from hypernets.tabular.datasets import dsutils


hyn_logging.set_level(hyn_logging.WARN)

df = dsutils.load_bank().head(10000)
tb = get_tool_box(df)
df_train, df_test = tb.train_test_split(df, test_size=0.2, random_state=9527)
Number Of Features objective example

This is an example about how using NumOfFeatures to reduce model complexity

[2]:
import numpy as np

experiment = make_experiment(df_train,
                             eval_data=df_test.copy(),
                             callbacks=[],
                             search_callbacks=[],
                             target='y',
                             searcher='nsga2',  # available MOO searchers: moead, nsga2, rnsga2
                             reward_metric='logloss',
                             objectives=['nf'],  # use NumberOfFeatures as objective
                             drift_detection=False)

estimators = experiment.run(max_trials=30)
[3]:
df_trials = experiment.hyper_model_.history.to_df()
df_trials[df_trials['non_dominated'] == True][['trial_no', 'succeeded', 'non_dominated', 'reward_logloss', 'reward_nf', 'model_index']]
[3]:
trial_no succeeded non_dominated reward_logloss reward_nf model_index
9 10 True True 0.283389 0.0 0.0
17 18 True True 0.25848 0.5 1.0
18 19 True True 0.199278 0.8125 2.0
25 26 True True 0.125533 0.9375 3.0
Prediction performance objective example
[4]:
experiment = make_experiment(df_train,
                             eval_data=df_test.copy(),
                             callbacks=[],
                             search_callbacks=[],
                             target='y',
                             searcher='nsga2',  # available MOO searchers: moead, nsga2, rnsga2
                             reward_metric='logloss',
                             objectives=['pred_perf'],  # use PredictionPerformanceObjective as objective
                             drift_detection=False)
estimators = experiment.run(max_trials=30)
[5]:
df_trials = experiment.hyper_model_.history.to_df()
df_trials[df_trials['non_dominated'] == True][['trial_no', 'succeeded', 'non_dominated', 'reward_logloss', 'reward_pred_perf', 'model_index']]
[5]:
trial_no succeeded non_dominated reward_logloss reward_pred_perf model_index
3 4 True True 0.199202 0.020022 0.0
5 6 True True 0.121710 0.022027 1.0
Feature usage objective example

example of automatically feature selection

[6]:
experiment = make_experiment(df_train,
                             eval_data=df_test.copy(),
                             callbacks=[],
                             search_callbacks=[],
                             target='y',
                             searcher='nsga2',  # available MOO searchers: moead, nsga2, rnsga2
                             reward_metric='logloss',
                             objectives=['feature_usage'],
                             drift_detection=False)
estimators = experiment.run(max_trials=30)
[7]:
df_trials = experiment.hyper_model_.history.to_df()
df_trials[df_trials['non_dominated'] == True].drop(['reward', 'scores'], axis=1)
[7]:
trial_no succeeded elapsed non_dominated model_index reward_logloss reward_feature_usage
4 5 True 0.491640 True 0.0 0.285834 0.1875
5 6 True 0.912090 True 1.0 0.094966 0.6875
7 8 True 0.493440 True 2.0 0.152629 0.3750
13 14 True 0.387586 True 3.0 0.230497 0.3125

View input features in model

[8]:
model_index = 0
experiment.hyper_model_.history.get_best()[model_index].get_model().data_pipeline[0].features[0][1].steps[0][1].important_features
[8]:
[('duration', 1712.328210838139),
 ('month', 429.7665938436985),
 ('age', 313.9162983652204)]
PSI objective example
[9]:
experiment = make_experiment(df_train,
                             test_data=df_test.copy().drop('y', axis=1),
                             eval_data=df_test.copy(),
                             callbacks=[],
                             search_callbacks=[],
                             target='y',
                             searcher='nsga2',  # available MOO searchers: moead, nsga2, rnsga2
                             reward_metric='logloss',
                             objectives=['psi'],
                             drift_detection=False)
estimators = experiment.run(max_trials=30)
[10]:
df_trials = experiment.hyper_model_.history.to_df()
df_trials[df_trials['non_dominated'] == True].drop(['reward', 'scores'], axis=1)
[10]:
trial_no succeeded elapsed non_dominated model_index reward_logloss reward_psi
3 4 True 0.474756 True 0.0 0.107476 0.0
[ ]:

How-To

如何在centos7上安装shap?

  1. 安装系统依赖

    yum install epel-release centos-release-scl -y  && yum clean all && yum make cache # llvm9.0 is in epel, gcc9 in scl
    yum install -y llvm9.0 llvm9.0-devel python36-devel devtoolset-9-gcc devtoolset-9-gcc-c++ make cmake 
    
  2. 配置安装环境

    whereis llvm-config-9.0-64  # find your `llvm-config` path
    # llvm-config-9: /usr/bin/llvm-config-9.0-64
    
    export LLVM_CONFIG=/usr/bin/llvm-config-9.0-64  # set to your path
    scl enable devtoolset-9 bash
    
  3. 安装shap

    pip -v install numpy==1.19.1  # prepare shap dependency
    pip -v install scikit-learn==0.23.1  # prepare shap dependency
    pip -v install shap==0.28.5
    

如何安装cuML及相关包?

cuML是英伟达 RAPIDS 框架中的一部分 ,使用GPU进行模型训练时,HyperGBM利用cuML(及cuDF)进行数据预处理。依据RAPIDS官方资料,可以通过conda、docker或源代码安装/使用RAPIDS(或特定组件)。推荐使用conda安装cuML和HyperGBM。

  1. 需要考虑的因素:

    • 操作系统:目前RAPIDS只支持Linux,您可以从Ubuntu、CentOS、RHEL中选择

    • CUDA版本:目前RAPIDS支持的CUDA版本包括11.0、11.2、11.4、11.5(请从RAPIDS官网获取最新信息),请确保您的系统中已经安装了能够被支持的CUDA驱动

    • RAPIDS版本:推荐使用21.10或以上的稳定版本

    • Python版本:推荐使用Python3.8

  2. 安装cuML及HyperGBM

    通过conda命令安装 cuML和 HyperGBM,示例:

    conda create -n hypergbm_with_cuml -c rapidsai -c nvidia -c conda-forge python=3.8 cudatoolkit=11.2 cudf=21.12 cuml=21.12  hypergbm 
    

    注意,请将示例命令中的软件版本替换为适您的选项。

更多关于RAPIDS的信息请参考RAPIDS官方网站 https://rapids.ai/

如何在HyperGBM中自定义评价指标?

您可通过如下方式其定义一个新的模型评价指标:

  1. 定义一个参数 为 y_true and y_preds 的函数 (not lambda)

  2. 使用您定义的函数创建一个 sklearn scorer

  3. 使用您定义的评价函数和scorer创建实验

参考示例:

from sklearn.metrics import make_scorer, accuracy_score

from hypergbm import make_experiment
from hypernets.tabular.datasets import dsutils


def foo(y_true, y_preds):
    return accuracy_score(y_true, y_preds)  # replace this line with yours

my_scorer = make_scorer(foo, greater_is_better=True, needs_proba=False)

train_data = dsutils.load_adult()
train_data.columns = [f'c{i}' for i in range(14)] + ['target']

exp = make_experiment(train_data.copy(), target='target',
                      reward_metric=foo,
                      scorer=my_scorer,
                      max_trials=3,
                      log_level='info')
estimator = exp.run()
print(estimator)

如何在HyperGBM中自定义存储空间?

HyperGBM 在运行时将中间数据(缓存数据、模型文件等)存储在系 work_dir 中, 默认情况下 work_dir时系统临时目录下的一个子目录。


  • 设置 work_dir 位置

    您可以通过修改系统临时目录来调整 work_dir 的位置,另外您也可以通过如下方式设置work_dir的位置

  1. 在您运行HyerGBM的工作目录中创建一个子目录 conf

  2. conf 目录下创建文件 storage.py ,在其中指定 work_dir 的位置,如下:

    c.StorageCfg.root = '/your/full/path/for/work_dir'
    
  3. 按照常规方式使用HyperGBM


  • 使用兼容 s3 的对象存储作为 work_dir

  1. 安装s3fs

  2. 在您运行HyerGBM的工作目录中创建一个子目录 conf

  3. conf 目录下创建文件 storage.py ,在其中配置s3存储的信息,示例如下:

    c.StorageCfg.kind = 's3'
    c.StorageCfg.root = '/bucket_name/some_path'
    c.StorageCfg.options = """
    {
            "anon": false,
            "client_kwargs": {
                    "endpoint_url": "your_service_address",
                    "aws_access_key_id": "your_access_key",
                    "aws_secret_access_key": "your_secret_access_key"
            }
    }
    """
    

    关于s3存储的详细配置信息请参考 s3fs 的 官方文档

如何在Kaggle中使用HyperGBM?

Kaggle中提供了在线notebook方便用户进行数据处理和模型训练,您可以在Kaggle的notebook中安装并使用HyperGBM。建议使用pip 在kaggle的notebook安装HyperGBM。

需要注意的是,由于kaggle的notebook中默认安装了许多软件,其中个别软件的依赖与HyperGBM的依赖有冲突,建议 在安装HyperGBM之前先卸载这些软件。您可首先尝试安装HyperGBM,然后根据pip命令 的提示信息检查哪些软件与HyperGBM有冲突,重启notebook并删除存在冲突的软件后再试尝试安装HyperGBM。

实际使用示例可参考 notebook_hypergbm_bank_marketing_kaggle

如何在Kaggle中通过GPU运行HyperGBM实验?

Kaggle中为每个用户提供免费的GPU资源(有时间限制),HyperGBM支持通过GPU运行实验以加速训练过程。

  • 确保您还有可用的GPU时间(GPU hours)

_images/kaggle_gpu_hours.pngDataCanvas AutoML Toolkit

  • 在您的Notebook设置中启用GPU加速

_images/kaggle_gpu_setting.pngDataCanvas AutoML Toolkit

  • 通过cudf加载数据并用cudf.DataFrame创建和运行HyperGBM实验

    train_data=cudf.read_xxx('...')
    experiment=make_experiment(train_data,...)
    estimator=experiment.run()
    

实际使用示例可参考 notebook_hypergbm_bank_marketing_gpu_kaggle

Release Notes

历史:

Version 0.3.0

本次发布优化及新增的特性:

  • 多目标优化

    • 优化算法
      • 新增MOEA/D(基于分解的多目标优化框架)

      • 新增目标分解方法: Tchebycheff, Weighted Sum, Penalty-based boundary intersection approach(PBI)

      • 新增适用于遗传算法的交叉算子: shuffle crossover, uniform crossover, single point crossover

      • 动态归一化不同量纲目标

      • 自动将最大化问题转换为最小化问题

      • 新增NSGA-II(非支配解快速排序算法)

      • 新增R-NSGA-II(为决策偏好提供支持的多目标优化算法)

    • 内置目标
      • 使用到特征估计

      • 预测性能

Version 0.2.5

本次发布优化及新增的特性:

  • 支持全Pipeline的GPU加速,包括

    • 数据适配

    • 数据清洗

    • 特征筛选

    • 漂移检测

    • 二阶段特征筛选

    • 伪标签

    • 模型优化

      • 数据预处理

      • 模型训练

    • 模型融合

    • 模型评价

  • 模型训练

    • 类别型特征的编码方式增加TargetEncoder

    • 根据实验的reward_metric自动调整模型训练时的eval_metric

    • 支持将自定义python函数作为实验的reward_metric

  • 高级特性

    • 根据服务器内存或GPU内存限额对实验数据进行缩减

  • 可视化

    • 基于Web网页的实验可视化

  • 调度工具

    • 集成Hyperctl, 通过配置运行HyperGBM的实验

  • 实验报告

    • 导出excel实验报告

Version 0.2.3

本次发布优化及新增的特性:

  • 数据清洗

    • 支持从数据类型为数值型的特征中自动识别类别列

    • 可指定在数据清洗时对某些列不做处理

  • 特征衍生

    • 增加对时间、文本、经纬度类型的支持

    • 增加对分布式的支持

  • 建模算法

    • XGBoost:分布式建模从 dask_xgboost 迁移到 xgboost.dask ,与XGBoost官网保值一致

    • LightGBM:增加对多机分布式的支持

  • 模型训练

    • 搜索过程可复现

    • 支持低保真搜索

    • 基于统计信息预测学习曲线

    • 支持非侵入式超参数优化

    • EarlyStopping时间限制的范围调整为对整个实验的训练周期

    • 训练时支持自定义pos_label

    • 分布式场景下,eval-set支持Dask数据集

    • 优化模型训练中间结果的缓存策略

  • 搜索算法

    • 增加GridSearch算法

    • 增加Playback算法

  • 高级特性

    • 增加一阶段特征筛选并支持多种策略

    • 二阶段特征筛选支持多种策略

    • 伪标签支持多种数据筛选策略,并增加对多分类的支持

    • 优化概念漂移处理的执行性能

    • 增加对高级特性执行中间结果的缓存机制

  • 可视化

    • 实验信息可视化

    • 训练过程可视化

  • 命令行工具

    • 模型训练时可通过命令行参数支持实验的大部分特性

    • 支持模型评价

    • 支持模型预测

Version 0.2.2

本次发布新增以下特性:

特征工程

  • 特征衍生

  • 特征降维

数据清洗

  • 特殊空值字符处理

  • 列类型校正

  • 常量列清理

  • 重复列清理

  • 删除标签列为空的样本

  • 非法值替换

  • id列清理

  • 共线性特征清理

数据集拆分

  • 对抗验证

建模算法

  • XGBoost

  • Catboost

  • LightGBM

  • HistGridientBoosting

模型训练

  • 自动任务类型推断

  • 命令行工具

评估方法

  • 交叉验证(Cross-Validation)

  • Train-Validation-Holdout验证

搜索算法

  • 蒙特卡洛树算法

  • 进化算法

  • 随机搜索算法

不平衡数据处理

  • 类平衡(Class Weight)

  • 降采样(Under -Samping)支持

    • Near miss

    • Tomeks links

    • Random

  • 过采样(Over-Samping)支持

    • SMOTE

    • ADASYN

    • Random

提前停止策略

  • n次搜索都不再提升,提前停止

  • 最大用时提前停止

  • 到达预期指标提前停止

高级特性

  • 二阶段搜索

    • 伪标签

    • 特征选择

  • 概念漂移处理

  • 模型融合

ces and tables