import numpy as np
import pandas as pd
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
Посмотрим на примере данных по оттоку клиентов из телеком-компании.
df = pd.read_csv("../../data/telecom_churn.csv")
df.head()
Штаты просто занумеруем, а признаки International plan (наличие международного роуминга), Voice mail plan (наличие голосовой почтыы) и целевой Churn сделаем бинарными.
state_enc = LabelEncoder()
df["State"] = state_enc.fit_transform(df["State"])
df["International plan"] = (df["International plan"] == "Yes").astype("int")
df["Voice mail plan"] = (df["Voice mail plan"] == "Yes").astype("int")
df["Churn"] = (df["Churn"]).astype("int")
Разделим данные на обучающую и тестовую выборки в отношении 7:3. Создадим соотв. объекты DMAtrix.
X_train, X_test, y_train, y_test = train_test_split(
df.drop("Churn", axis=1), df["Churn"], test_size=0.3, random_state=42
)
dtrain = xgb.DMatrix(X_train, y_train)
dtest = xgb.DMatrix(X_test, y_test)
Зададим параметры Xgboost.
params = {"objective": "binary:logistic", "max_depth": 3, "silent": 1, "eta": 0.5}
num_rounds = 10
Будем отслеживать качество модели и на обучающей выборке, и на валидационной.
watchlist = [(dtest, "test"), (dtrain, "train")]
В Xgboost реализованы большинство популярных метрик для классификации, регрессии и ранжирования:
rmse
- root mean square errormae
- mean absolute errorlogloss
- negative log-likelihooderror
(по умолчанию) - доля ошибок в бинарной классификацииmerror
- доля ошибок в классификации на несколько классовauc
- area under curvendcg
- normalized discounted cumulative gainmap
- mean average precisionxgb_model = xgb.train(params, dtrain, num_rounds, watchlist)
Чтоб отслеживать log_loss, просто добавим ее в словарь params.
params["eval_metric"] = "logloss"
xgb_model = xgb.train(params, dtrain, num_rounds, watchlist)
Можно отслеживать сразу несколько метрик.
params["eval_metric"] = ["logloss", "auc"]
xgb_model = xgb.train(params, dtrain, num_rounds, watchlist)
Чтобы создать свою метрику качества, достаточно определить функцию, принимающую 2 аргумента: вектор предсказанных вероятностей и объект DMatrix
с истинными метками.
В этом примере функция вернет просто число объектов, на которых классификатор ошибся, когла относил к классу 1 при превышении предсказанной вероятности класса 1 порога 0.5.
Далее передаем эту функцию в xgb.train (параметр feval), если метрика тем лучше, чем меньше, надо дополнительно указать maximize=False
.
# custom evaluation metric
def misclassified(pred_probs, dmatrix):
labels = dmatrix.get_label() # obtain true labels
preds = pred_probs > 0.5 # obtain predicted values
return "misclassified", np.sum(labels != preds)
xgb_model = xgb.train(
params, dtrain, num_rounds, watchlist, feval=misclassified, maximize=False
)
С помощью параметра evals_result можно сохранить значения метрик по итерациям.
evals_result = {}
xgb_model = xgb.train(
params,
dtrain,
num_rounds,
watchlist,
feval=misclassified,
maximize=False,
evals_result=evals_result,
)
evals_result
Ранняя остановка используется для того, чтобы прекратить обучение модели, если ошибка за несколько итераций не уменьшилась.
params["eval_metric"] = "error"
num_rounds = 1500
xgb_model = xgb.train(params, dtrain, num_rounds, watchlist, early_stopping_rounds=10)
print("Booster best train score: {}".format(xgb_model.best_score))
print("Booster best iteration: {}".format(xgb_model.best_iteration))
Продемонстрируем функцию xgboost.cv.
num_rounds = 10
hist = xgb.cv(params, dtrain, num_rounds, nfold=10, metrics={"error"}, seed=42)
hist
Замечания:
as_pandas
),feval
и maximize
),early_stopping_rounds
)