zoukankan      html  css  js  c++  java
  • sklearn中的超参数调节

    进行参数的选择是一个重要的步骤。在机器学习当中需要我们手动输入的参数叫做超参数,其余的参数需要依靠数据来进行训练,不需要我们手动设定。进行超参数选择的过程叫做调参。

    进行调参应该有一下准备条件:

    • 一个学习器
    • 一个参数空间
    • 一个从参数空间当中寻找参数的方法
    • 一个交叉验证的规则
    • 一个性能评估的策略

    下面我介绍几种调参的方法:

    1:穷举式的网格搜索

    sklearn当中的GridSearchCV实现了这种穷举是的网格搜索,其实这种方法是很简单的。下面是使用交叉验证来进行网格搜索的一个例子:

    from sklearn import datasets
    from sklearn.model_selection import train_test_split, GridSearchCV
    from sklearn.svm import SVC
    from sklearn.metrics import classification_report
    digits = datasets.load_digits()
    
    n_samples = len(digits.images)
    X = digits.images.reshape((n_samples, -1))
    y = digits.target
    
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.5, random_state=0)
    #上面的操作是导入数据,并且把数据划分为训练数据和测试数据,这里使用的是手写数字识别数据集
    
    tunned_parameters = [{'kernel':['rbf'],'gamma':[1e-3, 1e-4],'C':[1, 10, 100, 1000]},
                         {'kernel':['linear'], 'C':[1, 10, 100, 1000]}]
    
    scores = ['precision', 'recall']   #这是我们使用的评分策略,因为是多分类问题,所以最后的评分策略为precision_macro 和 recall_macro 见下面
    
    for score in scores:
        print("# Tuning hyper-parameters for %s" % score)
        print()
    
        clf = GridSearchCV(SVC(), tunned_parameters, cv=5,
                           scoring='%s_macro' % score)
        clf.fit(X_train, y_train)
    
        print("Best parameters set found on development set:")
        print()
        print(clf.best_params_)
        print()
        print("Grid scores on development set:")
        print()
        means = clf.cv_results_['mean_test_score']
        stds = clf.cv_results_['std_test_score']
        #这里输出了各种参数在使用交叉验证的时候得分的均值和方差
        for mean, std, params in zip(means, stds, clf.cv_results_['params']):
            print("%0.3f (+/-%0.03f) for %r"
                  % (mean, std * 2, params))
        print()
    
        print("Detailed classification report:")
        print()
        print("The model is trained on the full development set.")
        print("The scores are computed on the full evaluation set.")
        print()
        #这里是使用训练出来的最好的参数进行预测
        y_true, y_pred = y_test, clf.predict(X_test)
        print(classification_report(y_true, y_pred))
        print()

    实际当中有用的参数,以clf表示我们的GridSearchCV对象

    clf.best_params_   返回最好的参数

    clf.best_score_  返回最好的测试分数,它的值和 clf.cv_results_['mean_test_score'][dt_grid.best_index_] 是相同的。

    clf.best_index_  返回列表中分数最好的下表

    clf.best_estimator_  返回最好的模型

    grid_scores_     在sklearn 0.18中已经不赞成使用了,用下面的cv_results_来代替

    clf.cv_results_     返回使用交叉验证进行搜索的结果,它本身又是一个字典,里面又有很多内容,我们来看一下上面的clf.cv_results_.keys()里面有什么:

    dict_keys(
    ['mean_fit_time', 'std_fit_time', 'mean_score_time', 'std_score_time', 
    'param_C', 'param_gamma', 'param_kernel', 'params', 
    'split0_test_score', 'split1_test_score', 'split2_test_score', 'split3_test_score', 'split4_test_score',
    'mean_test_score', 'std_test_score', 'rank_test_score', 
    'split0_train_score', 'split1_train_score', 'split2_train_score', 'split3_train_score', 'split4_train_score', 
    'mean_train_score', 'std_train_score'] )

    可以分为上面几类: 第一类是时间, 第二类是参数, 第三类是测试分数,其中又分为每次交叉验证的参数和统计的参数,第四类是训练分数,其中也分为每次交叉验证的参数和统计的参数。

    2: 随机搜索

    随机搜索就是制定参数的随机分布的策略,从这些策略当中随机产生我们需要的参数进行评估。sklearn当中使用RandomizedSearchCV来完成。

    比如下面使用了scipy统计库中的指数分布,其中scale参数制定随机变量的缩放比例。然后RandomizedSearchCV会根据这些分布选取参数

    {'C': scipy.stats.expon(scale=100), 'gamma': scipy.stats.expon(scale=.1),
      'kernel': ['rbf'], 'class_weight':['balanced', None]}

    一个例子是这样的:

    import numpy as np
    
    from time import time
    from scipy.stats import randint as sp_randint
    
    from sklearn.model_selection import RandomizedSearchCV
    from sklearn.datasets import load_digits
    from sklearn.ensemble import RandomForestClassifier
    
    # get some data
    digits = load_digits()
    X, y = digits.data, digits.target
    
    # build a classifier
    clf = RandomForestClassifier(n_estimators=20)
    
    
    # Utility function to report best scores
    def report(results, n_top=3):
        '''
        这是自定义的打印函数,results为一个字典,里面包含训练以后的结果,
        其中rank_test_score为参数排序的结果,下面的代码是根据rank_test_score
        的值取出排名靠前的均值、方差和参数
        '''
        for i in range(1, n_top + 1):
            candidates = np.flatnonzero(results['rank_test_score'] == i)
            for candidate in candidates:
                print("Model with rank: {0}".format(i))
                print("Mean validation score: {0:.3f} (std: {1:.3f})".format(
                    results['mean_test_score'][candidate],
                    results['std_test_score'][candidate]))
                print("Parameters: {0}".format(results['params'][candidate]))
                print("")
    
    
    
    # specify parameters and distributions to sample from
    #这里使用了scipy统计库中的randint分布函数
    param_dist = {"max_depth": [3, None],
                  "max_features": sp_randint(1, 11),
                  "min_samples_split": sp_randint(2, 11),
                  "min_samples_leaf": sp_randint(1, 11),
                  "bootstrap": [True, False],
                  "criterion": ["gini", "entropy"]}
    
    # run randomized search
    n_iter_search = 20
    random_search = RandomizedSearchCV(clf, param_distributions=param_dist,
                                       n_iter=n_iter_search)
    
    start = time()
    random_search.fit(X, y)
    print("RandomizedSearchCV took %.2f seconds for %d candidates"
          " parameter settings." % ((time() - start), n_iter_search))
    report(random_search.cv_results_)
    
    #源代码后面还有一个GridSearchCV代码,这里删除了

    输出结果如下:

    RandomizedSearchCV took 3.38 seconds for 20 candidates parameter settings.
    Model with rank: 1
    Mean validation score: 0.924 (std: 0.006)
    Parameters: {'bootstrap': True, 'criterion': 'entropy', 'max_depth': None, 'max_features': 6, 'min_samples_leaf': 1, 'min_samples_split': 3}
    
    Model with rank: 2
    Mean validation score: 0.922 (std: 0.007)
    Parameters: {'bootstrap': True, 'criterion': 'gini', 'max_depth': None, 'max_features': 7, 'min_samples_leaf': 1, 'min_samples_split': 9}
    
    Model with rank: 3
    Mean validation score: 0.918 (std: 0.015)
    Parameters: {'bootstrap': False, 'criterion': 'entropy', 'max_depth': None, 'max_features': 9, 'min_samples_leaf': 7, 'min_samples_split': 7}

    3:贝叶斯优化(Bayesian optimazation)

    前两种策略属于那种参数的选择的时候相互独立的情况,这种情况并没有完全利用好上一次选择的参数所得到的一些信息。而贝叶斯优化则更好相反,这一类优化充分利用了前面所选择的参数的信息,属于sequential model-based optimization (SMBO)。

    参考:

    浅谈高斯过程回归

    Hyper-parameter tuning for machine learning models

    Tuning the hyper-parameters of an estimator

  • 相关阅读:
    mplayer编程模式控制命令
    设置开发板启动后自启动Qt
    Linux下制作logo并显示到开发板上 .
    启动开发板,提示:can't access tty,job control turned off
    BellmanFord贝尔曼福特算法
    阿拉伯数字转中文数字
    webService
    http请求全过程
    (转)MongoDB设置访问权限、设置用户
    YTC, YTM, YTW
  • 原文地址:https://www.cnblogs.com/jiaxin359/p/8641976.html
Copyright © 2011-2022 走看看