h2o GLM网格搜索lambda值

3
我正在使用 H2O (Python) 进行实验,使用 H2OGridSearch 来寻找 GLM (H2OGeneralizedLinearEstimator) 的 alpha 值,同时使用 k-fold 交叉验证中的 lambda_search=True
如何获取最佳模型的 lambda 值? 编辑: 完全可复现的示例
数据:
34.40 17:1 73:1 127:1 265:1 912:1 1162:1 1512:1 1556:1 1632:1 1738:1
205.10 127:1 138:1 338:1 347:1 883:1 912:1 1120:1 1122:1 1512:1
7.75 66:1 127:1 347:1 602:1 1422:1 1512:1 1535:1 1738:1
8.85 127:1 608:1 906:1 979:1 1077:1 1512:1 1738:1
51.80 127:1 347:1 608:1 766:1 912:1 928:1 952:1 1034:1 1512:1 1610:1 1738:1
110.00 127:1 229:1 347:1 602:1 608:1 1171:1 1512:1 1718:1
8.90 66:1 127:1 205:1 347:1 490:1 589:1 912:1 1016:1 1512:1

请将此文件命名为h2o_example.svmlight
然后运行:
h2o_data = h2o.import_file("h2o_example.svmlight")
cols = h2o_data.columns[1:]
hyper_parameters = {"alpha": [0.0, 0.01, 0.99, 1.0]}
grid = H2OGridSearch(H2OGeneralizedLinearEstimator(family="gamma", link="log", lambda_search=True, nfolds=2, intercept=True, standardize=False),
hyper_params=hyper_parameters)
grid.train(y="C1", x=cols, training_frame=h2o_data)
grid_table = grid.get_grid(sort_by="r2", decreasing=True)
best = grid_table.models[0]
best.actual_params["lambda"]
best.actual_params["alpha"]

最后两个命令失败了,给我错误提示:
TypeError: 'property' object has no attribute '__getitem__'

显然,我在错误地使用lambda_search。根据我的标准,我如何获得最佳模型的单个alpha和lambda值?


只是指出您的代码为什么不能工作。实际参数"lambda_"和"alpha"是指模型在最初给定的参数——如果它们事先被固定的话。 - Alan Chalk
2个回答

3

最终编辑

有多种方法可以得到lambda(如下所示),但以下是两种简洁的获取lambda的方法。(请注意,完全可重现的代码在底部)

如果你设置了lambda_search = True,你可以在模型摘要表中查看lambda_search列,并查看为lambda.min设置的值,这就是你的最佳lambda。

model.summary()['lambda_search']

这将产生一个类似于以下字符串的列表:

['nlambda = 100, lambda.max = 12.733, lambda.min = 0.05261, lambda.1se = -1.0']

如果您不使用Lambda搜索,并且不设置Lambda值(或者进行了设置),您也可以使用汇总表。
model.summary()['regularization']

输出结果如下:
['Elastic Net (alpha = 0.5, lambda = 0.01289 )']

其他选项:

查看模型的实际参数: best.actual_params['lambda'] best.actual_params['alpha']

这里的 best 是网格搜索结果中的最佳模型。

第一次编辑:

为了获得最佳模型,你可以执行以下操作:

grid_table = grid.get_grid(sort_by='r2', decreasing=True)
best = grid_table.models[0]

然后你可以使用:

best.actual_params['lambda']

完全可复现的示例

import h2o
from h2o.estimators.glm import H2OGeneralizedLinearEstimator
h2o.init()

# import the airlines dataset:
# This dataset is used to classify whether a flight will be delayed 'YES' or not "NO"
# original data can be found at http://www.transtats.bts.gov/
airlines= h2o.import_file("https://s3.amazonaws.com/h2o-public-test-data/smalldata/airlines/allyears2k_headers.zip")

# convert columns to factors
airlines["Year"]= airlines["Year"].asfactor()
airlines["Month"]= airlines["Month"].asfactor()
airlines["DayOfWeek"] = airlines["DayOfWeek"].asfactor()
airlines["Cancelled"] = airlines["Cancelled"].asfactor()
airlines['FlightNum'] = airlines['FlightNum'].asfactor()

# set the predictor names and the response column name
predictors = ["Origin", "Dest", "Year", "UniqueCarrier", "DayOfWeek", "Month", "Distance", "FlightNum"]
response = "IsDepDelayed"

