R - doParallel не работает с тестами Стьюдента и Фишера.

Поэтому я использую пакет R doParallel для распараллеливания некоторых шагов моего скрипта, когда мне нужно обрабатывать большой список элементов, чтобы вычислить его быстрее. С этого времени все функции, которые я использовал до сих пор, отлично работали с foreach (): мне просто нужно было указать количество ядер с помощью registerDoParallel (), и все!

Недавно я попытался использовать разные статистические тесты в R, используя var.test () и t.test (), и я не понимаю, почему, но я понял, что при использовании в foreach () он не работает ... Итак, чтобы быть больше ясно, что я в основном делаю, это перебираю строки из двух матриц одинаковых размеров: каждая строка в каждой матрице содержит 5 числовых значений, и я, например, делаю:

var.test(matrixA[1,],matrixB[1,])$p.value

для извлечения для строки номер 1 соответствующего значения p из теста Фишера, сделанного для 10 числовых значений (2 группы по 5 значений в строке номер 1 каждой матрицы). Проблема в том, что в моих матрицах миллионы строк, поэтому мне приходится перебирать количество строк, и я делаю это с помощью функции foreach ():

p.values.res<-foreach(i=seq(dim(matrixA)[1])) %dopar%
  var.test(matrixA[i,],matrixB[i,])$p.value

(Здесь я установил registerDoParallel (cores = 6) до foreach ()). Я пробовал разные тесты: тест Фишера и тест студента (t.test ()), и, к сожалению, ни один из них не работал на моих 6 ядрах, только одно.

Я также пробовал с "cl": registerDoParallel (cl = 4) Это тоже не работает.

Я попытался перезапустить R, выйти и снова открыть сеанс, перезагрузить компьютер: не работает.

Кто-нибудь знает, почему не работает и как это исправить?

Моя конфигурация: Linux Mint 18.2 Cinnamon 64-бит (3.4.6); Процессор Intel Core I7-6700; R версия 3.4.3 (30.11.2017); RStudio версии 1.1.383 2009-2017.

вот 2 коротких примера матриц

МатрицаA:

0.7111111  0.7719298  0.7027027   0.6875000  0.6857143
0.8292683  0.6904762  0.8222222   0.8333333  0.6250000
0.8846154  0.5714286  0.8928571   0.8846154  0.9259259
0.9000000  0.5000000  0.9500000   0.8666667  0.8260870
0.8235294  0.3684211  0.9411765   0.8333333  0.8000000
0.5714286  0.2142857  0.6666667   0.5000000  0.5555556

МатрицаB:

0.5227273  0.7142857  0.7808219   0.6346154  0.7362637
0.9166667  0.7173913  0.8611111   0.7391304  0.7538462
0.8666667  0.6052632  0.8260870   0.7333333  0.9024390
0.9285714  0.5806452  0.8750000   0.6956522  0.8787879
0.8333333  0.5517241  0.8333333   0.6818182  0.8750000
0.7500000  0.2941176  0.6666667   0.4444444  0.7500000

Заранее всем спасибо за помощь. С уважением,


person Yoann Pageaud    schedule 04.12.2017    source источник
comment
Вам будет легче помочь, если вы предоставите воспроизводимый пример с образцы входных данных и кода, которые мы можем скопировать / вставить для запуска. Непонятно, что именно вы пытаетесь или в чем именно заключается ошибка / проблема.   -  person MrFlick    schedule 04.12.2017
comment
Вы можете сгенерировать 2 матрицы случайных числовых значений (с точками, которые я имею в виду, например, 1.2, 2.5, ...), единственное, что особенным - это то, что обе матрицы имеют одинаковое количество строк и только 4 столбца (то есть 4 значения по строкам) I не могу легко скопировать свои матрицы в настоящее время извините ... я повторяю строку за строкой, сравнивая значения из двух матриц A и B. Пример: row 1: var.test (matrixA [1,], matrixB [1, ]) $ p.value строка 2: var.test (matrixA [2,], matrixB [2,]) $ p.value [...] и я сохраняю только p-значения каждого результата, чтобы добавить его к моему Список p.values.res.   -  person Yoann Pageaud    schedule 04.12.2017


Ответы (2)


Я не могу воспроизвести вашу проблему. У меня это отлично работает:

matrixA <- matrix(runif(36), 6)
matrixB <- matrix(runif(36), 6)

cl <- parallel::makeCluster(4)
doParallel::registerDoParallel(cl)
library(foreach)
p.values.res<-foreach(i=seq(dim(matrixA)[1])) %dopar%
  var.test(matrixA[i,],matrixB[i,])$p.value
