numpy.random.seed (0) ทำอะไรได้บ้าง


282

สิ่งที่ไม่np.random.seedทำในด้านล่างรหัสจาก Scikit เรียนรู้กวดวิชา? ฉันไม่คุ้นเคยกับสิ่งที่เครื่องกำเนิดรัฐแบบสุ่มของ NumPy ดังนั้นฉันขอขอบคุณคำอธิบายคำศัพท์ของคนธรรมดาในเรื่องนี้

np.random.seed(0)
indices = np.random.permutation(len(iris_X))

คำตอบ:


557

np.random.seed(0) ทำให้ตัวเลขสุ่มสามารถคาดเดาได้

>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])
>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])

ด้วยการตั้งค่าเมล็ดพันธุ์ (ทุกครั้ง) ที่เดียวกันชุดของตัวเลขจะปรากฏทุกครั้ง

หากไม่ได้รีเซ็ตเมล็ดแบบสุ่มตัวเลขที่แตกต่างกันจะปรากฏขึ้นพร้อมกับทุกการเรียกใช้

>>> numpy.random.rand(4)
array([ 0.42,  0.65,  0.44,  0.89])
>>> numpy.random.rand(4)
array([ 0.96,  0.38,  0.79,  0.53])

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

หากคุณต้องการตัวเลขสุ่มดูเหมือนอย่าตั้งค่าเมล็ด หากคุณมีรหัสที่ใช้ตัวเลขสุ่มที่คุณต้องการตรวจแก้จุดบกพร่องมันจะมีประโยชน์มากในการตั้งค่า seed ก่อนการเรียกใช้แต่ละครั้งเพื่อให้รหัสทำสิ่งเดียวกันทุกครั้งที่คุณเรียกใช้

numpy.random.seed()ที่จะได้รับการสุ่มตัวเลขมากที่สุดสำหรับการทำงานในแต่ละสาย สิ่งนี้จะทำให้ numpy ตั้งค่า seed เป็นตัวเลขสุ่มที่ได้รับจาก/dev/urandomWindows analog หรือถ้าไม่มีทั้งคู่ก็จะใช้นาฬิกา

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้เมล็ดพันธุ์ที่จะสร้างตัวเลขสุ่มหลอกให้ดูที่วิกิพีเดีย


86
คำตอบนี้ควรถูกเพิ่มเข้าไปในเอกสารของ numpy ขอบคุณ.
gorjanz

8
นอกจากนี้เมื่อคุณโทรหาnumpy.random.seed(None)มัน "จะพยายามอ่านข้อมูลจาก / dev / urandom (หรืออะนาล็อก Windows) หากมีหรือเป็นแบบอื่นจากนาฬิกา"
Jonathan

1
จุดที่ยอดเยี่ยม @ Jonathan numpy.random.seed(None)เกี่ยวกับ ฉันอัปเดตคำตอบด้วยข้อมูลนั้นและลิงก์ไปยังเอกสาร
John1024

@ curio1729 การปรับใช้อาจแตกต่างจากระบบปฏิบัติการหนึ่งไปยังระบบถัดไป แต่จำนวนมากพยายามที่จะทำให้คำสั่งรวมถึงseedเข้ากันได้
John1024

1
@ L3viathan จุดดี! เพื่อความสมบูรณ์และแม่นยำยิ่งขึ้นฉันควรจะกล่าวว่ามีการเพิ่มออฟเซ็ต อัปเดตคำตอบแล้ว สำหรับผู้ที่ต้องการรายละเอียดเพิ่มเติมฉันยังเพิ่มลิงก์ไปยังการอภิปรายของวิกิพีเดียเกี่ยวกับการสร้างตัวเลขสุ่มหลอก
John1024

38

หากคุณตั้งค่าnp.random.seed(a_fixed_number)ทุกครั้งที่คุณเรียกฟังก์ชั่นสุ่มอื่น ๆ ของ numpy ผลลัพธ์จะเหมือนกัน:

