使用 Hyperopt 進行參數調優(譯)

本文是對Parameter Tuning with Hyperopt一文的翻譯。譯者在設計深度學習模型的網絡結構發現了hyperopt這個大殺器,相比每次手動各種試,用工具批量調節網絡中的各種超參數確實能省心不少。不過hyperopt的官方文檔描述的太渣,google 了一翻,發現這篇博客算是介紹的比較清楚的一個,便順手翻譯了,譯文已取得原作者授權。

正文開始

本文將介紹一種快速有效的方法用于實現機器學習模型的調參。有兩種常用的調參方法:網格搜索和隨機搜索。每一種都有自己的優點和缺點。網格搜索速度慢,但在搜索整個搜索空間方面效果很好,而隨機搜索很快,但可能會錯過搜索空間中的重要點。幸運的是,還有第三種選擇:貝葉斯優化。本文我們將重點介紹貝葉斯優化的一個實現,一個名為hyperopt的 Python 模塊。

使用貝葉斯優化進行調參可以讓我們獲得給定模型的最佳參數,例如邏輯回歸模型。這也使我們能夠執行最佳的模型選擇。通常機器學習工程師或數據科學家將為少數模型(如決策樹,支持向量機和 K 近鄰)執行某種形式(網格搜索或隨機搜索)的手動調參,然后比較準確率并選擇最佳的一個來使用。該方法可能比較的是次優模型。也許數據科學家找到了決策樹的最優參數,但卻錯過了 SVM 的最優參數。這意味著他們的模型比較是有缺陷的。如果 SVM 參數調整得很差,K 近鄰可能每次都會擊敗 SVM。貝葉斯優化允許數據科學家找到所有模型的最佳參數,并因此比較最佳模型。這會得到更好的模型選擇,因為你比較的是最佳的 k 近鄰和最佳的決策樹。只有這樣你才能非常自信地進行模型選擇,確保選擇并使用的是實際最佳的模型。

本文涵蓋的主題有:

  1. 目標函數
  2. 搜索空間
  3. 存儲評估試驗
  4. 可視化
  5. 經典數據集上的完整示例:Iris

要使用下面的代碼,你必須安裝hyperoptpymongo

目標函數 - 一個啟發性例子

假設你有一個定義在某個范圍內的函數,并且想把它最小化。也就是說,你想找到產生最低輸出值的輸入值。下面的簡單例子找到x的值用于最小化線性函數y(x) = x

from hyperopt import fmin, tpe, hp
best = fmin(
    fn=lambda x: x,
    space=hp.uniform('x', 0, 1),
    algo=tpe.suggest,
    max_evals=100)
print best

我們來分解一下這個例子。

函數fmin首先接受一個函數來最小化,記為fn,在這里用一個匿名函數lambda x: x來指定。該函數可以是任何有效的值返回函數,例如回歸中的平均絕對誤差。

下一個參數指定搜索空間,在本例中,它是0到1之間的連續數字范圍,由hp.uniform('x', 0, 1)指定。hp.uniform是一個內置的hyperopt函數,它有三個參數:名稱x,范圍的下限和上限01

algo參數指定搜索算法,本例中tpe表示 tree of Parzen estimators。該主題超出了本文的范圍,但有數學背景的讀者可以細讀這篇文章。algo參數也可以設置為hyperopt.random,但是這里我們沒有涉及,因為它是眾所周知的搜索策略。但在未來的文章中我們可能會涉及。

最后,我們指定fmin函數將執行的最大評估次數max_evals。這個fmin函數將返回一個python字典。

上述函數的一個輸出示例是{'x': 0.000269455723739237}

以下是該函數的圖。紅點是我們試圖找到的點。

Silvrback blog image

更復雜的例子

這有一個更復雜的目標函數:lambda x: (x-1)**2。這次我們試圖最小化一個二次方程y(x)=(x-1)**2。所以我們改變搜索空間以包括我們已知的最優值(x=1)加上兩邊的一些次優范圍:hp.uniform('x', -2, 2)

現在我們有:

best = fmin(
    fn=lambda x: (x-1)**2,
    space=hp.uniform('x', -2, 2),
    algo=tpe.suggest,
    max_evals=100)
print best

輸出應該看起來像這樣:

{'x': 0.997369045274755}

這是函數圖。

Silvrback blog image

有時也許我們想要最大化目標函數,而不是最小化它。為此,我們只需要返回函數的負數。例如,我們有函數y(x) = -(x**2)

