В документации h2o для опции weights_column
указано, что
Эта опция указывает столбец в тренировочной рамке, который будет использоваться при определении весов. Веса являются весами наблюдений для каждой строки и не увеличивают размер фрейма данных. Обычно это число повторений строки, но также поддерживаются нецелые значения. Во время тренировки ряды с большим весом имеют большее значение из-за большего коэффициента потерь.
Меня особенно интересует влияние столбца весов на деревья регрессии DRF
(случайный лес).
Я нахожу описание «Это, как правило, количество повторений строки» запутанным. Хотя они говорят, что размер фрейма фактически не увеличивается, он намекает на то, что строки с большим / меньшим весом подвергаются избыточной / недостаточной выборке (когда данные обучения для каждого дерева выбраны в соответствии с sample_rate
). Однако, глядя на исходный код h2o на github, похоже, это не так.
Соответствующие части кода, где используются веса, находятся в DHistogram.java и читаются
double wy = weight * y;
double wyy = wy * y; // This is the correct implementation.
int b = bin(col_data);
_vals[3*b + 0] += weight;
_vals[3*b + 1] += wy;
_vals[3*b + 2] += wyy;
Это означает, что весовые коэффициенты используются только для вычисления количества взвешенных строк (_vals[3*b + 0]
) и для взвешенных сумм квадратов ошибок (через _vals[3*b + 1]
и _vals[3*b + 2]
, см. DTree.java ).
Кроме того, я провел несколько тестов с разными весами в R
. Я тренировал различные DRF
модели, каждая с однородными весами для всех наблюдений, но с разной величиной веса для моделей. Мое подозрение, что веса используются только для взвешенного числа строк, а взвешенные квадратные ошибки, похоже, подтверждаются.
library(h2o)
h2o.init()
#different weights for each model
iris$weight0=0.5
iris$weight1=1
iris$weight2=2
irisH=as.h2o(iris)
predNames=setdiff(colnames(irisH),c("Sepal.Length","weight2","weight1","weight0"))
exludeLinesRegex="(.*DRF_model_R_.*)|(.*AUTOGENERATED.*)|(.*UUID.*)|(.*weight.*)"
pojoList=list()
#train 3 models, each with different weights magnitude
for (i in 0:2) {
weightColName=paste0("weight",i)
tmpRf=h2o.randomForest(y="Sepal.Length",
x=predNames,
training_frame = irisH,
seed = 1234,
ntrees = 10,
#min_rows has to be adjusted-it refers to weighted rows
min_rows= 20*irisH[1,weightColName],
max_depth = 3,
mtries = 4,
weights_column = weightColName)
tmpPojo=capture.output(h2o.download_pojo(tmpRf))
pojoList[[length(pojoList)+1]]=tmpPojo[!grepl(exludeLinesRegex,tmpPojo)]
}
h2o.shutdown(FALSE)
# all forests are the same
length(unique(pojoList))
# 1
Как видно выше, все 3 леса одинаковы, несмотря на разную величину веса. Единственная корректировка, которую нужно было сделать, это min_rows
, поскольку она относится к взвешенному номеру строки.
Если бы строки действительно переполнились / недосэмплировались, я бы ожидал увидеть (небольшие) различия между моделями.
Поэтому мои вопросы:
- Используются ли веса где-либо еще, кроме как для вычисления количества взвешенных строк и суммы квадратов ошибок?
- Являются ли регрессионные
DRF
модели, как правило, инвариантными при однородном масштабировании весов, т. Е. Если я умножу столбец весов на скаляр a>0
и скорректирую min_rows
соответственно, останутся ли модели такими же? (Как показано в примере кода R выше.)
- Если да, верно ли это для лесов с деревьями классификации и
GBM
моделями?
Спасибо за помощь!