Python 网格搜索预处理多个超参数和多个估计量

Python 网格搜索预处理多个超参数和多个估计量,python,scikit-learn,Python,Scikit Learn,长期R用户,学习Python。我尝试使用GridSearch来尝试管道中PCA步骤的不同数量的组件,以及使用多个估计器。我认为下面的代码正在执行这些操作(使用GridSearch文档和其他来源),但是best\u params的结果没有预处理参数和估计器参数;相反,它会打印{'prep2_uuupcadtm_uuun_components':3},这向我表明代码并没有像我想象的那样运行 下面的代码是用多个超参数和多个估计器(加上超参数)测试预处理的方法吗 相同的网格搜索?如果不是 如何将预处理

长期R用户,学习Python。我尝试使用GridSearch来尝试管道中PCA步骤的不同数量的组件,以及使用多个估计器。我认为下面的代码正在执行这些操作(使用
GridSearch
文档和其他来源),但是
best\u params
的结果没有预处理参数和估计器参数;相反,它会打印
{'prep2_uuupcadtm_uuun_components':3}
,这向我表明代码并没有像我想象的那样运行

  • 下面的代码是用多个超参数和多个估计器(加上超参数)测试预处理的方法吗 相同的网格搜索?如果不是
  • 如何将预处理包含在 多个超参数和多个估计量(加上超参数) 在同一网格中搜索?
MWE 我认为
GridSearch
将生成2个和3个PCA分量数据集,然后使用估计器将其传递到下一步。反过来,两个PCA输出都将使用随机林进行测试,然后使用KNN[其中每个都有2个超参数。这意味着2(2和3个分量的PCA数据集)x2(估计器)x2(每个估计器的超参数)=8个正在测试的模型]。我想我是不对的


最后,为了提高效率,最好不要每次尝试新的估计器时都计算
prep2
步骤。

事实上,当
param\u grid
是一个字典列表时,搜索会在每个字典生成的网格的并集上进行。因此,您的代码实际上检查了六个超参数组合:

  • PCA尺寸2,随机森林默认深度=无
  • PCA尺寸3,随机森林默认深度=无
  • PCA默认值(dim2),随机森林深度5
  • PCA默认值(dim2),随机森林深度15
  • PCA默认值(dim2),KNN k=2
  • PCA默认值(dim2),KNN k=3
你需要像这样的东西

搜索空间={
“prep2_uuuuPCADTM_uuuuun_u组件”:[2,3],
“clf”:[RandomForestClassifier(最大深度=5),
随机森林分类器(最大深度=15),
Kneighbors分类器(n_近邻=2),
Kneighbors分类器(n_近邻=3)],
}
当然,根据您的实际需要,列出每个不同模型所需的所有超参数组合可能会变得很麻烦。在这种情况下,嵌套搜索可能最简单:

rf\u gs=GridSearchCV(
估计器=随机森林分类器(),
参数网格={'max_depth':[5,15]},
)
kn_gs=网格搜索CV(
估计器=KNeighborsClassifier(),
param_grid={'n_neights':[2,3]},
)
管道=管道([
(“准备”,预处理),
('prep2',prep2),
('clf',RandomForestClassifier())
])
search=GridSearchCV(
估算器=管道,
参数网格={
“prep2_uuuuPCADTM_uuuuun_u组件”:[2,3],
‘clf’:[rf_gs,kn_gs],
},
得分=‘准确度’,
cv=3,
return\u train\u score=真
)
这还可以减少预处理器的计算次数。但也请参见
管道
内存
参数


另外,请注意,这种方法会相当显著地更改cv折叠。如果您想进行“平面”搜索,可以编写一个快速脚本,在第一种方法中生成较长的列表。

完美!谢谢你的正确方法,一种替代方法(第二种方法对我来说在心理上更容易),特别是解释实际发生的事情。这对塑造我的思想观念很有帮助。感谢您抽出时间传授您的知识和经验。非常感谢!
## Dependencies
import seaborn as sns
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.compose import ColumnTransformer
from sklearn.neighbors import KNeighborsClassifier
from imblearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
    
## load data set
df = sns.load_dataset('mpg').drop(["name"], axis = 1).dropna()

## Factoize the outcome
factor = pd.factorize(df['origin'])
df.origin = factor[0]
definitions = factor[1]
outcome_order = definitions.tolist()

X = df.loc[:, ~df.columns.isin(['origin'])]
y = df.iloc[:,7].values

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 21) 


scaler = StandardScaler()
pca = PCA(n_components = 2)
dtm_i = list(range(2, len(X_train.columns)))
dtm_i2 = list(range(0, len(X_train.columns)-2))

preprocess = ColumnTransformer(transformers=[('scaler', scaler, dtm_i)], remainder='passthrough')
preprocess2 = ColumnTransformer(transformers=[('pcadtm', pca, dtm_i2)], remainder='passthrough')


pipeline = Pipeline([
    ('prep', preprocess),
    ('prep2', preprocess2),
    ('clf', RandomForestClassifier())
])


search_space = [
    {
       'prep2__pcadtm__n_components': [2, 3]
    },
    {
       'clf': [RandomForestClassifier()],
       'clf__max_depth': [5, 15]
    },
    {
       'clf': [KNeighborsClassifier()],
       'clf__n_neighbors' : [2, 3]
    }
]


# Create grid search
grid_imba = GridSearchCV(
    estimator = pipeline,
    param_grid = search_space,
    scoring = 'accuracy',
    cv = 3,
    return_train_score = True
)

## Fit the model using all the different estimators
grid_imba.fit(X_train, y_train);

## Extract best
best_params = grid_imba.best_params_
print(best_params)
##{'prep2__pcadtm__n_components': 3}