إذا كنت تؤمن بالقوالب النمطية ، فإن لغة R هي شيء متخصص للغاية في الإحصاء والتعلم الآلي. الصورة النمطية الثانية هي أن كود R الصافي ليس سريعًا جدًا: أولاً ، لأنه يتم تفسيره ، وثانيًا ، لأنه يتم تنفيذه بالتتابع. بالطبع ، القوالب النمطية لها نوع من الارتباط بالواقع ، وإلا فإنها لن تكون موجودة ، ولكن هذا هو السبب في أنها قوالب نمطية ، والتي تعطي صورة مبسطة للغاية للعالم حيث يتم فقد الكثير من التفاصيل. على وجه الخصوص ، أريد اليوم أن أشارك طريقة بسيطة بشكل مدهش لإضافة التوازي إلى R ومضاعفة تسريع تنفيذ الكود الحالي دون الحاجة إلى إجراء أي تغييرات كبيرة عليه. كل هذا يتم في دقيقتين فقط.
لنفترض أن لدينا مصفوفة أو جدول بيانات يحتوي على عدد من الصفوف والأعمدة ، ونريد إجراء نوع من نفس النوع من الحسابات لكل صف من الصفوف. على سبيل المثال ، احسب مجموع مربعات قيمه. من المنطقي نقل الحسابات إلى دالة واستدعائها لكل سطر من السطور.
البيانات الأولية:
a <- matrix(rnorm(500000, mean=0, sd=2), 100000, 50)
وظيفة:
sum.of.squares <- function(n) {
n_sq <- sapply(n, function(x) x^2)
sum(n_sq)
}
يمكنك ببساطة تكرار السطور وتطبيق هذه الوظيفة على كل سطر ، ولكن هذه ليست الطريقة الأكثر موصى بها لـ R. سيتم إجراء الحسابات لكل سطر بالتسلسل ، وسيتم تنفيذ جميع الحسابات على نفس النواة. هذا النوع من الكود ليس فعالًا جدًا حقًا. فقط في حالة حدوث ذلك ، دعنا نكتب هذا الخيار ونقيس وقت التنفيذ:
b <- vector()
for(i in 1:dim(a)[1]) {
b[i] <- sum.of.squares(a[i,])
}
نقيس وقت التنفيذ:
b <- vector()
start_time <- Sys.time()
for(i in 1:dim(a)[1]) {
b[i] <- sum.of.squares(a[i,])
}
timediff <- difftime(Sys.time(), start_time)
cat(" : ", timediff, units(timediff))
نحن نحصل:
: 4.474074 secs
سنستخدم هذا الوقت كنقطة انطلاق للمقارنة مع الطرق الأخرى.
. R apply(). , : 1, 2. , . – sapply(), . – . , apply() :
b <- apply(a, 1, function(x) sum.of.squares(x))
, . , , :
start_time <- Sys.time()
b <- apply(a, 1, function(x) sum.of.squares(x))
timediff <- difftime(Sys.time(),start_time)
cat(" : ", timediff, units(timediff))
:
: 4.484046 secs
, . : , .
, , R , . : apply(), , . , , . , apply(). apply() by(), eapply(), lapply(), Map(), .mapply(), mapply(), replicate(), sapply(), tapply(), vapply(). , future_apply:
install.packages("future.apply")
– . , :
library("future.apply")
plan(multiprocess)
. , . future::plan(). , , apply "future_". :
b <- future_apply(a, 1, function(x) sum.of.squares(x))
:
start_time <- Sys.time()
b <- future_apply(a, 1, function(x) sum.of.squares(x))
timediff <- difftime(Sys.time(),start_time)
cat(" : ", timediff, units(timediff))
:
: 1.283569 secs
Intel Core i7-8750H 12 . 12-, .
. , , , , , . , , future_sapply, . . – . , , , (a <- data.frame(a)), , 8 . .
حسنا هذا كل شيء. الطريقة بسيطة للغاية. بالنسبة لي ، عندما اكتشفت أمره ، كان مجرد هبة من السماء. هل صحيح أن R الحالية لا تدعم الحوسبة المتوازية؟ يعتمد على وجهة نظر هذه القضية ، على شدة بيانها. لكن بمعنى ما ، يمكننا أن نفترض أنه يدعم.