Как выполнить поиск по сетке для нескольких моделей ML

Обычно мы используем GridSearchCV для выполнения поиска по сетке по гиперпараметрам одной конкретной модели, например:

model_ada = AdaBoostClassifier()
params_ada = {'n_estimators':[10,20,30,50,100,500,1000], 'learning_rate':[0.5,1,2,5,10]}
grid_ada = GridSearchCV(estimator = model_ada, param_grid = params_ada, scoring = 'accuracy', cv = 5, verbose = 1, n_jobs = -1)
grid_ada.fit(X_train, y_train)

Есть ли какой-либо метод или функция, которая позволяет нам выполнять поиск по сетке на самих моделях ML? Например, я хочу сделать, как указано ниже:

models = {'model_gbm':GradientBoostingClassifier(), 'model_rf':RandomForestClassifier(), 'model_dt':DecisionTreeClassifier(), 'model_svm':SVC(), 'model_ada':AdaBoostClassifier()}
params_gbm = {'learning_rate':[0.1,0.2,0.3,0.4], 'n_estimators':[50,100,500,1000,2000]}
params_rf = {'n_estimators':[50,100,500,1000,2000]}
params_dt = {'splitter':['best','random'], 'max_depth':[1, 5, 10, 50, 100]}
params_svm = {'C':[1,2,5,10,50,100,500], 'kernel':['rbf','poly','sigmoid','linear']}
params_ada = {'n_estimators':[10,20,30,50,100,500,1000], 'learning_rate':[0.5,1,2,5,10]}
params = {'params_gbm':params_gbm, 'params_rf':params_rf, 'params_dt':params_dt, 'params_svm':params_svm, 'params_ada':params_ada}
grid_ml = "that function"(models = models, params = params)
grid_ml.fit(X_train, y_train)

где «эта функция» — это функция, которую мне нужно использовать для выполнения этого типа операции.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
296
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Даже я столкнулся с подобной проблемой, но не смог найти предопределенный пакет/метод, который мог бы достичь этого. Поэтому я написал свою собственную функцию для достижения этого:

    def Algo_search(models , params):

       max_score = 0
       max_model = None
       max_model_params = None

       for i,j in zip(models.keys() , models.values() ):

            gs = GridSearchCV(estimator=j,param_grid=params[i])
            a = gs.fit(X_train,y_train)
            score = gs.score(X_test,y_test)

            if score > max_score:
                max_score = score
                max_model = gs.best_estimator_
                max_model_params = gs.best_params_

       return max_score, max_model, max_model_params

      #Data points
    models = {'model_gbm':GradientBoostingClassifier(), 'model_rf':RandomForestClassifier(), 
      'model_dt':DecisionTreeClassifier(), 'model_svm':SVC(), 'model_ada':AdaBoostClassifier()}
   params_gbm = {'learning_rate':[0.1,0.2,0.3,0.4], 'n_estimators':[50,100,500,1000,2000]}
   params_rf = {'n_estimators':[50,100,500,1000,2000]}
   params_dt = {'splitter':['best','random'], 'max_depth':[1, 5, 10, 50, 100]}
   params_svm = {'C':[1,2,5,10,50,100,500], 'kernel':['rbf','poly','sigmoid','linear']}
   params_ada = {'n_estimators':[10,20,30,50,100,500,1000], 'learning_rate':[0.5,1,2,5,10]}
   params = {'model_gbm':params_gbm, 'model_rf':params_rf, 'model_dt':params_dt, 'model_svm':params_svm, 'model_ada':params_ada}
   grid_ml = Algo_search(models = models, params = params)

@MujeeburRahman Братан, я думаю, ты только что выбрал более короткий ответ. Мой подробно рассмотрел проблему, чтобы вы знали последствия своей реализации. Вы явно упустили мою мысль об использовании OrderedDict, так как этот ответ не будет работать в большинстве реализаций Python (даже если он работает сейчас в вашей текущей версии Python). Посмотрите здесь, чтобы понять, почему.

Yahya 28.12.2020 14:05

Ты прав, братан. Извини, что не упомянул раньше, но мне понравились оба решения. Я использую оба этих решения в разных местах. К сожалению, я не могу принять два ответа, поэтому я принял ответ, который соответствовал моему требованию в этой ситуации. В настоящее время я использую ваше решение для другого сценария. Спасибо за ваши усилия, чтобы дать мне решение...

