{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"## 05. 实现一个简单的AutoML系统"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"### AutoML系统的顶层设计"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"我们在上个教程中,学习到了UltraOpt的设计哲学是将优化器与评价器分离,如图所示:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from graphviz import Digraph; g = Digraph()\n",
"g.node(\"config space\", shape=\"ellipse\"); g.node(\"optimizer\", shape=\"box\")\n",
"g.node(\"config\", shape=\"ellipse\"); g.node(\"loss\", shape=\"circle\"); g.node(\"evaluator\", shape=\"box\")\n",
"g.edge(\"config space\", \"optimizer\", label=\"initialize\"); g.edge(\"optimizer\", \"config\", label=\"<ask>\", color='blue')\n",
"g.edge(\"config\",\"evaluator\" , label=\"send to\"); g.edge(\"evaluator\",\"loss\" , label=\"evaluate\")\n",
"g.edge(\"config\", \"optimizer\", label=\"<tell>\", color='red'); g.edge(\"loss\", \"optimizer\", label=\"<tell>\", color='red')\n",
"g.graph_attr['rankdir'] = 'LR'; g"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"而当我们要解决AutoML问题时,我们可以这样定义AutoML系统结构:"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"![AutoML Structure](https://img-blog.csdnimg.cn/20201225225241790.jpg)"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"### 用HDL定义一个简单的AutoML配置空间"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"在`03. Conditional Parameter`教程中,我们知道了AutoML问题的优化可以视为一个CASH问题,不仅涉及算法选择,还涉及超参优化。我们用HDL定义一个简单的CASH问题的配置空间:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"pycharm": {}
},
"outputs": [],
"source": [
"from ultraopt.hdl import hdl2cs, plot_hdl, layering_config, plot_layered_dict\n",
"HDL = {\n",
" 'classifier(choice)':{\n",
" \"LinearSVC\": {\n",
" \"max_iter\": {\"_type\": \"int_quniform\",\"_value\": [300, 3000, 100], \"_default\": 600},\n",
" \"penalty\": {\"_type\": \"choice\", \"_value\": [\"l1\", \"l2\"],\"_default\": \"l2\"},\n",
" \"dual\": {\"_type\": \"choice\", \"_value\": [True, False],\"_default\": False},\n",
" \"loss\": {\"_type\": \"choice\", \"_value\": [\"hinge\", \"squared_hinge\"],\"_default\": \"squared_hinge\"},\n",
" \"C\": {\"_type\": \"loguniform\", \"_value\": [0.01, 10000],\"_default\": 1.0},\n",
" \"multi_class\": \"ovr\",\n",
" \"random_state\": 42,\n",
" \"__forbidden\": [\n",
" {\"penalty\": \"l1\",\"loss\": \"hinge\"},\n",
" {\"penalty\": \"l2\",\"dual\": False,\"loss\": \"hinge\"},\n",
" {\"penalty\": \"l1\",\"dual\": False},\n",
" {\"penalty\": \"l1\",\"dual\": True,\"loss\": \"squared_hinge\"},\n",
" ]\n",
" },\n",
" \"RandomForestClassifier\": {\n",
" \"n_estimators\": {\"_type\": \"int_quniform\",\"_value\": [10, 200, 10], \"_default\": 100},\n",
" \"criterion\": {\"_type\": \"choice\",\"_value\": [\"gini\", \"entropy\"],\"_default\": \"gini\"},\n",
" \"max_features\": {\"_type\": \"choice\",\"_value\": [\"sqrt\",\"log2\"],\"_default\": \"sqrt\"},\n",
" \"min_samples_split\": {\"_type\": \"int_uniform\", \"_value\": [2, 20],\"_default\": 2},\n",
" \"min_samples_leaf\": {\"_type\": \"int_uniform\", \"_value\": [1, 20],\"_default\": 1},\n",
" \"bootstrap\": {\"_type\": \"choice\",\"_value\": [True, False],\"_default\": True},\n",
" \"random_state\": 42\n",
" },\n",
" \"KNeighborsClassifier\": {\n",
" \"n_neighbors\": {\"_type\": \"int_loguniform\", \"_value\": [1,100],\"_default\": 3},\n",
" \"weights\" : {\"_type\": \"choice\", \"_value\": [\"uniform\", \"distance\"],\"_default\": \"uniform\"},\n",
" \"p\": {\"_type\": \"choice\", \"_value\": [1, 2],\"_default\": 2},\n",
" },\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"CS = hdl2cs(HDL)\n",
"g = plot_hdl(HDL)\n",
"g.graph_attr['size'] = \"15,8\"\n",
"g"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"### 定义一个简单的AutoML评价器"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"在定义好了配置空间之后,现在我们来看评价器。\n",
"\n",
"在UltraOpt的设计哲学中,评价器可以是一个类(实现`__call__`魔法方法),也可以是个函数。但其必须满足:\n",
"\n",
"- 接受 `dict` 类型参数 `config` \n",
"- 返回 `float` 类型参数 `loss` \n",
"\n",
"在AutoML问题中,评价器的工作流程如下:\n",
"1. 将config转化为一个机器学习模型\n",
"2. 在训练集上对机器学习模型进行训练\n",
"3. 在验证集上得到相应的评价指标\n",
"4. 对评价指标进行处理,使其`越小越好`,返回`loss`\n",
"\n",
"在了解了这些知识后,我们来开发 **AutoML 评价器**"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"为了方便同学们理解,我们先顺序地将之前提到的**AutoML 评价器**工作流程跑一遍:\n",
"\n",
"#### Step 1. 将config转化为一个机器学习模型"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"pycharm": {}
},
"outputs": [],
"source": [
"# 引入 sklearn 的分类器\n",
"from sklearn.svm import LinearSVC\n",
"from sklearn.ensemble import RandomForestClassifier\n",
"from sklearn.neighbors import KNeighborsClassifier"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"假设评价器传入了一个 `config` 参数,我们先通过获取配置空间默认值(也可以对配置空间 `CS` 对象进行采样)得到 `config`"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"text/plain": [
"{'classifier:__choice__': 'LinearSVC',\n",
" 'classifier:LinearSVC:C': 1.0,\n",
" 'classifier:LinearSVC:dual': 'True:bool',\n",
" 'classifier:LinearSVC:loss': 'squared_hinge',\n",
" 'classifier:LinearSVC:max_iter': 600,\n",
" 'classifier:LinearSVC:multi_class': 'ovr',\n",
" 'classifier:LinearSVC:penalty': 'l2',\n",
" 'classifier:LinearSVC:random_state': '42:int'}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"config = CS.get_default_configuration().get_dictionary()\n",
"config"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"我们用**配置分层函数** `ultraopt.hdl.layering_config` 处理这个配置"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"text/plain": [
"{'classifier': {'LinearSVC': {'C': 1.0,\n",
" 'dual': True,\n",
" 'loss': 'squared_hinge',\n",
" 'max_iter': 600,\n",
" 'multi_class': 'ovr',\n",
" 'penalty': 'l2',\n",
" 'random_state': 42}}}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"layered_dict = layering_config(config)\n",
"layered_dict"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot_layered_dict(layered_dict)"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"我们需要获取这个配置的如下信息:\n",
"\n",
"- 算法选择的结果\n",
"- 被选择算法对应的参数"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"text/plain": [
"'LinearSVC'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"AS_HP = layered_dict['classifier'].copy()\n",
"AS, HP = AS_HP.popitem()\n",
"AS # 算法选择的结果"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"text/plain": [
"{'C': 1.0,\n",
" 'dual': True,\n",
" 'loss': 'squared_hinge',\n",
" 'max_iter': 600,\n",
" 'multi_class': 'ovr',\n",
" 'penalty': 'l2',\n",
" 'random_state': 42}"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"HP # 被选择算法对应的参数"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"根据 **算法选择结果** + **对应的参数** 实例化一个 **机器学习对象**"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"text/plain": [
"LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,\n",
" intercept_scaling=1, loss='squared_hinge', max_iter=600,\n",
" multi_class='ovr', penalty='l2', random_state=42, tol=0.0001,\n",
" verbose=0)"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ML_model = eval(AS)(**HP)\n",
"ML_model # 实例化的机器学习对象"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"#### Step 2. 在训练集上对机器学习模型进行训练"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {}
},
"source": [
"我们采用MNIST手写数字数据集的一个子集来作为训练数据:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"pycharm": {}
},
"outputs": [],
"source": [
"from sklearn.datasets import load_digits\n",
"import seaborn as sns\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"X, y = load_digits(return_X_y=True)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"pycharm": {}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"