ทำไม runif ไม่สร้างผลลัพธ์เดียวกันทุกครั้ง


11

ทำไมเครื่องกำเนิดตัวเลขแบบสุ่มrunif()ใน R ไม่สร้างผลลัพธ์เหมือนกันทุกครั้ง?

ตัวอย่างเช่น:

X <- runif(100)
X

กำลังสร้างเอาต์พุตที่แตกต่างกันทุกครั้ง

เหตุผลในการสร้างผลลัพธ์ที่แตกต่างกันทุกครั้งคืออะไร?

มันทำหน้าที่อะไรในพื้นหลังที่จะทำเช่นนี้?


3
วิธีคิดอย่างหนึ่งคือถามตัวเองว่า: "คุณต้องการให้ตัวสร้างตัวเลขสุ่มของคุณสร้างหมายเลขเดียวกันทุกครั้งหรือไม่"
shadowtalker

2
@ssdecontrol: ดูDilbert
Henry

2
หรือxkcd
Henry

คำตอบ:


18

ในใจนี่ไม่ใช่แค่คำถาม R จริงๆ มันเกี่ยวข้องกับการสร้างตัวเลขสุ่มโดยทั่วไป

ตัวเลข "สุ่ม" มีความสำคัญมากในหลาย ๆ ส่วนของสถิติ เราต้องการค่าสุ่มที่เราสร้างขึ้นเพื่อให้มีคุณสมบัติบางอย่างและ (โดยปกติ) ความพยายามจำนวนมากไปสู่การสร้างเครื่องกำเนิดตัวเลขสุ่มและตรวจสอบคุณสมบัติของพวกเขา

แนวคิดคือเราต้องการได้รับลำดับของค่าที่เป็นตัวแทนที่ดีสำหรับตัวเลขสุ่มจริง workhorse ปกติของการสร้างตัวเลขสุ่มคือการแจกแจงแบบเดียวกัน (จากที่เราสร้างคนอื่น ๆ เช่นตัวเลขสุ่มแบบเกาส์เซียน)

ดังนั้น (โดยทั่วไป) อัลกอริธึมเชิงตัวเลขถูกใช้เพื่อสร้างลำดับของจำนวนเต็มแต่ละอันในแง่ของฟังก์ชั่นบางอย่างของหน้าที่ก่อนหน้านี้ จำนวนเต็มเหล่านี้จะถูกปรับสัดส่วนให้อยู่ระหว่าง 0 ถึง 1 (โดยปกติคือ )[0,1)

ตัวอย่างเช่นหลายคนทำงานในหน้าที่ก่อนหน้านี้:

x1=f(x0)z1=x1/mx2=f(x1)z2=x2/mx3=f(x2)z3=x3/m

... โดยที่เป็นจำนวนเต็มจะถูกปรับขนาดให้อยู่ในช่วงหน่วยและเป็นบางฟังก์ชันที่ซับซ้อน แต่มักจะเป็นฟังก์ชันที่รวดเร็วซึ่งทำงานบนบิตในอาร์กิวเมนต์เพื่อสร้างบิตใหม่ ที่ (หวังว่า) ดูเหมือนจะไม่เกี่ยวข้องกับค่าก่อนหน้าใด ๆ (ถ้าเราดูพวกเขาในรูปแบบของวิธีการทั้งหมดแม้จะค่อนข้างระมัดระวัง - แม้ว่าพวกเขาจะมีความเกี่ยวข้องจริงๆเพราะนั่นเป็นวิธีที่พวกเขาทำ) สิ่งเหล่านี้จะต้องถูกสร้างขึ้นอย่างระมัดระวังเพื่อให้แน่ใจว่าลำดับนั้นมีวัฏจักรที่ยาวนานมากและค่าของมันนั้นเหมือนกันจริง ๆ และไม่ได้ขึ้นอยู่กับการเรียงลำดับในทางใด ๆ ที่เราอาจสนใจ (รวมถึงโฮสต์ของข้อกำหนดอื่น ๆ สิ่งสำคัญ).z fxzf

พวกเขาต้องการจำนวนเต็มเริ่มต้น ("เมล็ด") ( ) ซึ่งคุณจัดหา (อัลกอริทึมบางอย่างอาจต้องการมากกว่าหนึ่งเมล็ด) หากคุณใช้เมล็ดพันธุ์เดิมอีกครั้งคุณจะได้รับลำดับที่เหมือนกัน (ซึ่งเป็นประโยชน์สำหรับความสามารถในการทำซ้ำผลลัพธ์) แต่ในบางครั้งคุณแค่ต้องการตัวเลขสุ่มและคุณไม่สนใจว่าเมล็ดพันธุ์อะไรตราบใดที่จุดเริ่มต้นแตกต่างจากล็อตก่อนหน้านี้ที่คุณใช้x0

