关于人工智能:一种超参数优化技术Hyperopt

6次阅读

共计 5776 个字符,预计需要花费 15 分钟才能阅读完成。

作者 |GUEST BLOG
编译 |VK
起源 |Analytics Vidhya

介绍

在机器学习我的项目中,你须要遵循一系列步骤,直到你达到你的指标,你必须执行的步骤之一就是对你抉择的模型进行超参数优化。此工作总是在模型抉择过程之后实现(抉择性能优于其余模型的最佳模型)。

什么是超参数优化?

在定义超参数优化之前,你须要理解什么是超参数。简言之,超参数是用来管制学习过程的不同参数值,对机器学习模型的性能有显著影响。

随机森林算法中超参数的例子是预计器的数目(n_estimators)、最大深度(max_depth)和准则。这些参数是可调的,能够间接影响训练模型的好坏。

超参数优化就是寻找适合的超参数值组合,以便在正当的工夫内实现对数据的最大性能。它对机器学习算法的预测精度起着至关重要的作用。因而,超参数优化被认为是建设机器学习模型中最艰难的局部。

大多数机器学习算法都带有默认的超参数值。默认值在不同类型的机器学习我的项目中并不总是体现良好,这就是为什么你须要优化它们,以获得最佳性能的正确组合。

好的超参数能够使一个算法发光。

有一些优化超参数的罕用策略:

(a)网格搜寻

这是一种宽泛应用的传统办法,它通过执行超参数调整来确定给定模型的最佳值。网格搜寻通过在模型中尝试所有可能的参数组合来工作,这意味着执行整个搜寻将破费大量工夫,这可能会导致计算成本十分高。

留神:你能够在这里学习如何实现网格搜寻:https://github.com/Davisy/Hyp…

(b)随机搜寻

在超参数值的随机组合用于为构建的模型寻找最佳解决方案时,这种办法的工作形式不同。随机搜寻的毛病是有时会漏掉搜寻空间中的重要点(值)。

留神:你能够在这里理解更多实现随机搜寻的办法:https://github.com/Davisy/Hyp…

超参数优化技术

在本系列文章中,我将向你介绍不同的高级超参数优化技术 / 办法,这些技术 / 办法能够帮忙你取得给定模型的最佳参数。咱们将钻研以下技术。

  • Hyperopt
  • Scikit Optimize
  • Optuna

在本文中,我将重点介绍 Hyperopt 的实现。

什么是 Hyperopt

Hyperopt 是一个弱小的 python 库,用于超参数优化,由 jamesbergstra 开发。Hyperopt 应用贝叶斯优化的模式进行参数调整,容许你为给定模型获得最佳参数。它能够在大范畴内优化具备数百个参数的模型。

Hyperopt 的个性

Hyperopt 蕴含 4 个重要的个性,你须要晓得,以便运行你的第一个优化。

(a)搜寻空间

hyperopt 有不同的函数来指定输出参数的范畴,这些是随机搜寻空间。抉择最罕用的搜寻选项:

  • hp.choice(label, options)- 这可用于分类参数,它返回其中一个选项,它应该是一个列表或元组。示例:hp.choice(“criterion”, [“gini”,”entropy”,])
  • hp.randint(label, upper)- 可用于整数参数,它返回范畴(0,upper)内的随机整数。示例:hp.randint(“max_features”,50)
  • hp.uniform(label, low, high)- 它返回一个介于 low 和 high 之间的值。示例:hp.uniform(“max_leaf_nodes”,1,10)

你能够应用的其余选项包含:

  • hp.normal(label, mu, sigma)- 这将返回一个理论值,该值遵从均值为 mu 和标准差为 sigma 的正态分布
  • hp.qnormal(label, mu, sigma, q)- 返回一个相似 round(normal(mu, sigma) / q) * q 的值
  • hp.lognormal(label, mu, sigma)- 返回 exp(normal(mu, sigma))
  • hp.qlognormal(label, mu, sigma, q) - 返回一个相似 round(exp(normal(mu, sigma)) / q) * q 的值

