sklearn GridSearchCV 给出了有问题的结果
sklearn GridSearchCV gives questionable results
我有输入数据 X_train 的尺寸 (477 x 200) 和 y_train 的长度 477。
我想使用支持向量机回归器,我正在进行网格搜索。
param_grid = {'kernel': ['poly', 'rbf', 'linear','sigmoid'], 'degree': [2,3,4,5], 'C':[0.01,0.1,0.3,0.5,0.7,1,1.5,2,5,10]}
grid = GridSearchCV(estimator=regressor_2, param_grid=param_grid, scoring='neg_root_mean_squared_error', n_jobs=1, cv=3, verbose = 1)
grid_result = grid.fit(X_train, y_train))
我得到 grid_result.best_params_
{'C': 0.3, 'degree': 2, 'kernel': 'linear'}
的分数是 -7.76。 {'C': 10, 'degree': 2, 'kernel': 'rbf'}
给出 mit -8.0.
然而,当我这样做时
regressor_opt = SVR(kernel='linear', 'degree'=2, C=0.3)
regressor_opt.fit(X_train,y_train)
y_train_pred = regressor_opt.predict(X_train)
print("rmse=",np.sqrt(sum(y_train-y_train_pred)**2)/np.shape(y_train_pred)))
我得到 7.4,当我做到时
regressor_2 = SVR(kernel='rbf', 'degree'=2, C=10)
regressor_2.fit(X_train,y_train)
y_train_pred = regressor_2.predict(X_train)
print("rmse=",np.sqrt(sum(y_train-y_train_pred)**2)/np.shape(y_train_pred)))
我得到 5.9。这显然比 7.4 好,但在网格搜索中,我为该参数组合得到的负 rmse 为 -8,因此比 7.4 差。
谁能向我解释发生了什么事?我不应该使用 scoring='neg_root_mean_square_error'
吗?
GridSearchCV 会根据遗漏的数据给你分数。这就是交叉验证的基本原理。当你在整个训练集上训练和评估时,你正在做的是没有进行交叉验证;你会得到一个过于乐观的结果。对于线性核(7.4 对 7.76),您会稍微看到这一点,而对于更灵活的 RBF 核(5.9 对 8),这一点会更加夸张。我期望正确,GridSearchCV 已经确定您的更灵活的模型也不能泛化。
通过使用特定的估计器(regressor_opt 和 regressor_2)并使用 sklearn 的 cross_validate() 获得遗漏折叠的结果,您应该能够更清楚地看到这种效果.我希望您会看到 regressor_2 的表现比您的乐观值 5.9 差得多。您可能会发现这是一项有益的练习。
请记住,您需要一个在新数据上表现最佳的模型,而不是一个可以任意拟合您的训练数据的模型。
我建议对此的进一步讨论不属于 Whosebug,而是属于 crossvalidated。
我有输入数据 X_train 的尺寸 (477 x 200) 和 y_train 的长度 477。 我想使用支持向量机回归器,我正在进行网格搜索。
param_grid = {'kernel': ['poly', 'rbf', 'linear','sigmoid'], 'degree': [2,3,4,5], 'C':[0.01,0.1,0.3,0.5,0.7,1,1.5,2,5,10]}
grid = GridSearchCV(estimator=regressor_2, param_grid=param_grid, scoring='neg_root_mean_squared_error', n_jobs=1, cv=3, verbose = 1)
grid_result = grid.fit(X_train, y_train))
我得到 grid_result.best_params_
{'C': 0.3, 'degree': 2, 'kernel': 'linear'}
的分数是 -7.76。 {'C': 10, 'degree': 2, 'kernel': 'rbf'}
给出 mit -8.0.
然而,当我这样做时
regressor_opt = SVR(kernel='linear', 'degree'=2, C=0.3)
regressor_opt.fit(X_train,y_train)
y_train_pred = regressor_opt.predict(X_train)
print("rmse=",np.sqrt(sum(y_train-y_train_pred)**2)/np.shape(y_train_pred)))
我得到 7.4,当我做到时
regressor_2 = SVR(kernel='rbf', 'degree'=2, C=10)
regressor_2.fit(X_train,y_train)
y_train_pred = regressor_2.predict(X_train)
print("rmse=",np.sqrt(sum(y_train-y_train_pred)**2)/np.shape(y_train_pred)))
我得到 5.9。这显然比 7.4 好,但在网格搜索中,我为该参数组合得到的负 rmse 为 -8,因此比 7.4 差。
谁能向我解释发生了什么事?我不应该使用 scoring='neg_root_mean_square_error'
吗?
GridSearchCV 会根据遗漏的数据给你分数。这就是交叉验证的基本原理。当你在整个训练集上训练和评估时,你正在做的是没有进行交叉验证;你会得到一个过于乐观的结果。对于线性核(7.4 对 7.76),您会稍微看到这一点,而对于更灵活的 RBF 核(5.9 对 8),这一点会更加夸张。我期望正确,GridSearchCV 已经确定您的更灵活的模型也不能泛化。
通过使用特定的估计器(regressor_opt 和 regressor_2)并使用 sklearn 的 cross_validate() 获得遗漏折叠的结果,您应该能够更清楚地看到这种效果.我希望您会看到 regressor_2 的表现比您的乐观值 5.9 差得多。您可能会发现这是一项有益的练习。
请记住,您需要一个在新数据上表现最佳的模型,而不是一个可以任意拟合您的训练数据的模型。
我建议对此的进一步讨论不属于 Whosebug,而是属于 crossvalidated。