Как использовать предопределенный сплит для RandomizedSearchCV - PullRequest
0 голосов
/ 17 марта 2020

Я пытаюсь упорядочить свой случайный лесной регрессор с помощью RandomizedSearchCV. С RandomizedSearchCV поезд и тест не указаны явно, мне нужно иметь возможность указать мой набор тестов поезда, чтобы я мог предварительно обработать их после разделения. Затем я нашел эту полезную QnA , а также эту . Но я все еще не знаю, как это сделать, поскольку в моем случае я использую перекрестную проверку. Я уже пытался добавить свой тестовый набор из перекрестной проверки, но он не работает. Там написано ValueError: could not broadcast input array from shape (1824,9) into shape (1824), что относится к моему X_test

x = np.array(avo_sales.drop(['TotalBags','Unnamed:0','year','region','Date'],1))
y = np.array(avo_sales.TotalBags)

kf = KFold(n_splits=10)

for train_index, test_index in kf.split(x):
    X_train, X_test, y_train, y_test = x[train_index], x[test_index], y[train_index], y[test_index]

impC = SimpleImputer(strategy='most_frequent')
X_train[:,8] = impC.fit_transform(X_train[:,8].reshape(-1,1)).ravel()
X_test[:,8] = impC.transform(X_test[:,8].reshape(-1,1)).ravel()

imp = SimpleImputer(strategy='median')
X_train[:,1:8] = imp.fit_transform(X_train[:,1:8])
X_test[:,1:8] = imp.transform(X_test[:,1:8])

le = LabelEncoder()
X_train[:,8] = le.fit_transform(X_train[:,8])
X_test[:,8] = le.transform(X_test[:,8])

train_indices = X_train, y_test
test_indices = X_test, y_test
my_test_fold = np.append(train_indices, test_indices)
pds = PredefinedSplit(test_fold=my_test_fold)

n_estimators = [int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]
max_features = ['auto', 'sqrt']
max_depth = [int(x) for x in np.linspace(10, 110, num = 11)]
max_depth.append(None)
min_samples_split = [2, 5, 10]
min_samples_leaf = [1, 2, 4]
bootstrap = [True, False]
random_grid = {'n_estimators': n_estimators,
               'max_features': max_features,
               'max_depth': max_depth,
               'min_samples_split': min_samples_split,
               'min_samples_leaf': min_samples_leaf,
               'bootstrap': bootstrap}
rfr = RandomForestRegressor()
rfr_random = RandomizedSearchCV(estimator = rfr , 
                               param_distributions = random_grid,
                               n_iter = 100,
                               cv = pds, verbose=2, random_state=42, n_jobs = -1) <-- i'll be filling the cv parameter with the predefined split
rfr_random.fit(X_train, y_train)

1 Ответ

0 голосов
/ 19 марта 2020

Я думаю, что ваш лучший вариант - использовать конвейер плюс ColumnTransformer . Конвейеры позволяют указать несколько этапов вычислений, включая предварительную / последующую обработку, а преобразователь столбцов применяет различные преобразования к различным столбцам. В вашем случае это будет что-то вроде:

pipeline = make_pipeline([
    make_column_transformer([
        (SimpleImputer(strategy='median'), range(1, 8)),
        (make_pipeline([
            SimpleImputer(strategy='most_frequent'),
            LabelEncoder(),
        ]), 8)
    ]),
    RandomForestRegressor()
])

Затем вы используете эту модель в качестве обычного оценщика с обычным fit и predict API. В частности, вы даете это рандомизированному поиску:

rfr_random = RandomizedSearchCV(estimator = pipeline, ...)

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

Это, безусловно, не будет работать без дальнейшей адаптации, но, надеюсь, вы поняли.

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