调参神器:Hyperopt

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gg_18826075157/article/details/78068086

调参神器:Hyperopt

1.概述

hyperopt是一个Python库,主要使用①随机搜索算法/②模拟退火算法/③TPE算法来对某个算法模型的最佳参数进行智能搜索,它的全称是Hyperparameter Optimization。

如果我们要确定某个算法模型的最佳参数,通常会使用网格搜索(GridSearch),即假如有两个参数A和B,它们分别有 NA NB 个取值(人为设定),那么我们则需要依次枚举这些取值的所有组合情况(在这里是共 NANB 种),然后取准确率最高的那一个作为最终这个算法模型的最优参数。

显然,如果要枚举的组合情况非常多,网格搜索将变得十分低效,甚至不可接受。那么本文要介绍的hyperopt可以理解为一个智能化的网格搜索,能大大缩短调参所需的时间。

2.实例演示

既然谈起python和机器学习,自然少不了scikit-learn,那么下面将演示如何使用hyperopt来对scikit-learn的SVM分类器进行调参的详细过程。

#coding:utf-8
from hyperopt import fmin, tpe, hp, rand
import numpy as np
from sklearn.metrics import accuracy_score
from sklearn import svm
from sklearn import datasets

# SVM的三个超参数:C为惩罚因子,kernel为核函数类型,gamma为核函数的额外参数(对于不同类型的核函数有不同的含义)
# 有别于传统的网格搜索(GridSearch),这里只需要给出最优参数的概率分布即可,而不需要按照步长把具体的值给一个个枚举出来
parameter_space_svc ={
    # loguniform表示该参数取对数后符合均匀分布
    'C':hp.loguniform("C", np.log(1), np.log(100)),
    'kernel':hp.choice('kernel',['rbf','poly']),
    'gamma': hp.loguniform("gamma", np.log(0.001), np.log(0.1)),
}

# 鸢尾花卉数据集,是一类多重变量分析的数据集
# 通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类
iris = datasets.load_digits()

#--------------------划分训练集和测试集--------------------
train_data = iris.data[0:1300]
train_target = iris.target[0:1300]
test_data = iris.data[1300:-1]
test_target = iris.target[1300:-1]
#-----------------------------------------------------------

# 计数器,每一次参数组合的枚举都会使它加1
count = 0

def function(args):
    print(args)

    # **可以把dict转换为关键字参数,可以大大简化复杂的函数调用
    clf = svm.SVC(**args)

    # 训练模型
    clf.fit(train_data,train_target)

    # 预测测试集
    prediction = clf.predict(test_data)

    global count
    count = count + 1
    score = accuracy_score(test_target,prediction)
    print("第%s次,测试集正确率为:" % str(count),score)

    # 由于hyperopt仅提供fmin接口,因此如果要求最大值,则需要取相反数
    return -score

# algo指定搜索算法,目前支持以下算法:
# ①随机搜索(hyperopt.rand.suggest)
# ②模拟退火(hyperopt.anneal.suggest)
# ③TPE算法(hyperopt.tpe.suggest,算法全称为Tree-structured Parzen Estimator Approach)
# max_evals指定枚举次数上限,即使第max_evals次枚举仍未能确定全局最优解,也要结束搜索,返回目前搜索到的最优解
best = fmin(function, parameter_space_svc, algo=tpe.suggest, max_evals=100)

# best["kernel"]返回的是数组下标,因此需要把它还原回来
kernel_list = ['rbf','poly']
best["kernel"] = kernel_list[best["kernel"]]

print("最佳参数为:",best)

clf = svm.SVC(**best)
print(clf)

输出结果如下:

{'gamma': 0.0010051585652497248, 'kernel': 'poly', 'C': 29.551164584073586}
第1次,测试集正确率为: 0.959677419355
{'gamma': 0.006498482991283678, 'kernel': 'rbf', 'C': 6.626826808981864}
第2次,测试集正确率为: 0.834677419355
{'gamma': 0.008192671915044216, 'kernel': 'poly', 'C': 34.48947180442318}
第3次,测试集正确率为: 0.959677419355
{'gamma': 0.001359874432712413, 'kernel': 'rbf', 'C': 1.6402360233244775}
第98次,测试集正确率为: 0.971774193548
{'gamma': 0.0029328466160223813, 'kernel': 'poly', 'C': 1.6328276445108112}
第99次,测试集正确率为: 0.959677419355
{'gamma': 0.0015786919481979775, 'kernel': 'rbf', 'C': 4.669133703622153}
第100次,测试集正确率为: 0.969758064516
最佳参数为: {'gamma': 0.00101162002595069, 'kernel': 'rbf', 'C': 21.12514792460218}
SVC(C=21.12514792460218, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma=0.00101162002595069,
  kernel='rbf', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)

猜你喜欢

转载自blog.csdn.net/gg_18826075157/article/details/78068086