scikit-learn: параметры произвольного леса class_weight и sample_weight

У меня есть проблема с дисбалансом классов, и я экспериментировал со взвешенным Случайным Лесом, используя реализацию в scikit-learn (>= 0.16).

Я заметил, что реализация принимает параметр class_weight в конструкторе дерева и параметр sample_weight в методе fit, чтобы помочь устранить дисбаланс классов. Эти два, кажется, умножены, чтобы решить окончательный вес.

У меня проблемы с пониманием следующего:

  • На каких этапах построения / обучения / прогнозирования дерева используются эти веса? Я видел некоторые документы для взвешенных деревьев, но я не уверен, что реализует Scikit.
  • В чем конкретно разница между class_weight и sample_weight?

2 ответа

Решение

RandomForests построены на деревьях, которые очень хорошо задокументированы. Проверьте, как деревья используют взвешивание выборки:

Что касается разницы между class_weight а также sample_weight: многое можно определить просто по характеру их типов данных. sample_weight 1D массив длины n_samples, присваивая явный вес каждому примеру, используемому для обучения. class_weight является ли словарь каждого класса одинаковым весом для этого класса (например, {1:.9, 2:.5, 3:.01}), или строка, сообщающая sklearn, как автоматически определять этот словарь.

Таким образом, тренировочный вес для данного примера является продуктом его явно названного sample_weight (или же 1 если sample_weight не предусмотрено), и это class_weight (или же 1 если class_weight не предусмотрено).

Если мы посмотрим исходный код ,RandomForestClassifierявляется подклассом отForestClassifierкласс, который, в свою очередь, является подклассом класса, а метод фактически определенBaseForestсорт. Как отметил ОП, взаимодействие между и определение весов выборки используется для подбора каждого дерева решений случайного леса.

Если мы проверим_validate_y_class_weight(),иметоды, мы можем понять взаимодействие между иbootstrapпараметры лучше. В частности,

  • если передается вRandomForestClassifier()конструктор, но не передается, используется в качестве образца веса
  • если и то, и другоеclass_weightпередаются, затем они умножаются вместе, чтобы определить окончательные веса выборки, используемые для обучения каждого отдельного дерева решений.
  • еслиclass_weight=None, затем определяет окончательные веса выборки (по умолчанию, если None, выборки имеют одинаковый вес).

Соответствующую часть исходного кода можно резюмировать следующим образом.

      from sklearn.utils import compute_sample_weight

if class_weight == "balanced_subsample" and not bootstrap:
    expanded_class_weight = compute_sample_weight("balanced", y)
elif class_weight is not None and class_weight != "balanced_subsample" and bootstrap:
    expanded_class_weight = compute_sample_weight(class_weight, y)
else:
    expanded_class_weight = None

if expanded_class_weight is not None:
    if sample_weight is not None:
        sample_weight = sample_weight * expanded_class_weight
    else:
        sample_weight = expanded_class_weight

Сbootstrap=True, наблюдения выбираются случайным образом для отдельных обученных деревьев, что осуществляется с помощьюsample_weightаргумент_parallel_build_trees()fit()соответствующий (сокращенный) код которого выглядит следующим образом.

      if bootstrap:
    if sample_weight is None:
        sample_weight = np.ones((X.shape[0],), dtype=np.float64)

    indices = check_random_state(tree.random_state).randint(X.shape[0], n_samples_bootstrap)
    sample_counts = np.bincount(indices, minlength=X.shape[0])
    sample_weight *= sample_counts

    if class_weight == "balanced_subsample":
        sample_weight *= compute_sample_weight("balanced", y, indices=indices)
Другие вопросы по тегам