0Pricing
R Academy · درس

set.seed() وقابلية إعادة الإنتاج

اضمن إمكانية إعادة إنتاج توليد الأعداد العشوائية عبر عمليات التشغيل باستخدام set.seed()

set.seed() وقابلية إعادة الإنتاج درس مجاني في R Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في R Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة R Academy 4 دروس في المجموع.

لماذا تهم قابلية إعادة الإنتاج؟

إن توليد الأعداد العشوائية شبه عشوائي؛ فهو خوارزمية حتمية تبدأ بقيمة ابتدائية تُسمى البذرة. ويجعل ضبط البذرة عمليات المحاكاة قابلةً لإعادة الإنتاج، إذ ينتج الكود نفسه النتائج نفسها دائمًا، وهو أمر أساسي لتصحيح الأخطاء والنشر والتعليم.

# Without set.seed: different every run
runif(3)  # e.g., 0.21, 0.57, 0.89 (changes each run)
runif(3)  # different again!

# With set.seed: always identical
set.seed(42)
runif(3)  # always: 0.9148060 0.9370754 0.2861395

set.seed(42)  # reset seed
runif(3)  # exactly the same three numbers again

cat('set.seed() is your reproducibility guarantee')

آلية set.seed()

تعمل set.seed(n) على تهيئة حالة مولّد الأعداد العشوائية (RNG). ويصلح أي عدد صحيح موجب. وتحدد البذرة التسلسل الكامل المستقبلي للأعداد العشوائية إلى أن تُعاد تهيئة البذرة. استخدم عددًا ثابتًا لضمان قابلية إعادة الإنتاج.

# Different seeds give different sequences
set.seed(1)
seq1 <- rnorm(5)

set.seed(99)
seq2 <- rnorm(5)

print(seq1)
print(seq2)
identical(seq1, seq2)  # FALSE

# Same seed always gives same sequence
set.seed(1)
seq1_again <- rnorm(5)
identical(seq1, seq1_again)  # TRUE

# Common seed choices
set.seed(123)   # popular convention
set.seed(2024)  # use year for temporal clarity

RNGkind(): خوارزمية RNG

تعرض RNGkind() خوارزمية RNG أو تضبطها. والإعداد الافتراضي في R هو Mersenne-Twister، مع استخدام طريقة Inversion للتوزيع الطبيعي. وتؤثر الخوارزمية في التسلسل، لذا وثّق كلًا من البذرة وRNGkind لضمان قابلية إعادة الإنتاج الكاملة.

# Check current RNG settings
RNGkind()
# [1] 'Mersenne-Twister' 'Inversion' 'Rejection'
# [1] kind, normal.kind, sample.kind

# Set explicitly for maximum reproducibility
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
set.seed(42)
runif(3)

# Alternative RNG algorithms (rarely needed)
# RNGkind('L'Ecuyer-CMRG') # for parallel RNG
# RNGkind('Super-Duper')   # older algorithm

cat('Default Mersenne-Twister has period 2^19937 - 1')

فحص .Random.seed

يمثل .Random.seed متجهًا صحيحًا عامًا يخزّن حالة RNG الكاملة. ويُحدَّث تلقائيًا بعد كل سحب عشوائي. ويمكنك حفظه واستعادته لإعادة تشغيل تسلسل بدءًا من أي نقطة.

set.seed(42)
# .Random.seed is created in .GlobalEnv after first use
length(.Random.seed)  # 626 integers for Mersenne-Twister
.Random.seed[1]       # encodes RNG type

# Generate one number (state advances)
x1 <- runif(1)
state_after <- .Random.seed

# Generate another
x2 <- runif(1)

# Restore state to after x1
.Random.seed <<- state_after
x2_replay <- runif(1)

identical(x2, x2_replay)  # TRUE - we replayed the state
cat('x2:', x2, 'x2_replay:', x2_replay)

حفظ حالة RNG واستعادتها

احفظ حالة RNG قبل كتلة من الكود، ثم استعدها لاحقًا لإعادة تشغيل تلك الكتلة نفسها بدقة. وتوفر هذه الطريقة مرونة أكبر من set.seed() عندما تحتاج إلى استئناف التسلسل من منتصفه.

