Прогнозирование кликов по объявлению с очень несбалансированными данными

У меня есть очень несбалансированные данные (3% положительных), и я использую xgboost, чтобы немного поучиться. Файл довольно большой, и я ранее пробовал логистическую регрессию, randomforest и svm (используя только некоторую подвыборку всех данных, потому что данные слишком большие). Чтобы учесть несбалансированность данных, я попробовал данные о весе классов и балансировке с помощью SMOTE (что делает данные очень большими). Но, похоже, ничего из этого не помогает. Уровень точности ухудшается, когда я использую любой из вышеупомянутых подходов.

Когда я попробовал xgboost и попытался настроить параметр scale-positive-weight, как предлагается в документе, это только ухудшило точность. В целом, все мои модели работают хуже, чем просто предсказывают все нули.

Могу ли я как-то учесть этот дисбаланс данных?

вот мой код для xgboost

x = data[:,3:] 
y = data[:,2]
from xgboost import XGBClassifier 
model = XGBClassifier(scale_pos_weight = np.sum(y==0)/np.sum(y==1))
model.fit(x, y, eval_metric="auc")
# make predictions for test data
y_pred = model.predict(x)
#predictions = [round(value) for value in y_pred]
# evaluate predictions
accuracy = accuracy_score(y, y_pred)
print("Accuracy: %.2f%%" % (accuracy * 100.0))

person I-PING Ou    schedule 26.05.2017    source источник


Ответы (1)


Похоже, что большинство онлайн-советов по обработке несбалансированных данных с помощью XGBoost (и в противном случае) заключается в настройке гиперпараметров с помощью поиска.

Вы можете использовать GridSearchCV от scikit-learn: http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html

Но в настоящее время есть методы лучше, чем поиск по сетке для исследования параметрического пространства, например scikit-optimize: https://scikit-optimize.github.io/#skopt.BayesSearchCV < / а>

Пример: (это регрессор, бит работает точно так же для классификации

from xgboost import XGBRegressor
from skopt import BayesSearchCV

n_features = X_train.shape[1] - 1

sum_pos = np.sum(y_train==1)
sum_neg = np.sum(y_train==0)

opt = BayesSearchCV(
    XGBRegressor(objective='reg:linear', n_jobs=4, scale_pos_weight = sum_neg/sum_pos),
    {
        'n_estimators': (1, 50),
        'max_depth': (1, 20),
        'learning_rate': (10**-5, 10**0, "log-uniform"),
        'min_child_weight': (1, 5),
        'max_delta_step': (1, 10)
    },
    n_iter=8, # may want to have more iterations here... :)
    verbose=99
)

opt.fit(X_train[:,1:], y_train)
person Roy Shilkrot    schedule 09.04.2018