Reputation: 2081
I have this kind of data (columns):
| year-month | client_id | Y | X1.. Xn |
Where Y
is if the client client_id
purchased the product in a given year-month
. And X
are the explanatory variables. I have two years of monthly data, and I have done the split correctly with TimeSeriesSplit()
given in this answer. The problem now, is that I'm looking to do a GridSearchCV()
on that split, trying different models (RF
, XGBoostClassifier()
, LightGBM()
, etc.) with different hyperparameters, but I can't figure out a way to use the GridSearchCV()
with the split done.
Any suggestions?
Upvotes: 1
Views: 2598
Reputation: 2822
Assuming you have splits
df based on this question.
First save indices for each Fold into arrays of tuples (train,test), i.e,:
[(train_indices, test_indices), # 1stfold
(train_indices, test_indices)] # 2nd fold etc
The following code will do this:
custom_cv = []
for FOLD_train,FOLD_test in zip(splits['train'],splits['test']):
custom_cv.append((np.array(FOLD_train.index.values.tolist()),np.array(FOLD_test.index.values.tolist())))
you can use GridSearchCV()
in the following manner:
Here we create dictionary with classifier functions and another dictionary with param list
This is just a sample make sure to limit search space when testing,
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
from xgboost import XGBRegressor
dict_classifiers = {
"Random Forest": RandomForestClassifier(),
"Gradient Boosting Classifier": GradientBoostingClassifier(),
"Linear SVM": SVC(),
"XGB": XGBRegressor(),
"Logistic Regression": LogisticRegression(),
"Nearest Neighbors": KNeighborsClassifier(),
"Decision Tree": DecisionTreeClassifier(),
}
params = {
"Random Forest": {"max_depth": range(5, 30, 5), "min_samples_leaf": range(1, 30, 2),
"n_estimators": range(100, 2000, 200)},
"Gradient Boosting Classifier": {"learning_rate": [0.001, 0.01, 0.1], "n_estimators": range(1000, 3000, 200)},
"Linear SVM": {"kernel": ["rbf", "poly"], "gamma": ["auto", "scale"], "degree": range(1, 6, 1)},
"XGB": {'min_child_weight': [1, 5, 10],
'gamma': [0.5, 1, 1.5, 2, 5],
'subsample': [0.6, 0.8, 1.0],
'colsample_bytree': [0.6, 0.8, 1.0],
'max_depth': [3, 4, 5], "n_estimators": [300, 600],
"learning_rate": [0.001, 0.01, 0.1],
},
"Logistic Regression": {'penalty': ['none', 'l2'], 'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]},
"Nearest Neighbors": {'n_neighbors': [3, 5, 11, 19], 'weights': ['uniform', 'distance'], 'metric': ['euclidean', 'manhattan']},
"Decision Tree": {'criterion': ['gini', 'entropy'], 'max_depth': np.arange(3, 15)},
}
for classifier_name in dict_classifiers.keys() & params:
print("training: ", classifier_name)
gridSearch = GridSearchCV(
estimator=dict_classifiers[classifier_name], param_grid=params[classifier_name], cv=custom_cv)
gridSearch.fit(df[['X']].to_numpy(), # shoud have shape of (n_samples, n_features)
df[['Y']].to_numpy().reshape((-1))) #this should be an array with shape (n_samples,)
print(gridSearch.best_score_, gridSearch.best_params_)
replace ['X']
with df.columns[pd.Series(df.columns).str.startswith('X')]
on gridsearch.fit
, if you want to pass in all columns starting with 'X'
in their name (e.g., 'X1'
,'X2'
, ...) as train_set.
Upvotes: 1