sparse.model.matrix создает противоречивый вывод - PullRequest
1 голос
/ 24 января 2020

У меня есть модель xgboost на двух разных серверах - тестовом сервере и производственном сервере. Каждый сервер имеет абсолютно одинаковые данные и абсолютно одинаковый код, но когда я применяю одну и ту же модель к одинаковым данным в каждой среде, я получаю немного разные результаты. Нам нужно, чтобы результаты были идентичны.

Я обнаружил, что объект разреженной матрицы, который возвращает следующая строка, отличается на каждом сервере:

mm <- sparse.model.matrix(y ~ ., data = df.new)[,-1]

mm в тесте Сервер имеет @i и @x длины 182, тогда как mm на рабочем сервере имеет @i и @x длины 184. Опять же, я сравнил df.new с обоих серверов, и они идентичны.

Я попытался понизить пакет Matrix на производственном сервере, чтобы версии совпадали, но он все еще дает другие результаты. Единственная идея, которую я оставил, состоит в том, чтобы соответствовать версиям каждого пакета.

У кого-нибудь есть предложения относительно того, что может происходить? К сожалению, я не могу поделиться данными, но если это поможет, это 227 переменных смешанных типов (775 при преобразовании в разреженную матрицу модели). Большинство переменных в основном 0. 0. 1019 *

Я не знаю, имеет ли это значение или нет, но тестовый сервер - Windows, а рабочий сервер - Linux.

1 Ответ

1 голос
/ 01 февраля 2020

Вы укушены соединением двух проблем:

(1) вычисления с плавающей точкой изначально чувствительны к небольшим различиям (платформа, компилятор, настройки компилятора ...) (2) упорядоченные коэффициенты в R используют ортогональный полином контрастов (см. ?contr.poly, Venables и Ripley Современная прикладная статистика с S или здесь ), которые включают вычисления с плавающей точкой.

dd <- data.frame(x=ordered(0:2))
> Matrix::sparse.model.matrix(~x,dd)
3 x 3 sparse Matrix of class "dgCMatrix"
  (Intercept)           x.L        x.Q
1           1 -7.071068e-01  0.4082483
2           1 -7.850462e-17 -0.8164966
3           1  7.071068e-01  0.4082483

Вы можете видеть, что одна из записей здесь близка, но не точно равна нулю. До сих пор я не смог придумать пример, показывающий разницу между двумя удобными мне платформами (Ubuntu Linux и MacOS), но это почти наверняка является источником вашей проблемы; почти нулевая запись вычисляется как точно ноль на одной платформе, но не на другой.

Вероятно, не существует идеального решения этой проблемы, но zapsmall() преобразует небольшие записи в ноль и drop0 преобразует их из явных (неявных) (структурных) нулевых записей, поэтому drop0(zapsmall(mm)) может работать ...

...