Запись лучших классификаторов GridSearch в таблицу

Я нашел и успешно протестировал следующий скрипт, который применяет Pipeline и GridSearchCV к выбору классификатора. Скрипт выводит лучший классификатор и его точность.

import numpy as np
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline

from sklearn import datasets
iris = datasets.load_iris()
X_train = iris.data
y_train = iris.target
X_test = iris.data[:10] # Augmenting test data
y_test = iris.target[:10] # Augmenting test data

#Create a pipeline
pipe = Pipeline([('classifier', LogisticRegression())])

# Create space of candidate learning algorithms and their hyperparameters
search_space = [{'classifier': [LogisticRegression()],
                 'classifier__penalty': ['l1', 'l2'],
                 'classifier__C': np.logspace(0, 4, 10)},
                {'classifier': [RandomForestClassifier()],
                 'classifier__n_estimators': [10, 100, 1000],
                 'classifier__max_features': [1, 2, 3]}]

# Create grid search 
clf = GridSearchCV(pipe, search_space, cv=5, verbose=0)

# Fit grid search
best_model = clf.fit(X_train, y_train)

print('Best training accuracy: %.3f' % best_model.best_score_)
print('Best estimator:', best_model.best_estimator_.get_params()['classifier'])
# Predict on test data with best params
y_pred = best_model.predict(X_test)
# Test data accuracy of model with best params
print(classification_report(y_test, y_pred, digits=4))
print('Test set accuracy score for best params: %.3f' % accuracy_score(y_test, y_pred))

from sklearn.metrics import precision_recall_fscore_support
print(precision_recall_fscore_support(y_test, y_pred, 
average='weighted'))

Как настроить скрипт так, чтобы он выдавал не только лучший классификатор, которым в нашем примере является LogReg, но и лучший, выбранный среди других классификаторов? Выше мне также нравится видеть вывод из RandomForestClassifier().

Идеальным является решение, в котором показан лучший классификатор для каждого алгоритма (LogReg, RandomForest,..) и где каждый из этих лучших классификаторов отсортирован в таблицу. Первый столбец или индекс должен быть моделью, а значения precision_recall_fscore_support находятся в строках справа. Затем таблица должна быть отсортирована по F-оценке.

PS: хотя скрипт работает, я еще не уверен, какова функция LogisticRegression() в конвейере, поскольку она определена в пространстве поиска позже.

Решение (упрощенное):

from sklearn import datasets
iris = datasets.load_iris()
X_train = iris.data
y_train = iris.target
X_test = iris.data[:10]
y_test = iris.target[:10]

seed=1
models = [
            'RFC',
            'logisticRegression'
         ]
clfs = [
        RandomForestClassifier(random_state=seed,n_jobs=-1),
        LogisticRegression()
        ]

params = {
            models[0]:{'n_estimators':[100]},
            models[1]: {'C':[1000]}
         }


for name, estimator in zip(models,clfs):

    print(name)

    clf = GridSearchCV(estimator, params[name], scoring='accuracy', refit='True', n_jobs=-1, cv=5)

    clf.fit(X_train, y_train)

    print("best params: " + str(clf.best_params_))
    print("best scores: " + str(clf.best_score_))

    y_pred = clf.predict(X_test)
    acc = accuracy_score(y_test, y_pred)

    print("Accuracy: {:.4%}".format(acc))
    print(classification_report(y_test, y_pred, digits=4))

person Christopher    schedule 11.05.2018    source источник
comment
@Кристофер, надеюсь, мой ответ поможет   -  person seralouk    schedule 12.05.2018


Ответы (1)


Если я правильно понял, это должно работать нормально.

import pandas as pd
import numpy as np

df = pd.DataFrame(list(best_model.cv_results_['params']))
ranking = best_model.cv_results_['rank_test_score']
# The sorting is done based on the test_score of the models.
sorting = np.argsort(best_model.cv_results_['rank_test_score'])

# Sort the lines based on the ranking of the models
df_final = df.iloc[sorting]

# The first line contains the best model and its parameters
df_final.to_csv('sorted_table.csv')

# OR to avoid the index in the writting 
df_final.to_csv('sorted_table2.csv',index=False)

Результаты:

Смотрите здесь


Однако в этом случае упорядочивание не выполняется на основе значений F. Для этого используйте это. Определите в GridSearch атрибут scoring для f1_weighted и повторите мой код.


Пример:

...
clf = GridSearchCV(pipe, search_space, cv=5, verbose=0,scoring='f1_weighted')

best_model = clf.fit(X_train, y_train)

df = pd.DataFrame(list(best_model.cv_results_['params']))
ranking = best_model.cv_results_['rank_test_score']

# The sorting is done based on the F values of the models.
sorting = np.argsort(best_model.cv_results_['rank_test_score'])

# Sort the lines based on the ranking of the models
df_final = df.iloc[sorting]

df_final.to_csv('F_sorted_table.csv')

Результаты: Здесь


person seralouk    schedule 11.05.2018
comment
Спасибо. Это почти ответ, я думаю. Для приведенного выше примера я бы ожидал только две строки: логистическая регрессия, а затем RandomForest, каждая со своей лучшей моделью и результатом. Я подумал, что модели могут быть записаны в словарь, а затем будет вызван лучший результат для каждого элемента словаря. Я пытался, но у меня было несколько проблем с синтаксисом. - person Christopher; 12.05.2018
comment
привет. затем вы можете отфильтровать кадр данных df_final pandas, чтобы сохранить первый Logistic и первый RandomForest, найденные во втором столбце. - person seralouk; 12.05.2018