>>> import numpy as np
>>> np.random.seed(0) 
>>> perm = np.random.permutation(10) 
>>> print perm 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.rand(4) 
[0.5488135  0.71518937 0.60276338 0.54488318]
>>> np.random.seed(0) 
>>> print np.random.rand(4) 
[0.5488135  0.71518937 0.60276338 0.54488318]

อย่างไรก็ตามหากคุณเพียงแค่เรียกมันครั้งเดียวและใช้ฟังก์ชั่นแบบสุ่มที่หลากหลายผลลัพธ์จะยังคงแตกต่างกัน:

>>> import numpy as np
>>> np.random.seed(0) 
>>> perm = np.random.permutation(10)
>>> print perm 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> print np.random.permutation(10) 
[3 5 1 2 9 8 0 6 7 4]
>>> print np.random.permutation(10) 
[2 3 8 4 5 1 0 6 9 7]
>>> print np.random.rand(4) 
[0.64817187 0.36824154 0.95715516 0.14035078]
>>> print np.random.rand(4) 
[0.87008726 0.47360805 0.80091075 0.52047748]

3
มีฟังก์ชั่นที่สามารถเรียกได้หนึ่งครั้งว่ามีการตั้งค่าเมล็ดแบบสุ่มสำหรับการnp.randomโทรที่ตามมาทั้งหมดจนกว่าจะเปลี่ยนเมล็ดหรือไม่? ต้องโทรหาทุกครั้งที่ดูเหมือนว่าไม่จำเป็นและง่ายต่อการลืม
Lubed Slug

@LubedUpSlug คุณสามารถตกแต่งพวกมันได้ - อย่างน้อยสำหรับกรณีง่ายๆที่ฉันทดสอบว่ามันควรจะทำงานได้ def seed_first(fun, seed=0):| \tdef wrapped(*args, **kwargs):| \t\tnp.random.seed(seed)| \t\treturn fun(*args, **kwargs)| \treturn wrappedแล้วfor m in np.random.__all__:| \tif m != 'seed':| \t\tsetattr(np.random, m, seed_first(getattr(np.random, m)))อย่างไรก็ตามสิ่งนี้อาจนำไปสู่ข้อบกพร่องที่ลึกซึ้งมากและพฤติกรรมแปลก ๆ ในระยะยาว (แทนที่ \ t ด้วยสี่ช่องว่างและ | ด้วยตัวแบ่งบรรทัด ... )
Sebastian Höffner

1
@ SebastianHöffnerขอบคุณสำหรับความคิดเห็นของคุณ คำถามของฉันถูกเข้าใจผิดเล็กน้อยเพราะฉันสับสนกับประโยค "อย่างไรก็ตามถ้าคุณเพียงแค่เรียกมันครั้งเดียวและใช้ฟังก์ชั่นแบบสุ่มต่าง ๆ ผลลัพธ์จะยังคงแตกต่างกัน:" การโทร np.random.seed()ครั้งเดียวเมื่อเริ่มต้นโปรแกรมจะให้ผลลัพธ์เดียวกันเสมอ สำหรับเมล็ดเดียวกันเนื่องจากการเรียกnp.randomฟังก์ชันที่ตามมาจะเปลี่ยนเมล็ดสำหรับการโทรในภายหลัง การโทรnp.random.seed()ก่อนการเรียกnp.randomฟังก์ชั่นทุกครั้งอาจทำให้ได้ผลลัพธ์ที่ไม่พึงประสงค์
Lubed Slug

17

ตามที่ระบุไว้ numpy.random.seed (0) ตั้งค่าเมล็ดสุ่มเป็น 0 ดังนั้นตัวเลขสุ่มหลอกที่คุณได้รับจากการสุ่มจะเริ่มจากจุดเดียวกัน นี่อาจเป็นผลดีสำหรับการดีบักในบางกรณี อย่างไรก็ตามหลังจากอ่านบางครั้งดูเหมือนว่าจะเป็นวิธีที่ผิดไปถ้าคุณมีหัวข้อเพราะมันไม่ปลอดภัยเธรด

