eval_set on XGBClassifier can someone explain what does the eval_set parameter do on the XGBClassifier?
I thought that by using eval_set, the algorithm would do some sort of grid search and find the best model to fit on train and test on the "eval_set" but I realize that both codes bellow produce basically the same log loss - so it seems unnecessary to use eval_set
model = XGBClassifier(objective='multi:softprob', n_estimators=500)
model.fit(X_train, y_train)
preds = model.predict_proba(X_valid)
log_loss(y_valid, preds)
#logloss: 0.8119

ad
model.fit(X_train, y_train, eval_set=[(X_valid, y_valid)],
        eval_metric = 'mlogloss',early_stopping_rounds=25, verbose=True)

best_iter = model.best_iteration
y_valid_pred = model.predict_proba(X_valid, ntree_limit = best_iter)
log_loss(y_valid, y_valid_pred)
#logloss: 0.8118

thanks
 A: I don't know which version of xgboost you were using, but in my set-up it makes a difference.
I'm using xgboost ver. 0.6a2, and sklearn 0.18.1.
When I run:
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier

# create a synthetic data set
X, y = make_classification(n_samples=2500, n_features=45, n_informative=5, n_redundant=25)
X_train, X_val, y_train, y_val = train_test_split(X, y, train_size=.8, random_state=0)

xgb_clf = XGBClassifier()
xgb_clf.fit(X_train, y_train, eval_set=[(X_train, y_train), (X_val, y_val)], early_stopping_rounds=10, verbose=True)

I get the following output (only a few first lines):

[0]   validation_0-error:0.0735   validation_1-error:0.106
Multiple eval metrics have been passed: 'validation_1-error' will be used for early stopping.
Will train until validation_1-error hasn't improved in 10 rounds.
[1]   validation_0-error:0.0725   validation_1-error:0.09
...

So, in other words, the last pair (X,y) from eval_set is used for early stopping. And it seems to behave reasonably -- I'm getting different (better) results on the validation set when I use early stopping. 
BTW, the metric used for early stopping is by default the same as the objective (defaults to 'binomial:logistic' in the provided example), but you can use a different metric, for example:
xgb_clf.fit(X_train, y_train, eval_set=[(X_train, y_train), (X_val, y_val)], eval_metric='auc', early_stopping_rounds=10, verbose=True)

Note, however, that the objective stays the same, it's only the criterion used in early stopping that's changed (it's now based on the area under the Sensitivity-Specificity curve).
You can monitor two different types of metrics, like so:
xgb_clf.fit(X_train, y_train, eval_set=[(X_train, y_train), (X_val, y_val)], eval_metric=['logloss', 'auc'], early_stopping_rounds=10, verbose=True)

And, like with eval_set, the last element ('auc') shall be used for deciding when to stop early. 