set.seed(100)
# Generate some random numbers first
runif(10)

# Save current state
saved_state <- .Random.seed

# Generate block of interest
block1 <- rnorm(5)
print(block1)

# ... later, restore and replay
.Random.seed <<- saved_state
block1_replay <- rnorm(5)

identical(block1, block1_replay)  # TRUE!
cat('RNG state saved and restored successfully')

RNG المتوازي باستخدام L'Ecuyer-CMRG

عند استخدام الحوسبة المتوازية، يحتاج كل process إلى تدفق مستقل من مولّد الأرقام العشوائية (RNG). يوفّر المولّد L'Ecuyer-CMRG تدفقات طويلة غير متداخلة للعاملين المتوازيين، مما يضمن استقلال النتائج عبر الأنوية.

# Set up L'Ecuyer-CMRG for parallel use
RNGkind('L\'Ecuyer-CMRG')
set.seed(42)

# Each parallel worker gets its own stream
# (parallel package handles this automatically)
# library(parallel)
# cl <- makeCluster(4)
# clusterSetRNGStream(cl, iseed = 42)

# Generate numbers with this generator
samples <- rnorm(5)
print(samples)

# Reset to default Mersenne-Twister
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
cat('L\'Ecuyer-CMRG: safe for parallel simulation')

البذرة في استدعاءات الدوال

لا يؤثر تعيين بذرة داخل دالة في حالة RNG الخاصة بالمستدعي بعد عودة الدالة، لأن استدعاء البذرة داخل الدالة يعدّل .Random.seed العام. لذلك، احرص على إدارة البذور بوضوح في الدوال القابلة لإعادة الاستخدام.

# Function that optionally accepts a seed
simulate_data <- function(n, seed = NULL) {
  if (!is.null(seed)) set.seed(seed)
  list(
    x = rnorm(n),
    y = rnorm(n)
  )
}

# Reproducible call
result1 <- simulate_data(5, seed = 42)
result2 <- simulate_data(5, seed = 42)
identical(result1$x, result2$x)  # TRUE

# Without seed: different each time
result3 <- simulate_data(5)
result4 <- simulate_data(5)
identical(result3$x, result4$x)  # FALSE

أخذ عينات قابل لإعادة الإنتاج

تؤثر الوسيطة sample.kind في RNGkind() على sample() تحديدًا. منذ R 3.6.0، تغيّرت القيمة الافتراضية إلى 'Rejection' لتحسين الانتظام؛ استخدم ذلك في سير العمل القابل لإعادة الإنتاج.

# R 3.6+ default sample kind
RNGkind(sample.kind = 'Rejection')  # default
set.seed(42)
sample(1:10, 5)
# [1] 1 5 10 8 2  (with Rejection)

# Old behavior (R < 3.6) for legacy code
RNGkind(sample.kind = 'Rounding')
set.seed(42)
sample(1:10, 5)
# Different result!

# Best practice: reset to modern defaults
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
set.seed(42)
sample(1:10, 5)

توثيق العشوائية

من الممارسات الجيدة في البحث القابل لإعادة الإنتاج توثيق إصدار R وقيمة البذرة وRNGkind. استخدم sessionInfo() لالتقاط معلومات البيئة كاملة. وسجّل البذور في تعليقات البرنامج النصي أو في ملف إعدادات.

# Reproducibility header for analysis scripts:
# R version: R.version$version.string
# Seed: 42
# RNGkind: Mersenne-Twister / Inversion / Rejection

# Capture R version
R.version$version.string

# Capture full session info
# sessionInfo()  # shows all packages and versions

# In RMarkdown, set seed in setup chunk:
# ```{r setup}
# knitr::opts_chunk$set(echo = TRUE)
# set.seed(42)
# ```

# This ensures all chunks share the same RNG state
set.seed(42)
cat('R version:', R.version$version.string, '\n')
cat('Seed: 42, RNGkind: Mersenne-Twister')

البذور في دراسات مونت كارلو