ดังนั้นหากคุณไม่ได้จัดหาเมล็ดพันธุ์แพคเกจมากมายสามารถสร้างให้คุณได้ แพคเกจบางอย่างดูที่ตัวเลขสองสามตัวสุดท้ายของนาฬิกาดิจิตอลภายใน บางคน (รวม R) เก็บค่าสุดท้าย (จำนวนเต็มข้างต้นโดยทั่วไปคำว่า "รัฐ" จะใช้เพื่อครอบคลุมกรณีที่มีมากกว่าหนึ่งหมายเลขที่เกี่ยวข้อง) ที่สร้างขึ้นโดยเครื่องกำเนิดตัวเลขสุ่มเพื่อใช้เป็นเมล็ดพันธุ์ต่อไป หากคุณไม่ได้จัดหาx3

ดู?runifใน R และคุณจะทราบว่ามันอธิบายเกี่ยวกับการมีอยู่ของเมล็ดพันธุ์แบบสุ่มพร้อมลิงก์ไปยังความช่วยเหลือ?.Random.seedซึ่งอธิบายจำนวนตัวกำเนิดจำนวนสุ่มที่มีใน R (คุณสามารถจัดหาเองได้) หน้าความช่วยเหลือเดียวกันอธิบายว่าหากคุณไม่ได้ใช้การสร้างตัวเลขสุ่มมาก่อนหรือตั้งค่าเมล็ดเริ่มต้นด้วยเมล็ดจะถูกนำมาจากนาฬิกาและหลังจากนั้นค่าก่อนหน้านี้จะถูกเก็บไว้ (เพื่อให้หมายเลขสุ่มถัดไปคุณจะได้รับ สิ่งเดียวกันกับที่คุณจะได้รับหากคุณสร้างมูลค่าเพิ่มได้อีกครั้งในครั้งสุดท้ายมันจะจดจำ "ที่คุณกำลังทำอยู่"

ฟังก์ชั่นrunifใน R (เหมือนกับการสร้างหมายเลขสุ่มอื่น ๆ ในแพ็คเกจอื่นซึ่งมักจะทำสิ่งที่คล้ายกัน) รู้เกี่ยวกับสถานที่ที่เก็บหมายเลขสุ่ม มันทำให้การปรับปรุงค่านั้นเป็นไป ดังนั้นจึงสามารถทำงานได้โดยไม่ต้องผ่านเมล็ดอย่างชัดเจน แต่ก็ยังใช้งานได้ หากคุณไม่ได้ให้มันก็แค่ใช้คนที่มันบันทึกไว้ล่าสุด

สำหรับสาเหตุที่มันให้เอาต์พุตที่แตกต่างกันในแต่ละครั้ง (ถ้าคุณไม่บอกให้เรียงลำดับเดียวกัน): ทำเช่นนี้เพราะค่าเดียวกันทุกครั้งมักจะมีผลตอบโต้มาก - มันจะไม่มีคุณสมบัติที่ซ้ำกัน การสุ่มตัวอย่างแบบสุ่มจะทำให้ไม่มีประโยชน์มากสำหรับสิ่งที่เราใช้ในการสุ่มตัวเลข


14

คุณต้องตั้งค่าเมล็ดสุ่มเพื่อให้ได้ผลลัพธ์เดียวกันทุกครั้ง ใช้? set.seedทำเช่นนั้น พิจารณา:

> runif(1)
[1] 0.6467259
> runif(1)
[1] 0.2101857
> set.seed(1)
> runif(1)
[1] 0.2655087
> set.seed(1)
> runif(1)
[1] 0.2655087

คุณอาจจะสนใจในการอ่านนี้: เหตุผลในการใช้ฟังก์ชั่น set.seed


3
แม้ว่าสิ่งนี้จะอธิบายกลไกของการทำซ้ำชุดผลลัพธ์ แต่ดูเหมือนว่าจะไม่สามารถตอบคำถามได้เองซึ่งสงสัยว่าทำไมพฤติกรรมแบบนี้ไม่อัตโนมัติ
whuber

@whuber ฉันคิดว่าคำถามไม่ได้อยู่ที่หัวข้อในระยะไกลที่นี่ ฉันโหวตให้ปิดทันที & จะปิดทันทีถ้าฉันมีสิทธิ์นั้น ฉันโพสต์สิ่งนี้เพื่อให้ OP ไม่ว่างเปล่า
gung - Reinstate Monica

เรียกใช้ "set.seed (1)" ทุกครั้ง
Nip
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.