# split into train and validation sets
train, valid= airlines.split_frame(ratios = [.8])

# try using the `lambda_` parameter:
# initialize your estimator
airlines_glm = H2OGeneralizedLinearEstimator(family = 'binomial', lambda_ = .0001)

# then train your model
airlines_glm.train(x = predictors, y = response, training_frame = train, validation_frame = valid)

# print the auc for the validation data
print(airlines_glm.auc(valid=True))


# Example of values to grid over for `lambda`
# import Grid Search
from h2o.grid.grid_search import H2OGridSearch

# select the values for lambda_ to grid over
hyper_params = {'lambda': [1, 0.5, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0]}

# this example uses cartesian grid search because the search space is small
# and we want to see the performance of all models. For a larger search space use
# random grid search instead: {'strategy': "RandomDiscrete"}
# initialize the glm estimator
airlines_glm_2 = H2OGeneralizedLinearEstimator(family = 'binomial')

# build grid search with previously made GLM and hyperparameters
grid = H2OGridSearch(model = airlines_glm_2, hyper_params = hyper_params,
                     search_criteria = {'strategy': "Cartesian"})

# train using the grid
grid.train(x = predictors, y = response, training_frame = train, validation_frame = valid)

# sort the grid models by decreasing AUC
grid_table = grid.get_grid(sort_by = 'auc', decreasing = True)
print(grid_table)

best = grid_table.models[0]
print(best.actual_params['lambda'])

按照上述描述获取最佳模型会得到一个具有实际参数(<property at 0x7fa349f62050>)的对象,但是当尝试使用您提到的命令时,我遇到了以下错误:'property'对象没有'getitem'属性。 - user90772
更新的答案,我认为现在应该解决了你的问题。 - Lauren
仍然得到相同的错误。type(best) 返回 h2o.estimators.glm.H2OGeneralizedLinearEstimator,而 type(best.actual_params)property - user90772
谢谢,你的示例非常有效。我正在使用 lambda_search=True 并明确提供 alpha 值。我已经更新了我的问题,并提供了一个可重现的示例(svmlight 文件),希望你能得到相同的错误。 - user90772
2
当我尝试使用alpha超参数和lambda_search=True运行您的示例时,actual_params['lambda']返回完整的lambda值集合。 - user90772
显示剩余2条评论

0

我不确定为什么以下内容无法正常工作

best = grid_table.models[0]
best.actual_params["lambda"]
best.actual_params["alpha"]

这可能与h2o有关,但如果您将上述内容更改为以下内容,则应该至少能够访问这些参数:
best = grid.models[x]
best.actual_params["lambda"]
best.actual_params["alpha"]

请注意,我已将0更改为x,因为您需要注意根据您的错误标准哪个模型表现最佳,因为grid中的内容可能未按照您的错误标准进行排序。这需要您查看grid_table并注意model_id以及查看模型如何存储在grid中。
然后,您应该至少能够引用lambdaalpha。但是,当您在alpha上运行网格搜索,并通过lambda_search属性打开对lambda的搜索时,best.actual_params["lambda"]将返回搜索过的所有lambda的完整列表。您仍然可以考虑Lauren建议的方法来引用它,但我通常喜欢在表格中查看所有内容,并建议关闭lambda_search并将其添加到您要搜索的超参数中。
import numpy as np
lambda_search_range = list(np.linspace(0,1,100))
h2o_data = h2o.import_file("h2o_example.svmlight")
cols = h2o_data.columns[1:]
hyper_parameters = {"alpha": [0.0, 0.01, 0.99, 1.0], 
"lambda": lambda_search_range}
grid = H2OGridSearch(H2OGeneralizedLinearEstimator(family="gamma", 
        link="log", lambda_search=False, nfolds=2, 
        intercept=True, standardize=False), hyper_params=hyper_parameters)
grid.train(y="C1", x=cols, training_frame=h2o_data)
grid_table = grid.get_grid(sort_by="r2", decreasing=True)
param_dict = grid_table.get_hyperparams_dict(grid_table.model_ids[0])

param_dict 应该是一个字典,其中包含您根据指定的误差标准得出的最佳模型的 alpha 和 lambda 值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接