في دراسات المحاكاة الكبيرة، استخدم بذرة رئيسية واحدة لتوليد بذور لكل تكرار. يتيح ذلك إعادة إنتاج كل تكرار على حدة، مع الحفاظ على حتمية التصميم الكلي.

# Generate per-replicate seeds from a master seed
set.seed(2024)
n_replicates <- 5
replicate_seeds <- sample.int(1e6, n_replicates)
print(replicate_seeds)

# Each replicate uses its own seed
run_replicate <- function(rep_id) {
  set.seed(replicate_seeds[rep_id])
  mean(rnorm(1000))  # estimate with this seed
}

results <- sapply(seq_len(n_replicates), run_replicate)
print(round(results, 4))

# Any single replicate can be re-run independently:
set.seed(replicate_seeds[3])
mean(rnorm(1000))  # exactly matches results[3]

اختبار العشوائية باستخدام withr

توفر الحزمة withr الدالة with_seed(seed, expr) التي تعيّن بذرة مؤقتًا، وتقيّم التعبير، ثم تستعيد حالة RNG الأصلية؛ ولذلك فهي مثالية للاختبارات من دون تلويث الحالة العامة.

# withr::with_seed - restore RNG state automatically
# library(withr)
# result <- with_seed(42, rnorm(5))

# Simulation without withr (manual state save)
old_seed <- if (exists('.Random.seed')) .Random.seed
old_kind <- RNGkind()

set.seed(42)
result <- rnorm(5)

# Restore
if (!is.null(old_seed)) .Random.seed <<- old_seed
cat('Result:', result, '\n')
cat('Caller\'s RNG state preserved')

# set.seed in tests ensures deterministic assertions:
set.seed(1)
stopifnot(round(rnorm(1), 6) == round(-0.6264538, 6))

تحقق سريع

اختبر مدى فهمك لقابلية إعادة إنتاج RNG في R.

مراجعة: البذرة وقابلية إعادة الإنتاج

أهم النقاط: تجعل set.seed(n) الشيفرة العشوائية قابلة لإعادة الإنتاج. تعرض RNGkind() الخوارزمية أو تعيّنها؛ لذا وثّق كلًا من البذرة والنوع. يخزّن .Random.seed حالة RNG الكاملة، ويمكن حفظها واستعادتها. استخدم L'Ecuyer-CMRG في الحوسبة المتوازية. وفي الدوال، اقبل وسيطة seed. استخدم بذورًا لكل تكرار، مولّدة من بذرة رئيسية، في المحاكاة الكبيرة.

# Reproducibility checklist:
# 1. Set seed at script top
set.seed(42)

# 2. Document RNGkind
RNGkind()  # Mersenne-Twister / Inversion / Rejection

# 3. Save RNG state if needed
saved <- .Random.seed

# 4. For functions, accept seed argument
my_sim <- function(n, seed = NULL) {
  if (!is.null(seed)) set.seed(seed)
  rnorm(n)
}

# 5. For parallel: use L'Ecuyer-CMRG
# RNGkind('L\'Ecuyer-CMRG'); set.seed(42)

cat('Reproducibility = trust in your results')

الأسئلة الشائعة

هل درس «set.seed() وقابلية إعادة الإنتاج» مجاني؟

نعم — نص درس «set.seed() وقابلية إعادة الإنتاج» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة R Academy، انتقل إلى CoddyKit PRO. تتضمن دورة R Academy 4 دروس في المجموع.

ماذا ستتعلم في «set.seed() وقابلية إعادة الإنتاج»؟

اضمن إمكانية إعادة إنتاج توليد الأعداد العشوائية عبر عمليات التشغيل باستخدام set.seed() تتمرن على R Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ R Academy؟

لا تُشترط خبرة سابقة. R Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «set.seed() وقابلية إعادة الإنتاج»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس R Academy هذا؟

نعم. كل درس في R Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. set.seed() وقابلية إعادة الإنتاج
  2. توليد التوزيعات العشوائية
  3. أساسيات محاكاة مونت كارلو
  4. إعادة أخذ العينات بطريقة Bootstrap في R
← العودة إلى R Academy