你能够在这里理解更多的搜寻空间选项:https://github.com/hyperopt/h…

注:每个可优化的随机表达式都有一个标签(例如 n_estimators)作为第一个参数。这些标签用于在优化过程中将参数抉择返回给调用者。

(b)指标函数

这是一个最小化函数,它从搜寻空间接管超参数值作为输出并返回损失。这意味着在优化过程中,咱们应用选定的超参数值训练模型并预测指标特色,而后评估预测误差并将其返回给优化器。优化器将决定要查看哪些值并再次迭代。你将在一个理论例子中学习如何创立一个指标函数。

(c)fmin

fmin 函数是对不同的算法集及其超参数进行迭代,而后使指标函数最小化的优化函数。fmin 有 5 个输出是:

  • 最小化的指标函数
  • 定义的搜寻空间
  • 应用的搜索算法有随机搜寻、TPE(Tree-Parzen 预计器)和自适应 TPE。

    留神:hyperopt.rand.suggest 以及 hyperopt.tpe.suggest 为超参数空间的顺序搜索提供逻辑。

  • 最大评估数
  • trials 对象(可选)

例子:

from hyperopt import fmin, tpe, hp,Trials

trials = Trials()

best = fmin(fn=lambda x: x ** 2,
            space= hp.uniform('x', -10, 10),
            algo=tpe.suggest,
            max_evals=50,
            trials = trials)

print(best)
(d)试验对象

Trials 对象用于保留所有超参数、损失和其余信息,这意味着你能够在运行优化后拜访它们。此外,trials 能够帮忙你保留和加载重要信息,而后持续优化过程。(你将在理论示例中理解更多信息)。

from hyperopt import Trials 

trials = Trials()

在了解了 Hyperopt 的重要个性之后,上面将介绍 Hyperopt 的应用办法。

  • 初始化要搜寻的空间。
  • 定义指标函数。
  • 抉择要应用的搜索算法。
  • 运行 hyperopt 函数。
  • 分析测试对象中存储的评估输入。

实际中的 Hyperpot

当初你曾经理解了 Hyperopt 的重要个性,在这个理论示例中,咱们将应用挪动价格数据集,工作是创立一个模型,预测挪动设施的价格是 0(低成本)或 1(中等老本)或 2(高老本)或 3(十分高老本)。

装置 Hyperopt

你能够从 PyPI 装置 hyperopt。

pip install hyperopt

而后导入重要的软件包

# 导入包
import numpy as np 
import pandas as pd 
from sklearn.ensemble import RandomForestClassifier 
from sklearn import metrics
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler 
from hyperopt import tpe, hp, fmin, STATUS_OK,Trials
from hyperopt.pyll.base import scope

import warnings
warnings.filterwarnings("ignore")

数据集

让咱们从数据目录加载数据集。以获取无关此数据集的更多信息:https://www.kaggle.com/iabhis…

# 加载数据

data = pd.read_csv("data/mobile_price_data.csv")

检查数据集的前五行。

# 读取数据

data.head()

如你所见,在咱们的数据集中,咱们有不同的数值特色。

让咱们察看一下数据集的形态。

# 显示形态

data.shape

(2000, 21)

在这个数据集中,咱们有 2000 行和 21 列。当初让咱们理解一下这个数据集中的特色列表。

# 显示列表 

list(data.columns)
[‘battery_power’,‘blue’,‘clock_speed’,‘dual_sim’,‘fc’,‘four_g’,‘int_memory’,‘m_dep’,‘mobile_wt’,‘n_cores’,‘pc’,‘px_height’,‘px_width’,‘ram’,‘sc_h’,‘sc_w’,‘talk_time’,‘three_g’,‘touch_screen’,‘wifi’,‘price_range’]