Silvrback blog image

我們如何解決這個問題?我們采用目標函數lambda x: -(x**2)并返回負值,只需給出lambda x: -1*-(x**2)或者lambda x: (x**2)即可。

這里有一個和例子1類似,但我們不是最小化,而是試圖最大化。

Silvrback blog image

這里有許多(無限多且無限范圍)局部最小值的函數,我們也試圖將其最大化:

Silvrback blog image

搜索空間

hyperopt模塊包含一些方便的函數來指定輸入參數的范圍。我們已經見過hp.uniform。最初,這些是隨機搜索空間,但隨著hyperopt更多的學習(因為它從目標函數獲得更多反饋),通過它認為提供給它最有意義的反饋,會調整并采樣初始搜索空間的不同部分。

以下內容將在本文中使用:

  1. hp.choice(label, options) 其中options應是 python 列表或元組。
  2. hp.normal(label, mu, sigma) 其中musigma分別是均值和標準差。
  3. hp.uniform(label, low, high) 其中lowhigh是范圍的下限和上限。

其他也是可用的,例如hp.normalhp.lognormalhp.quniform,但我們不會在這里使用它們。

為了查看搜索空間的一些例子,我們應該導入另一個函數,同時定義搜索空間。

import hyperopt.pyll.stochastic

space = {
    'x': hp.uniform('x', 0, 1),
    'y': hp.normal('y', 0, 1),
    'name': hp.choice('name', ['alice', 'bob']),
}

print hyperopt.pyll.stochastic.sample(space)

一個示例輸出是:

{'y': -1.4012610048810574, 'x': 0.7258615424906184, 'name': 'alice'}

嘗試運行幾次并查看不同的樣本。

通過 Trials 捕獲信息

如果能看到hyperopt黑匣子內發生了什么是極好的。Trials對象使我們能夠做到這一點。我們只需要導入一些東西。

from hyperopt import fmin, tpe, hp, STATUS_OK, Trials

fspace = {
    'x': hp.uniform('x', -5, 5)
}

def f(params):
    x = params['x']
    val = x**2
    return {'loss': val, 'status': STATUS_OK}

trials = Trials()
    best = fmin(fn=f, space=fspace, algo=tpe.suggest, max_evals=50, trials=trials)

print 'best:', best

print 'trials:'
for trial in trials.trials[:2]:
    print trial

STATUS_OKTrials是新導入的。Trials對象允許我們在每個時間步存儲信息。然后我們可以將它們打印出來,并在給定的時間步查看給定參數的函數評估值。

這是上面代碼的一個輸出示例:

best: {'x': 0.014420181637303776}
trials:
{'refresh_time': None, 'book_time': None, 'misc': {'tid': 0, 'idxs': {'x': [0]}, 'cmd': ('domain_attachment', 'FMinIter_Domain'), 'vals': {'x': [1.9646918559786162]}, 'workdir': None}, 'state': 2, 'tid': 0, 'exp_key': None, 'version': 0, 'result': {'status': 'ok', 'loss': 3.8600140889486996}, 'owner': None, 'spec': None}
{'refresh_time': None, 'book_time': None, 'misc': {'tid': 1, 'idxs': {'x': [1]}, 'cmd': ('domain_attachment', 'FMinIter_Domain'), 'vals': {'x': [-3.9393509404526728]}, 'workdir': None}, 'state': 2, 'tid': 1, 'exp_key': None, 'version': 0, 'result': {'status': 'ok', 'loss': 15.518485832045357}, 'owner': None, 'spec': None}

Trials對象將數據存儲為BSON對象,其工作方式與JSON對象相同。BSON來自pymongo模塊。我們不會在這里討論細節,這是對于需要使用MongoDB進行分布式計算的hyperopt的高級選項,因此需要導入pymongo。回到上面的輸出。tid是時間 id,即時間步,其值從0到max_evals-1。它隨著迭代次數遞增。'x'是鍵'vals'的值,其中存儲的是每次迭代參數的值。'loss'是鍵'result'的值,其給出了該次迭代目標函數的值。

我們用另一種方式來看看。

可視化

我們將在這里討論兩種類型的可視化:值 vs. 時間與損失 vs. 值。首先是值 vs. 時間。以下是繪制上述Trial.trials數據的代碼和示例輸出。

