我有一個模型串列,我在 for 回圈中迭代以獲得它們的性能。我已將 catboost 添加到我的模型串列中,但是當我嘗試將它的最佳估計器添加到字典時,它給了我一個錯誤,沒有其他模型給我 ( TypeError: unhashable type: 'CatBoostRegressor')。谷歌搜索,我看不到解決這個錯誤的明確方法,所以我一直在嘗試在我的 for 回圈中添加一個 if 陳述句,如果模型是 catboost 則忽略將它的最佳估計器放入字典中。
我正在運行的代碼示例如下:
lgbm = LGBMRegressor(random_state=seed)
lgbm_params = {
"max_depth": (1, 4),
"learning_rate": (0.01, 0.2, "log-uniform"),
"n_estimators": (10, 50),
"reg_alpha": (1, 10, "log-uniform"),
"reg_lambda": (1, 10, "log-uniform"),
}
catboost = CatBoostRegressor(random_seed=seed, verbose=False)
cat_params = {
"iterations": (10, 50),
'learning_rate': (0.01, 0.2, 'log-uniform'),
'depth': (1, 4),
}
inner_cv = KFold(n_splits=2, random_state=seed)
outer_cv = KFold(n_splits=2, random_state=seed)
models = []
models.append(("CB", BayesSearchCV(catboost, cat_params, cv=inner_cv, iid=False, n_jobs=1)))
models.append(("LGBM", BayesSearchCV(lgbm, lgbm_params, cv=inner_cv, iid=False, n_jobs=1)))
results = []
names = []
medians =[]
scoring = ['r2', 'neg_mean_squared_error', 'max_error', 'neg_mean_absolute_error',
'explained_variance','neg_root_mean_squared_error',
'neg_median_absolute_error']
models_dictionary_r2 = {}
models_dictionary_mse = {}
for name, model in models:
#run nested cross-validation
nested_cv_results = model_selection.cross_validate(model, X , Y, cv=outer_cv, scoring=scoring, error_score="raise")
nested_cv_results2 = model_selection.cross_val_score(model, X , Y, cv=outer_cv, scoring='r2', error_score="raise")
results.append(nested_cv_results2)
names.append(name)
medians.append(np.median(nested_cv_results['test_r2']))
print(name, 'Nested CV results for all scores:', '\n', nested_cv_results, '\n')
print(name, 'r2 Nested CV Median', np.median(nested_cv_results['test_r2']))
print(name, 'MSE Nested CV Median', np.median(nested_cv_results['test_neg_mean_squared_error'] ))
#view best tuned model
model.fit(X_train, Y_train)
print("Best Parameters: \n{}\n".format(model.best_params_))
y_pred_train = model.best_estimator_.predict(X_train)
y_pred = model.best_estimator_.predict(X_test)
#view shap interpretation of best tuned model
explainer = shap.TreeExplainer(model.best_estimator_)
shap_values = explainer.shap_values(X_importance)
X_importance = pd.DataFrame(data=X_test, columns=df3.columns)
print(name,'ALL FEATURES Ranked SHAP Importance:', X.columns[np.argsort(np.abs(shap_values).mean(0))[::-1]])
fig, ax = plt.subplots()
shap.summary_plot(shap_values, X_importance)
fig.savefig("shap_summary" name ".svg", format='svg', dpi=1200, bbox_inches = "tight")
#add model's best estimator's best metrics to a dictionary, but ignore this for catboost
if model is models[0]:
print('catboost best estimator not compatible with entering a dictionary')
else:
models_dictionary_r2[model.best_estimator_] = np.median(nested_cv_results['test_r2'])
models_dictionary_mse[model.best_estimator_] = np.median(nested_cv_results['test_neg_mean_squared_error']
這是我試圖開始作業的最后的 if 陳述句,但我沒有使用帶有條件陳述句的 python 的經驗。目前它運行并仍然發送 catboost 模型以嘗試將其結果放入字典中,我得到相同的結果TypeError: unhashable type: 'CatBoostRegressor'- 有沒有一種方法可以編碼'如果模型是 catboost 然后繼續測驗下一個模型,否則存盤最佳估計器結果在字典里?
不幸的是,我無法提供我的資料,但它只是連續變數的 8 個特征,回歸模型的得分行在 0-1 之間。
編輯:我這樣做是為了獲得性能最好的模型的最佳估計器,以便我可以將該特定/調整的模型擬合到新資料。
我將它從字典中單獨取出以適應新資料,如下所示:
top_model = max(models_dictionary_r2, key=models_dictionary_r2.get)
從目前的答案中,我正在運行以獲取一個輸出如下的串列:
[(<catboost.core.CatBoostRegressor at 0x7f8d50860400>, 0.8110325480633154),
(LGBMRegressor(learning_rate=0.14567200981008144, max_depth=3, n_estimators=50,
random_state=0, reg_alpha=1, reg_lambda=1),
0.7632660705322947)]
Catboost 在此串列中具有最佳的中值 r2,但我不確定 catboost 是否采用正確的格式以使其最佳估算器詳細資訊適合新資料?我試過:
top_model = models_list_predr2[0]
top_model.fit(X_train, Y_train)
AttributeError: 'tuple' object has no attribute 'fit'
我怎樣才能best_estimator_從這個串列中選出表現最好的模型,并確保它適用于 catboost?
我沒有使用 python 的經驗,嘗試max(models_list_predr2)使用上面的串列也會給出錯誤TypeError: '>' not supported between instances of 'LGBMRegressor' and 'CatBoostRegressor' ?
uj5u.com熱心網友回復:
發生此錯誤是因為任何字典鍵都應該屬于可散列型別,這意味著它應該實作__hash__()散列方法和__eq__()比較。
由于CatBoostRegressor沒有實作這些方法,因此您在嘗試將CatBoostRegressor其作為鍵添加到字典中時會收到例外。
我建議您使用串列而不是字典 formodels_dictionary_r2和models_dictionary_mse。
models_list_r2 = []
models_list_mse = []
然后您可以將值添加到這些串列中,如下所示:
best_estimator = model.best_estimator_
median_r2 = np.median(nested_cv_results['test_r2'])
models_list_r2.append((best_estimator, median_r2))
median_mse = np.median(nested_cv_results['test_neg_mean_squared_error'])
models_list_mse.append((model.best_estimator_, median_mse))
要選擇具有最高 R 平方的模型,您可以添加以下代碼:
best_model, best_r2 = sorted(models_list_r2, key = lambda x: x[1], reverse=True)[0]
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/476694.html
