GridSeachCV с отдельными наборами обучения и проверки ошибочно учитывает также результаты обучения для окончательного выбора лучшей модели - PullRequest
0 голосов
/ 30 сентября 2018

У меня есть набор данных из 3500 наблюдений x 70 объектов, который является моим обучающим набором, и у меня также есть набор данных из 600 наблюдений x 70 объектов, который является моим набором проверки.Цель состоит в том, чтобы правильно классифицировать наблюдения как 0 или 1.

Я использую Xgboost и нацеливаюсь на максимально возможную точность при пороге классификации = 0.5.

Я выполняю поиск по сетке:

import numpy as np
import pandas as pd
import xgboost

# Import datasets from edge node
data_train = pd.read_csv('data.csv')
data_valid = pd.read_csv('data_valid.csv')

# Specify 'data_test' as validation set for the Grid Search below
from sklearn.model_selection import PredefinedSplit
X, y, train_valid_indices = train_valid_merge(data_train, data_valid)
train_valid_merge_indices = PredefinedSplit(test_fold=train_valid_indices)

# Define my own scoring function to see
# if it is called for both the training and the validation sets
from sklearn.metrics import make_scorer
custom_scorer = make_scorer(score_func=my_precision, greater_is_better=True, needs_proba=False)

# Instantiate xgboost
from xgboost.sklearn import XGBClassifier
classifier = XGBClassifier(random_state=0)

# Small parameters' grid ONLY FOR START
# I plan to use way bigger parameters' grids 
parameters = {'n_estimators': [150, 175, 200]}

# Execute grid search and retrieve the best classifier
from sklearn.model_selection import GridSearchCV
classifiers_grid = GridSearchCV(estimator=classifier, param_grid=parameters, scoring=custom_scorer,
                                   cv=train_valid_merge_indices, refit=True, n_jobs=-1)
classifiers_grid.fit(X, y)

............................................................................

train_valid_merge - Укажите свой собственный набор проверки:

Я хочу провести обучение каждой модели с моим набором обучения (data_train) и настройкой гиперпараметра с отдельным / отдельным набором проверки:мой (data_valid).По этой причине я определяю функцию с именем train_valid_merge, которая объединяет мои тренировки и мой набор проверки, чтобы их можно было подавать в GridSeachCV, и я также использовал PredefineSplit, чтобы указать, какое обучение и какая проверка установлены вэтот объединенный набор:

def train_valid_merge(data_train, data_valid):

    # Set test_fold values to -1 for training observations
    train_indices = [-1]*len(data_train)

    # Set test_fold values to 0 for validation observations
    valid_indices = [0]*len(data_valid)

    # Concatenate the indices for the training and validation sets
    train_valid_indices = train_indices + valid_indices

    # Concatenate data_train & data_valid
    import pandas as pd
    data = pd.concat([data_train, data_valid], axis=0, ignore_index=True)
    X = data.iloc[:, :-1].values
    y = data.iloc[:, -1].values
    return X, y, train_valid_indices

............................................................................

custom_scorer - указатьмоя собственная метрика оценки:

Я определяю свою собственную функцию оценки, которая просто возвращает точность, просто чтобы увидеть, вызывается ли она как для учебных, так и для проверочных наборов:

def my_precision(y_true, y_predict):

    # Check length of 'y_true' to see if it is the training or the validation set
    print(len(y_true))

    # Calculate precision
    from sklearn.metrics import precision_score
    precision = precision_score(y_true, y_predict, average='binary')

    return precision

............................................................................

Когда я запускаю все это (для parameters = {'n_estimators': [150, 175, 200]}), то из * выводятся следующие данные1034 * при функции my_precision:

600
600
3500
600
3500
3500

, что означает, что функция оценки вызывается как для обучения, так и для набора проверки.Но я проверил, что функция оценки не только вызывается, но и ее результаты из наборов обучения и проверки используются для определения наилучшей модели из поиска в сетке (даже если я указал ее для использования только результатов набора проверки).

Например, при наших трех значениях параметров ('n_estimators': [150, 175, 200]) он учитывает баллы как для обучающего, так и для проверочного набора (2 комплекта) и, следовательно, производит (3 параметра)х (2 комплекта) = 6 различных результатов сетки.Таким образом, он выбирает лучшие наборы гиперпараметров из всех этих результатов сетки и, следовательно, может, наконец, выбрать тот, который был из результатов с набором обучения, в то время как я хотел принять во внимание только набор проверки (3 результата).

Однако, если я добавлю к функции my_precision что-то подобное, чтобы обойти тренировочный набор (установив все его значения точности в 0):

# Remember that the training set has 3500 observations
# and the validation set 600 observations
if(len(y_true>600)):
    return 0

затем (насколько япроверил это) Я определенно выбрал лучшую модель для моих спецификаций, потому что результаты точности тренировочного набора слишком малы, поскольку все они равны от 0 до.

Мои вопросы следующие:

Почему пользовательская функция оценки учитывает как обучение, так и набор для проверки, чтобы выбрать лучшую модель, в то время как я указал с помощью train_valid_merge_indices, что лучшая модель для поиска по сетке должна выбираться только в соответствии сна проверку?

Как я могу сделать GridSearchCV для учета только для проверкиустановить и оценка моделей на нем, когда будет сделан выбор и ранжирование моделей?

1 Ответ

0 голосов
/ 02 октября 2018

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

Тогда вам, безусловно, не нужны ни PredefinedSplit, ни GridSearchCV:

import pandas as pd
from xgboost.sklearn import XGBClassifier
from sklearn.metrics import precision_score

# Import datasets from edge node
data_train = pd.read_csv('data.csv')
data_valid = pd.read_csv('data_valid.csv')

# training data & labels:
X = data_train.iloc[:, :-1].values
y = data_train.iloc[:, -1].values   

# validation data & labels:
X_valid = data_valid.iloc[:, :-1].values
y_true = data_valid.iloc[:, -1].values 

n_estimators = [150, 175, 200]
perf = []

for k_estimators in n_estimators:
    clf = XGBClassifier(n_estimators=k_estimators, random_state=0)
    clf.fit(X, y)

    y_predict = clf.predict(X_valid)
    precision = precision_score(y_true, y_predict, average='binary')
    perf.append(precision)

и perf не будет содержать производительность ваших соответствующих классификаторов на вашем наборе проверки..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...