你能够在这里找到每个列名的含意:https://www.kaggle.com/iabhis…

将数据集合成为指标特色和独立特色

这是一个分类问题,咱们将从数据集中拆散出指标特色和独立特色。咱们的指标是价格区间。

# 将数据拆分为特色和指标

X = data.drop("price_range", axis=1).values 
y = data.price_range.values

预处理数据集

而后应用 scikit-learn 中的 StandardScaler 办法对独立特色进行标准化。

# 标准化特色变量

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

为优化定义参数空间

咱们将应用随机森林算法的三个超参数,即 n_estimators、max_depth 和 criterion。

space = {"n_estimators": hp.choice("n_estimators", [100, 200, 300, 400,500,600]),
    "max_depth": hp.quniform("max_depth", 1, 15,1),
    "criterion": hp.choice("criterion", ["gini", "entropy"]),
}

咱们在下面抉择的超参数中设置了不同的值。而后定义指标函数。

定义最小化函数(指标函数)

咱们的最小化函数称为超参数调整,优化其超参数的分类算法是随机森林。我应用穿插验证来防止过拟合,而后函数将返回一个损失值及其状态。

# 定义指标函数

def hyperparameter_tuning(params):
    clf = RandomForestClassifier(**params,n_jobs=-1)
    acc = cross_val_score(clf, X_scaled, y,scoring="accuracy").mean()
    return {"loss": -acc, "status": STATUS_OK}

留神:记住 hyperopt 最小化了函数,所以我在 acc 中增加了负号:

微调模型

最初,首先实例化 Trial 对象,对模型进行微调,而后用其超参数值打印出最佳损失。

# 初始化 Trial 对象
trials = Trials()

best = fmin(
    fn=hyperparameter_tuning,
    space = space, 
    algo=tpe.suggest, 
    max_evals=100, 
    trials=trials
)

print("Best: {}".format(best))
100%|█████████████████████████████████████████████████████████| 100/100 [10:30<00:00, 6.30s/trial, best loss: -0.8915] Best: {‘criterion’: 1,‘max_depth’: 11.0,‘n_estimators’: 2}.

在进行超参数优化后,损失为 -0.8915,应用随机森林分类器中的 n_estimators=300,max_depth=11,criterian=“entropy”,模型性能的准确率为 89.15%。

应用 trials 对象剖析后果

trials 对象能够帮忙咱们查看在试验期间计算的所有返回值。

(一)trials.results

这显示搜寻期间“objective”返回的词典列表。

trials.results
[{‘loss’: -0.8790000000000001,‘status’:‘ok’}, {‘loss’: -0.877,‘status’:‘ok’}, {‘loss’: -0.768,‘status’:‘ok’}, {‘loss’: -0.8205,‘status’:‘ok’}, {‘loss’: -0.8720000000000001,‘status’:‘ok’}, {‘loss’: -0.883,‘status’:‘ok’}, {‘loss’: -0.8554999999999999,‘status’:‘ok’}, {‘loss’: -0.8789999999999999,‘status’:‘ok’}, {‘loss’: -0.595,‘status’:‘ok’},…….]
(二)trials.losses()

这显示了一个损失列表

trials.losses()
[-0.8790000000000001, -0.877, -0.768, -0.8205, -0.8720000000000001, -0.883, -0.8554999999999999, -0.8789999999999999, -0.595, -0.8765000000000001, -0.877, ………]
(三)trials.statuses()

这将显示状态字符串的列表。

trials.statuses()
[‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’,‘ok’, ……….]

注:这个试验对象能够保留,传递到内置的绘图例程,或者用你本人的自定义代码进行剖析。

结尾

祝贺你,你曾经实现了这篇文章

你能够在此处下载本文中应用的数据集和笔记本:https://github.com/Davisy/Hyp…

原文链接:https://www.analyticsvidhya.c…

欢送关注磐创 AI 博客站:
http://panchuang.net/

sklearn 机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/

正文完
 0