parallel::stopCluster(cl)
person F. Privé    schedule 04.12.2017
comment
Я пробую как можно скорее ваше решение. Проблема может заключаться в том, что я не устанавливаю количество кластеров так же, как вы в моих тестах. Я держу вас на связи. - person Yoann Pageaud; 04.12.2017
comment
Прости. Пробовал, тоже не работает: через несколько секунд все переходит на 1 CPU. Есть идеи, откуда могла возникнуть эта проблема? В моем случае это происходит только для рыбака и студенческого теста. foreach () отлично работает со всеми другими функциями, которые я ранее использовал в своем опыте, кроме этих ... - person Yoann Pageaud; 04.12.2017
comment
Что вы имеете в виду под everything goes on 1 CPU? - person F. Privé; 04.12.2017
comment
извините, все на одном ядре. - person Yoann Pageaud; 04.12.2017
comment
он не распараллеливает то, что я выполняю. - person Yoann Pageaud; 04.12.2017
comment
Как вы оцениваете, распараллеливается он или нет? - person F. Privé; 04.12.2017
comment
В Linux Mint я установил небольшой виджет на панели, отображаемой внизу, чтобы увидеть в реальном времени использование ЦП, ОЗУ, ДИСКОВ ... чтобы можно было быстро проверить, какое ядро ​​работает, а какое нет. Я также могу проверить это в терминале с помощью команды: atop 2. Если я вижу, что используется только одно ядро, то оно не распараллеливается на 4 ядра. - person Yoann Pageaud; 04.12.2017
comment
С N <- 1e4; matrixA <- matrix(runif(36*N), 6*N); matrixB <- matrix(runif(36*N), 6*N) вы можете кое-что увидеть. - person F. Privé; 04.12.2017
comment
Я пробовал с вашим примером: так что есть момент в самом начале после запуска функции, когда у меня работают 3 ядра (в данном случае я установил 3 ядра), а затем через несколько секунд у меня есть только один ядро работает ... Таким образом, в этом примере распараллеливание все еще не работает. Я пробовал функции var.test () и t.test () для сравнения ваших матриц. - person Yoann Pageaud; 05.12.2017
comment
Я начинаю думать, что проблема может исходить из размеров моих матриц, которые огромны (миллионы строк). Может это усложняет настройку распараллеливания? Честно говоря, понятия не имею ... - person Yoann Pageaud; 05.12.2017
comment
вот функции, которые я пробовал, так что вы можете попробовать их, чтобы увидеть, что он дает: p.valals.m ‹-foreach (i = seq (dim (matrixA) [1]))% dopar% + t.test (matrixA [i,], matrixB [i,]) $ p.value p.vals.m ‹-foreach (i = seq (dim (matrixA) [1]))% dopar% + var.test (matrixA [i,] , matrixB [i,]) $ p.value - person Yoann Pageaud; 05.12.2017
comment
Я пытался сказать вам, что в распараллеливании нет ничего плохого. Проблема в том, как вы распараллеливаете. Ядра заняты чем-то другим, кроме вычислений, поэтому вы думаете, что они ничего не делают. Это может вам помочь. - person F. Privé; 05.12.2017
comment
Нет, я не думаю, что ядра жужжат. Обычно, когда я обычно распараллеливаю функцию на 5 ядрах, например: все 4 ядра работают на 100%. Здесь, когда я делаю то же самое, но для t.test () или var.test () у меня только ядро ​​работает на 100%, остальные 3 - на 0% использования. у него явно другой профиль, чем обычно, когда я использую doParallel. - person Yoann Pageaud; 05.12.2017

К сожалению, я не нашел решения моей проблемы с doParallel, но понял, что мне вообще не нужно его использовать.

В пакете R "genefilter" я нашел альтернативное решение, используя функцию rowttests (), которая действительно быстро выполняет t-тесты для больших матриц. Единственное замечание, которое я имею против этой функции, заключается в том, что она предполагает, что при вычислении p-значений дисперсии равны (и вы не можете это изменить). К счастью, я в этом случае.

Поэтому мне просто пришлось cbind () мои 2 матрицы, указать принадлежащие группы как факторы для столбцов. И это все !

bind_matrix<-cbind(matrixA,matrixB)
fact<-factor(c("A","A","A","A","A","B","B","B","B","B"))
p.vals<-rowttests(bind_matrix,fact)$p.values

Это занимает несколько секунд, и я попробовал это для матрицы из 10 миллионов строк.

Решение все тот же тест Фишера, есть функция rowFtests ().

Так что теперь я мог бы попросить эффективное решение для тестов Вилкоксона. Если кто-то знает функцию, которая работает аналогично этим, прокомментируйте, пожалуйста.

person Yoann Pageaud    schedule 06.12.2017