f, ax = plt.subplots(1)
xs = [t['tid'] for t in trials.trials]
ys = [t['misc']['vals']['x'] for t in trials.trials]
ax.set_xlim(xs[0]-10, xs[-1]+10)
ax.scatter(xs, ys, s=20, linewidth=0.01, alpha=0.75)
ax.set_title('$x$ $vs$ $t$ ', fontsize=18)
ax.set_xlabel('$t$', fontsize=16)
ax.set_ylabel('$x$', fontsize=16)

假設我們將`max_evals設為1000,輸出應該如下所示。

[圖片上傳失敗...(image-2f30d5-1524930959800)]

我們可以看到,最初算法從整個范圍中均勻地選擇值,但隨著時間的推移以及參數對目標函數的影響了解越來越多,該算法越來越聚焦于它認為會取得最大收益的區域-一個接近零的范圍。它仍然探索整個解空間,但頻率有所下降。

現在讓我們看看損失 vs. 值的圖。

f, ax = plt.subplots(1)
xs = [t['misc']['vals']['x'] for t in trials.trials]
ys = [t['result']['loss'] for t in trials.trials]
ax.scatter(xs, ys, s=20, linewidth=0.01, alpha=0.75)
ax.set_title('$val$ $vs$ $x$ ', fontsize=18)
ax.set_xlabel('$x$', fontsize=16)
ax.set_ylabel('$val$', fontsize=16)
Silvrback blog image

它給了我們所期望的,因為函數y(x)=x**2是確定的。

總結一下,讓我們嘗試一個更復雜的例子,伴隨更多的隨機性和更多的參數。

Iris 數據集

在本節中,我們將介紹4個使用hyperopt在經典數據集 Iris 上調參的完整示例。我們將涵蓋 K 近鄰(KNN),支持向量機(SVM),決策樹和隨機森林。需要注意的是,由于我們試圖最大化交叉驗證的準確率(acc請參見下面的代碼),而hyperopt只知道如何最小化函數,所以必須對準確率取負。最小化函數f與最大化f的負數是相等的。

對于這項任務,我們將使用經典的Iris數據集,并進行一些有監督的機器學習。數據集有有4個輸入特征和3個輸出類別。數據被標記為屬于類別0,1或2,其映射到不同種類的鳶尾花。輸入有4列:萼片長度,萼片寬度,花瓣長度和花瓣寬度。輸入的單位是厘米。我們將使用這4個特征來學習模型,預測三種輸出類別之一。因為數據由sklearn提供,它有一個很好的DESCR屬性,可以提供有關數據集的詳細信息。嘗試以下代碼以獲得更多細節信息。

print iris.feature_names # input names
print iris.target_names # output names
print iris.DESCR # everything else

讓我們通過使用下面的代碼可視化特征和類來更好地了解數據。如果你還沒安裝別忘了先執行pip install searborn

import seaborn as sns
sns.set(style="whitegrid", palette="husl")

iris = sns.load_dataset("iris")
print iris.head()

iris = pd.melt(iris, "species", var_name="measurement")
print iris.head()

f, ax = plt.subplots(1, figsize=(15,10))
sns.stripplot(x="measurement", y="value", hue="species", data=iris, jitter=True, edgecolor="white", ax=ax)

這是圖表:

Silvrback blog image

K 近鄰

我們現在將使用hyperopt來找到 K近鄰(KNN)機器學習模型的最佳參數。KNN 模型是基于訓練數據集中 k 個最近數據點的大多數類別對來自測試集的數據點進行分類。關于這個算法的更多信息可以參考這里。下面的代碼結合了我們所涵蓋的一切。

from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target

def hyperopt_train_test(params):
    clf = KNeighborsClassifier(**params)
    return cross_val_score(clf, X, y).mean()

space4knn = {
    'n_neighbors': hp.choice('n_neighbors', range(1,100))
}

def f(params):
    acc = hyperopt_train_test(params)
    return {'loss': -acc, 'status': STATUS_OK}

trials = Trials()
best = fmin(f, space4knn, algo=tpe.suggest, max_evals=100, trials=trials)
print 'best:'
print best

現在讓我們看看輸出結果的圖。y軸是交叉驗證分數,x軸是 k 近鄰個數。下面是代碼和它的圖像:

f, ax = plt.subplots(1)#, figsize=(10,10))
xs = [t['misc']['vals']['n'] for t in trials.trials]
ys = [-t['result']['loss'] for t in trials.trials]
ax.scatter(xs, ys, s=20, linewidth=0.01, alpha=0.5)
ax.set_title('Iris Dataset - KNN', fontsize=18)
ax.set_xlabel('n_neighbors', fontsize=12)
ax.set_ylabel('cross validation accuracy', fontsize=12)
Silvrback blog image

k 大于63后,準確率急劇下降。這是因為數據集中每個類的數量。這三個類中每個類只有50個實例。所以讓我們將'n_neighbors'的值限制為較小的值來進一步探索。

from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target

def hyperopt_train_test(params):
    clf = KNeighborsClassifier(**params)
    return cross_val_score(clf, X, y).mean()

space4knn = {
    'n_neighbors': hp.choice('n_neighbors', range(1,50))
}

def f(params):
    acc = hyperopt_train_test(params)
    return {'loss': -acc, 'status': STATUS_OK}

trials = Trials()
best = fmin(f, space4knn, algo=tpe.suggest, max_evals=100, trials=trials)
print 'best:'
print best

這是我們運行相同的可視化代碼得到的結果:

Silvrback blog image

現在我們可以清楚地看到k有一個最佳值,k=4

上面的模型沒有做任何預處理。所以我們來歸一化和縮放特征,看看是否有幫助。用如下代碼:

# now with scaling as an option
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target

def hyperopt_train_test(params):
    X_ = X[:]

    if 'normalize' in params:
        if params['normalize'] == 1:
            X_ = normalize(X_)
            del params['normalize']

    if 'scale' in params:
        if params['scale'] == 1:
            X_ = scale(X_)
            del params['scale']

    clf = KNeighborsClassifier(**params)
    return cross_val_score(clf, X_, y).mean()

space4knn = {
    'n_neighbors': hp.choice('n_neighbors', range(1,50)),
    'scale': hp.choice('scale', [0, 1]),
    'normalize': hp.choice('normalize', [0, 1])
}

def f(params):
    acc = hyperopt_train_test(params)
    return {'loss': -acc, 'status': STATUS_OK}

trials = Trials()
best = fmin(f, space4knn, algo=tpe.suggest, max_evals=100, trials=trials)
print 'best:'
print best

并像這樣繪制參數:

parameters = ['n_neighbors', 'scale', 'normalize']
cols = len(parameters)
f, axes = plt.subplots(nrows=1, ncols=cols, figsize=(15,5))
cmap = plt.cm.jet
for i, val in enumerate(parameters):
    xs = np.array([t['misc']['vals'][val] for t in trials.trials]).ravel()
    ys = [-t['result']['loss'] for t in trials.trials]
    xs, ys = zip(\*sorted(zip(xs, ys)))
    ys = np.array(ys)
    axes[i].scatter(xs, ys, s=20, linewidth=0.01, alpha=0.75, c=cmap(float(i)/len(parameters)))
    axes[i].set_title(val)
Silvrback blog image

我們看到縮放和/或歸一化數據并不會提高預測準確率。k的最佳值仍然為4,這得到98.6%的準確率。

所以這對于簡單模型 KNN 調參很有用。讓我們看看用支持向量機(SVM)能做什么。

支持向量機(SVM)

由于這是一個分類任務,我們將使用sklearnSVC類。代碼如下:

iris = datasets.load_iris()
X = iris.data
y = iris.target

def hyperopt_train_test(params):
    X_ = X[:]

    if 'normalize' in params:
        if params['normalize'] == 1:
            X_ = normalize(X_)
            del params['normalize']

    if 'scale' in params:
        if params['scale'] == 1:
            X_ = scale(X_)
            del params['scale']

    clf = SVC(**params)
    return cross_val_score(clf, X_, y).mean()

space4svm = {
    'C': hp.uniform('C', 0, 20),
    'kernel': hp.choice('kernel', ['linear', 'sigmoid', 'poly', 'rbf']),
    'gamma': hp.uniform('gamma', 0, 20),
    'scale': hp.choice('scale', [0, 1]),
    'normalize': hp.choice('normalize', [0, 1])
}

def f(params):
    acc = hyperopt_train_test(params)
    return {'loss': -acc, 'status': STATUS_OK}

trials = Trials()
best = fmin(f, space4svm, algo=tpe.suggest, max_evals=100, trials=trials)
print 'best:'
print best

parameters = ['C', 'kernel', 'gamma', 'scale', 'normalize']
cols = len(parameters)
f, axes = plt.subplots(nrows=1, ncols=cols, figsize=(20,5))
cmap = plt.cm.jet
for i, val in enumerate(parameters):
    xs = np.array([t['misc']['vals'][val] for t in trials.trials]).ravel()
    ys = [-t['result']['loss'] for t in trials.trials]
    xs, ys = zip(\*sorted(zip(xs, ys)))
    axes[i].scatter(xs, ys, s=20, linewidth=0.01, alpha=0.25, c=cmap(float(i)/len(parameters)))
    axes[i].set_title(val)
    axes[i].set_ylim([0.9, 1.0])

這是我們得到的:

Silvrback blog image

同樣,縮放和歸一化也沒有幫助。核函數的首選是(linear),C的最佳值是1.4168540399911616gamma的最佳值是15.04230279483486。這組參數得到了99.3%的分類準確率。

決策樹

我們將嘗試只優化決策樹的一些參數。代碼如下。

iris = datasets.load_iris()
X_original = iris.data
y_original = iris.target

def hyperopt_train_test(params):
    X_ = X[:]
    if 'normalize' in params:
        if params['normalize'] == 1:
            X_ = normalize(X_)
            del params['normalize']

    if 'scale' in params:
        if params['scale'] == 1:
            X_ = scale(X_)
            del params['scale']
    clf = DecisionTreeClassifier(**params)
    return cross_val_score(clf, X, y).mean()

space4dt = {
    'max_depth': hp.choice('max_depth', range(1,20)),
    'max_features': hp.choice('max_features', range(1,5)),
    'criterion': hp.choice('criterion', ["gini", "entropy"]),
    'scale': hp.choice('scale', [0, 1]),
    'normalize': hp.choice('normalize', [0, 1])
}

def f(params):
acc = hyperopt_train_test(params)
return {'loss': -acc, 'status': STATUS_OK}

trials = Trials()
best = fmin(f, space4dt, algo=tpe.suggest, max_evals=300, trials=trials)
print 'best:'
print best

輸出如下,其準確率為97.3%。

{'max_features': 1, 'normalize': 0, 'scale': 0, 'criterion': 0, 'max_depth': 17}

以下是圖表。我們可以看到,對于不同的scale值,normalizecriterion,性能幾乎沒有差別。

parameters = ['max_depth', 'max_features', 'criterion', 'scale', 'normalize'] # decision tree
cols = len(parameters)
f, axes = plt.subplots(nrows=1, ncols=cols, figsize=(20,5))
cmap = plt.cm.jet
for i, val in enumerate(parameters):
    xs = np.array([t['misc']['vals'][val] for t in trials.trials]).ravel()
    ys = [-t['result']['loss'] for t in trials.trials]
    xs, ys = zip(\*sorted(zip(xs, ys)))
    ys = np.array(ys)
    axes[i].scatter(xs, ys, s=20, linewidth=0.01, alpha=0.5, c=cmap(float(i)/len(parameters)))
    axes[i].set_title(val)
    #axes[i].set_ylim([0.9,1.0])
Silvrback blog image

隨機森林

讓我們來看看集成分類器隨機森林發生了什么,隨機森林只是在不同分區數據上訓練的決策樹集合,每個分區都對輸出類進行投票,并將絕大多數類的選擇為預測。

iris = datasets.load_iris()
X_original = iris.data
y_original = iris.target

def hyperopt_train_test(params):
    X_ = X[:]
    if 'normalize' in params:
        if params['normalize'] == 1:
            X_ = normalize(X_)
            del params['normalize']

    if 'scale' in params:
        if params['scale'] == 1:
            X_ = scale(X_)
            del params['scale']
    clf = RandomForestClassifier(**params)
    return cross_val_score(clf, X, y).mean()

space4rf = {
    'max_depth': hp.choice('max_depth', range(1,20)),
    'max_features': hp.choice('max_features', range(1,5)),
    'n_estimators': hp.choice('n_estimators', range(1,20)),
    'criterion': hp.choice('criterion', ["gini", "entropy"]),
    'scale': hp.choice('scale', [0, 1]),
    'normalize': hp.choice('normalize', [0, 1])
}

best = 0
def f(params):
    global best
    acc = hyperopt_train_test(params)
    if acc > best:
    best = acc
    print 'new best:', best, params
    return {'loss': -acc, 'status': STATUS_OK}

trials = Trials()
best = fmin(f, space4rf, algo=tpe.suggest, max_evals=300, trials=trials)
print 'best:'
print best

同樣,與決策樹相同,我們僅得到97.3%的準確率。

這是繪制參數的代碼:

parameters = ['n_estimators', 'max_depth', 'max_features', 'criterion', 'scale', 'normalize']
f, axes = plt.subplots(nrows=2, ncols=3, figsize=(15,10))
cmap = plt.cm.jet
for i, val in enumerate(parameters):
    print i, val
    xs = np.array([t['misc']['vals'][val] for t in trials.trials]).ravel()
    ys = [-t['result']['loss'] for t in trials.trials]
    xs, ys = zip(\*sorted(zip(xs, ys)))
    ys = np.array(ys)
    axes[i/3,i%3].scatter(xs, ys, s=20, linewidth=0.01, alpha=0.5, c=cmap(float(i)/len(parameters)))
    axes[i/3,i%3].set_title(val)
    #axes[i/3,i%3].set_ylim([0.9,1.0])
Silvrback blog image

是時候把所有東西合為一體了

自動調整一個模型的參數(如SVM或KNN)非常有趣并且具有啟發性,但同時調整它們并取得全局最佳模型則更有用。這使我們能夠一次比較所有參數和所有模型,因此為我們提供了最佳模型。代碼如下:

digits = datasets.load_digits()
X = digits.data
y = digits.target
print X.shape, y.shape

def hyperopt_train_test(params):
    t = params['type']
    del params['type']
    if t == 'naive_bayes':
        clf = BernoulliNB(**params)
    elif t == 'svm':
        clf = SVC(**params)
    elif t == 'dtree':
        clf = DecisionTreeClassifier(**params)
    elif t == 'knn':
        clf = KNeighborsClassifier(**params)
    else:
        return 0
    return cross_val_score(clf, X, y).mean()

space = hp.choice('classifier_type', [
    {
        'type': 'naive_bayes',
        'alpha': hp.uniform('alpha', 0.0, 2.0)
    },
    {
        'type': 'svm',
        'C': hp.uniform('C', 0, 10.0),
        'kernel': hp.choice('kernel', ['linear', 'rbf']),
        'gamma': hp.uniform('gamma', 0, 20.0)
    },
    {
        'type': 'randomforest',
        'max_depth': hp.choice('max_depth', range(1,20)),
        'max_features': hp.choice('max_features', range(1,5)),
        'n_estimators': hp.choice('n_estimators', range(1,20)),
        'criterion': hp.choice('criterion', ["gini", "entropy"]),
        'scale': hp.choice('scale', [0, 1]),
        'normalize': hp.choice('normalize', [0, 1])
    },
    {
        'type': 'knn',
        'n_neighbors': hp.choice('knn_n_neighbors', range(1,50))
    }
])

count = 0
best = 0
def f(params):
    global best, count
    count += 1
    acc = hyperopt_train_test(params.copy())
    if acc > best:
        print 'new best:', acc, 'using', params['type']
        best = acc
    if count % 50 == 0:
        print 'iters:', count, ', acc:', acc, 'using', params
    return {'loss': -acc, 'status': STATUS_OK}

trials = Trials()
best = fmin(f, space, algo=tpe.suggest, max_evals=1500, trials=trials)
print 'best:'
print best

由于我們增加了評估數量,此代碼需要一段時間才能運行完:max_evals=1500。當找到新的最佳準確率時,它還會添加到輸出用于更新。好奇為什么使用這種方法沒有找到前面的最佳模型:參數為kernel=linearC=1.416gamma=15.042SVM

總結

我們已經介紹了簡單的例子,如最小化確定的線性函數,以及復雜的例子,如調整隨機森林參數。hyperopt的官方文檔在這里。另一篇有關 hyperopt 不錯的博客位于 FastML 站點(譯注:已無效)。hyperopt作者的SciPy會議論文是Hyperopt: A Python Library for Optimizing the Hyperparameters of Machine Learning Algorithms,伴隨一起的視頻教程。關于工程來龍去脈的更多技術處理細節可以參見Making a Science of Model Search

本文的技術可以用于機器學習以外的許多領域,例如調整epsilon-greedy multi-armed banditepsilon參數,或將參數傳遞給圖生成器以生成具有某些屬性的合成網絡。我們以后會寫更多。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容