จากความแตกต่างระหว่าง -numpy-random-and-random-in-python :

สำหรับ numpy.random.seed () ปัญหาหลักคือมันไม่ปลอดภัยสำหรับเธรด - นั่นคือมันไม่ปลอดภัยที่จะใช้ถ้าคุณมีหลายเธรดที่แตกต่างกันเพราะมันไม่รับประกันว่าจะทำงานถ้าสองเธรดที่แตกต่างกันกำลังดำเนินการ ฟังก์ชั่นในเวลาเดียวกัน หากคุณไม่ได้ใช้เธรดและหากคุณสามารถคาดหวังได้อย่างสมเหตุสมผลว่าคุณไม่จำเป็นต้องเขียนโปรแกรมด้วยวิธีนี้อีกในอนาคต numpy.random.seed () ควรใช้ได้เพื่อการทดสอบ หากมีเหตุผลใดที่สงสัยว่าคุณอาจต้องใช้เธรดในอนาคตมันปลอดภัยกว่าในระยะยาวที่จะทำตามที่แนะนำและเพื่อให้เป็นตัวอย่างของ numpy.random.Random เท่าที่ฉันสามารถบอกได้ random.random.seed () ปลอดภัยต่อการเป็นเกลียว (หรืออย่างน้อยฉันก็ไม่พบหลักฐานใด ๆ ที่ตรงกันข้าม)

ตัวอย่างของวิธีการเกี่ยวกับเรื่องนี้:

from numpy.random import RandomState
prng = RandomState()
print prng.permutation(10)
prng = RandomState()
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)

อาจให้:

[3 0 4 6 8 2 1 9 7 5]

[1 6 9 0 2 7 8 3 5 4]

[8 1 5 0 7 2 9 4 3 6]

[8 1 5 0 7 2 9 4 3 6]

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


12

ฉันใช้สิ่งนี้บ่อยครั้งในเครือข่ายประสาท เป็นที่ทราบกันดีว่าเมื่อเราเริ่มฝึกโครงข่ายประสาทเทียมเราจะเริ่มต้นน้ำหนักแบบสุ่ม แบบจำลองนี้ได้รับการฝึกอบรมเกี่ยวกับน้ำหนักเหล่านี้ในชุดข้อมูลเฉพาะ หลังจากจำนวนยุคคุณจะได้รับชุดของน้ำหนักที่ผ่านการฝึกอบรม

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

จะเกิดอะไรขึ้นถ้าทุกครั้งที่คุณเริ่มฝึกตั้งแต่เริ่มต้นโมเดลจะถูกกำหนดค่าเริ่มต้นเป็นชุดน้ำหนักเริ่มต้นแบบสุ่มชุดเดียวกัน ในกรณีนี้แบบจำลองของคุณอาจทำซ้ำได้ สิ่งนี้สามารถทำได้โดย numpy.random.seed (0) โดยการกล่าวถึง seed () ให้กับหมายเลขที่เจาะจงคุณจะได้รับการสุ่มไปยังหมายเลขสุ่มชุดเดียวกันเสมอ


3

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

ดังนั้นมันจึงไม่ใช่การสุ่มอย่างแน่นอนเพราะอัลกอริทึมแยกตัวเลขออกมา แต่มันดูเหมือนว่าเป็นกลุ่มที่สร้างขึ้นแบบสุ่ม


0

การสุ่มเมล็ดระบุจุดเริ่มต้นเมื่อคอมพิวเตอร์สร้างลำดับหมายเลขสุ่ม