Mujeebur Rahman 23.04.2021 08:00

Должно быть просто выполнить несколько GridSearchCV, а затем сравнить результаты.

Ниже приведен полный пример того, как этого добиться.

Обратите внимание, что есть возможности для улучшения, я оставлю это вам. Тем не менее, это только для того, чтобы дать вам некоторое представление об этой идее.

from sklearn import datasets
from sklearn.ensemble import GradientBoostingClassifier, \
RandomForestClassifier, AdaBoostClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier


def get_param(model_name, params):
    """
    Not the most sufficient way.
    I recommend to have params and models
    in OrderedDict() instead.
    """
    for k, v in params.items():
        mn = str(model_name).upper().split('_')
        for k_ in str(k).upper().split('_'):
            if k_ in mn:
                return v


def models_gridSearchCV(models, params, scorer, X, y):
    all_results = dict.fromkeys(models.keys(), [])
    best_model = {'model_name': None,
                  'best_estimator': None,
                  'best_params': None,
                  'best_score': -9999999}
    for model_name, model in models.items():
        print("Processing {} ...".format(model_name))
        # or use OrderedDict() and zip(models, params) above
        # so there will be no need to check
        param = get_param(model_name, params)
        if param is None:
            continue
        clf = GridSearchCV(model, param, scoring=scorer)
        clf.fit(X, y)
        all_results[model_name] = clf.cv_results_
        if clf.best_score_ > best_model.get('best_score'):
            best_model['model_name'] = model_name
            best_model['best_estimator'] = clf.best_estimator_
            best_model['best_params'] = clf.best_params_
            best_model['best_score'] = clf.best_score_

    return best_model, all_results


### TEST ###
iris = datasets.load_iris()
X, y = iris.data, iris.target

# OrderedDict() is recommended here
# to maintain order between models and params 
models = {'model_gbm': GradientBoostingClassifier(),
          'model_rf': RandomForestClassifier(),
          'model_dt': DecisionTreeClassifier(),
          'model_svm': SVC(),
          'model_ada': AdaBoostClassifier()}
params_gbm = {'learning_rate': [0.1, 0.2], 'n_estimators': [50, 100]}
params_rf = {'n_estimators': [50, 100]}
params_dt = {'splitter': ['best', 'random'], 'max_depth': [1, 5]}
params_svm = {'C': [1, 2, 5], 'kernel': ['rbf', 'linear']}
params_ada = {'n_estimators': [10, 100], 'learning_rate': [0.5, 1]}

# OrderedDict() is recommended here
# to maintain order between models and params 
params = {'params_gbm': params_gbm,
          'params_rf': params_rf,
          'params_dt': params_dt,
          'params_svm': params_svm,
          'params_ada': params_ada}

best_model, all_results = models_gridSearchCV(models, params, 'accuracy', X, y)
print(best_model)
# print(all_results)

Результат

Processing model_gbm ...
Processing model_rf ...
Processing model_dt ...
Processing model_svm ...
Processing model_ada ...
{'model_name': 'model_svm', 'best_estimator': SVC(C=5), 
 'best_params': {'C': 5, 'kernel': 'rbf'}, 'best_score': 0.9866666666666667}

Другие вопросы по теме

Как передать нормализованные новые данные в сохраненную модель обученной нейронной сети, а затем инвертировать результат?
Получение пустого графика при построении графика зависимости стоимости от эпохи для модели многомерной линейной регрессии
Нейронная сеть для классификации с использованием функционального API Keras: One-hot-encoded y_train; Ошибка несовместимости формы
TypeError: не удалось построить TypeSpec с типом KerasTensor
ML.NET: Зачем мне обучать предварительно обученную модель?
Обучайте и тестируйте разделенные данные с функциями
Почему эта модель машинного обучения дает мне нулевую точность?
После обучения модели линейной регрессии с использованием scikit-learn Как делать прогнозы для новых точек данных, которых нет в исходном наборе данных?
Pandas: TypeError: аргумент float() должен быть строкой или числом, а не 'pandas._libs.interval.Interval'
Max_length не исправляет модель ответов на вопросы