ตัวอย่างเช่นสมมติว่าคุณต้องการสร้างตัวเลขสุ่มใน Excel (หมายเหตุ: Excel ตั้งค่าขีด จำกัด 9999 สำหรับเมล็ดพันธุ์) หากคุณป้อนตัวเลขลงในกล่องสุ่มเมล็ดในระหว่างกระบวนการคุณจะสามารถใช้หมายเลขสุ่มชุดเดียวกันอีกครั้ง หากคุณพิมพ์“ 77” ลงในกล่องและพิมพ์“ 77” ในครั้งต่อไปที่คุณเรียกใช้ตัวสร้างตัวเลขแบบสุ่ม Excel จะแสดงตัวเลขสุ่มชุดเดียวกัน หากคุณพิมพ์“ 99” คุณจะได้รับชุดตัวเลขที่แตกต่างอย่างสิ้นเชิง แต่ถ้าคุณย้อนกลับไปเป็นเมล็ด 77 คุณจะได้รับหมายเลขสุ่มชุดเดียวกับที่คุณเริ่มต้นด้วย

ตัวอย่างเช่น“ รับหมายเลข x เพิ่ม 900 + x จากนั้นลบ 52” เพื่อให้กระบวนการเริ่มต้นคุณต้องระบุหมายเลขเริ่มต้น x (เมล็ด) ลองใช้หมายเลขเริ่มต้น 77:

เพิ่ม 900 + 77 = 977 ลบ 52 = 925 ทำตามขั้นตอนวิธีเดียวกันหมายเลข“ สุ่ม” ตัวที่สองจะเป็น:

900 + 925 = 1825 ลบ 52 = 1773 ตัวอย่างง่ายๆนี้ตามรูปแบบ แต่อัลกอริทึมที่อยู่เบื้องหลังการสร้างหมายเลขคอมพิวเตอร์มีความซับซ้อนมากขึ้น


0

ตัวเลขสุ่มทั้งหมดที่สร้างขึ้นหลังจากตั้งค่าเมล็ดโดยเฉพาะจะเหมือนกันในทุกแพลตฟอร์ม / ระบบ


0

มีคำอธิบายที่มีความสุขในเอกสาร Numpy คือ https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.RandomState.html มันหมายถึงMersenne Twister เครื่องกำเนิดไฟฟ้าจำนวนสุ่มหลอก รายละเอียดเพิ่มเติมเกี่ยวกับอัลกอริทึมที่นี่: https://en.wikipedia.org/wiki/Mersenne_Twister


0
numpy.random.seed(0)
numpy.random.randint(10, size=5)

สิ่งนี้สร้างผลลัพธ์ต่อไปนี้: array([5, 0, 3, 3, 7]) อีกครั้งถ้าเราเรียกใช้รหัสเดียวกันเราจะได้ผลลัพธ์เดียวกัน

ตอนนี้ถ้าเราเปลี่ยนค่าเมล็ด 0 เป็น 1 หรืออื่น ๆ :

numpy.random.seed(1)
numpy.random.randint(10, size=5)

สิ่งนี้สร้างเอาต์พุตต่อไปนี้: array([5 8 9 5 0])แต่ตอนนี้เอาต์พุตไม่เหมือนกันด้านบน


0

คำตอบทั้งหมดข้างต้นแสดงการใช้งานของnp.random.seed()ในรหัส ฉันจะพยายามอย่างดีที่สุดเพื่ออธิบายสั้น ๆ ว่าทำไมมันเกิดขึ้นจริง คอมพิวเตอร์เป็นเครื่องจักรที่ออกแบบตามอัลกอริทึมที่กำหนดไว้ล่วงหน้า เอาต์พุตใด ๆ จากคอมพิวเตอร์คือผลลัพธ์ของอัลกอริทึมที่ใช้กับอินพุต ดังนั้นเมื่อเราขอคอมพิวเตอร์เพื่อสร้างตัวเลขสุ่มแน่ใจว่าพวกมันสุ่ม แต่คอมพิวเตอร์ไม่ได้มากับพวกมันแบบสุ่ม!

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

ตัวอย่างเช่นถ้าฉันเขียนnp.random.seed(10)ชุดตัวเลขเฉพาะที่ฉันได้รับจะยังคงเหมือนเดิมแม้ว่าฉันจะดำเนินการบรรทัดเดียวกันหลังจาก 10 ปีเว้นแต่ว่าการเปลี่ยนแปลงอัลกอริทึม

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