Numpy.random.seed (0) làm gì?


281

Làm gì np.random.seedtrong đoạn mã dưới đây từ hướng dẫn Scikit-Learn? Tôi không quen thuộc lắm với công cụ tạo trạng thái ngẫu nhiên của NumPy, vì vậy tôi thực sự đánh giá cao lời giải thích của một giáo dân về vấn đề này.

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

Câu trả lời:


552

np.random.seed(0) làm cho các số ngẫu nhiên có thể dự đoán được

>>> 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])

Với thiết lập lại hạt giống (mọi lúc), cùng một bộ số sẽ xuất hiện mỗi lần.

Nếu hạt giống ngẫu nhiên không được đặt lại, các số khác nhau sẽ xuất hiện với mỗi lần gọi:

>>> 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])

(pseudo-) số ngẫu nhiên hoạt động bằng cách bắt đầu bằng một số (hạt giống), nhân nó với một số lớn, thêm một phần bù, sau đó lấy modulo của tổng đó. Số kết quả sau đó được sử dụng làm hạt giống để tạo ra số "ngẫu nhiên" tiếp theo. Khi bạn đặt hạt giống (mọi lúc), nó sẽ làm điều tương tự mọi lúc, cho bạn cùng một số.

Nếu bạn muốn số dường như ngẫu nhiên, không đặt hạt giống. Tuy nhiên, nếu bạn có mã sử dụng các số ngẫu nhiên mà bạn muốn gỡ lỗi, tuy nhiên, có thể rất hữu ích để đặt hạt giống trước mỗi lần chạy để mã thực hiện điều tương tự mỗi khi bạn chạy nó.

Để có được các số ngẫu nhiên nhất cho mỗi lần chạy, hãy gọi numpy.random.seed(). Điều này sẽ khiến numpy đặt hạt giống thành một số ngẫu nhiên thu được từ /dev/urandomhoặc tương tự Windows của nó hoặc, nếu không có sẵn số đó, nó sẽ sử dụng đồng hồ.

Để biết thêm thông tin về việc sử dụng hạt giống để tạo số giả ngẫu nhiên, xem wikipedia .


86
Câu trả lời này nên được thêm vào tài liệu của numpy. Cảm ơn bạn.
gorjanz

8
Ngoài ra, khi bạn gọi numpy.random.seed(None), nó "sẽ cố đọc dữ liệu từ / dev / urandom (hoặc tương tự Windows) nếu có hoặc gieo từ đồng hồ nếu không".
Jonathan

1
@Jonathan Điểm tuyệt vời về numpy.random.seed(None). Tôi đã cập nhật câu trả lời với thông tin đó và một liên kết đến các tài liệu.
John1024

@ curio1729 Việc triển khai có thể thay đổi từ một hệ điều hành sang hệ điều hành tiếp theo nhưng numpy cố gắng thực hiện các lệnh của nó, bao gồm seed, tương thích.
John1024

1
@ L3viathan Điểm tốt! Để đầy đủ và chính xác hơn, tôi nên đề cập rằng một phần bù được thêm vào. Trả lời cập nhật. Đối với những người muốn biết thêm chi tiết, tôi cũng đã thêm một liên kết đến cuộc thảo luận của wikipedia về các trình tạo số giả ngẫu nhiên.
John1024

38

Nếu bạn đặt np.random.seed(a_fixed_number)mỗi lần bạn gọi hàm ngẫu nhiên khác của numpy, kết quả sẽ giống nhau:

>>> 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]

Tuy nhiên, nếu bạn chỉ gọi nó một lần và sử dụng các hàm ngẫu nhiên khác nhau, kết quả sẽ vẫn khác:

>>> 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
Có một chức năng có thể được gọi một lần sao cho hạt giống ngẫu nhiên được đặt cho tất cả các np.randomcuộc gọi tiếp theo cho đến khi hạt giống được thay đổi? Phải gọi nó mỗi lần dường như không cần thiết dài dòng và dễ quên.
Sled Up Slug

@LubedUpSlug bạn có thể trang trí chúng - ít nhất là đối với một số trường hợp đơn giản tôi đã thử nghiệm nó sẽ hoạt động. def seed_first(fun, seed=0):| \tdef wrapped(*args, **kwargs):| \t\tnp.random.seed(seed)| \t\treturn fun(*args, **kwargs)| \treturn wrappedvà sau đó for m in np.random.__all__:| \tif m != 'seed':| \t\tsetattr(np.random, m, seed_first(getattr(np.random, m)))Tuy nhiên, điều này có thể dẫn đến các lỗi rất tinh vi và hành vi kỳ lạ trong thời gian dài. (Thay thế \ t bằng bốn khoảng trắng và | bằng dấu ngắt dòng ...)
Sebastian Höffner

1
@ SebastianHöffner cảm ơn bạn đã bình luận của bạn. Câu hỏi của tôi hơi sai lầm vì tôi bị nhầm lẫn bởi câu "Tuy nhiên, nếu bạn chỉ gọi một lần và sử dụng nhiều chức năng ngẫu nhiên khác nhau, kết quả sẽ vẫn khác:" Gọi np.random.seed()một lần khi bắt đầu chương trình sẽ luôn tạo ra kết quả tương tự cho cùng một hạt giống vì các lệnh gọi tiếp theo đến các np.randomhàm sẽ thay đổi xác định hạt giống cho các lệnh gọi tiếp theo. Gọi np.random.seed()trước mỗi cuộc gọi đến các np.randomchức năng có thể sẽ tạo ra kết quả không mong muốn.
Slug Up Slug

17

Như đã lưu ý, numpy.random.seed (0) đặt hạt giống ngẫu nhiên thành 0, vì vậy các số ngẫu nhiên giả bạn nhận được từ ngẫu nhiên sẽ bắt đầu từ cùng một điểm. Điều này có thể tốt cho việc gỡ lỗi trong một số trường hợp. TUY NHIÊN, sau khi đọc một số, đây có vẻ là cách sai để đi vào nó, nếu bạn có chủ đề vì nó không phải là chủ đề an toàn.

từ sự khác biệt giữa-numpy-ngẫu nhiên và ngẫu nhiên-ngẫu nhiên-trong-trăn :

Đối với numpy.random.seed (), khó khăn chính là nó không an toàn cho luồng - nghĩa là không an toàn khi sử dụng nếu bạn có nhiều luồng thực thi khác nhau, vì nó không được bảo đảm để hoạt động nếu hai luồng khác nhau đang thực thi các chức năng cùng một lúc. Nếu bạn không sử dụng các chủ đề và nếu bạn có thể mong đợi một cách hợp lý rằng bạn sẽ không cần phải viết lại chương trình của mình theo cách này trong tương lai, thì numpy.random.seed () sẽ ổn cho mục đích thử nghiệm. Nếu có bất kỳ lý do nào để nghi ngờ rằng bạn có thể cần các chủ đề trong tương lai, thì về lâu dài sẽ an toàn hơn khi làm theo đề xuất và để tạo một phiên bản cục bộ của lớp numpy.random.Random. Theo như tôi có thể nói, Random.random.seed () là an toàn cho chuỗi (hoặc ít nhất, tôi không tìm thấy bất kỳ bằng chứng nào ngược lại).

ví dụ về cách đi về điều này:

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)

có thể cho:

[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]

Cuối cùng, lưu ý rằng có thể có trường hợp khởi tạo thành 0 (trái ngược với hạt giống không có tất cả các bit 0) có thể dẫn đến phân phối không đồng đều cho một số lần lặp đầu tiên vì cách xor hoạt động, nhưng điều này phụ thuộc vào thuật toán , và vượt ra ngoài những lo lắng hiện tại của tôi và phạm vi của câu hỏi này.


12

Tôi đã sử dụng điều này rất thường xuyên trong các mạng lưới thần kinh. Người ta biết rằng khi chúng ta bắt đầu đào tạo một mạng lưới thần kinh, chúng ta sẽ khởi tạo ngẫu nhiên các trọng số. Mô hình được đào tạo về các trọng số này trên một tập dữ liệu cụ thể. Sau số epoch bạn nhận được tập trọng lượng.

Bây giờ, giả sử bạn muốn một lần nữa luyện tập từ đầu hoặc bạn muốn truyền mô hình cho người khác để tái tạo kết quả của mình, các trọng số sẽ lại được khởi tạo thành một số ngẫu nhiên, hầu hết sẽ khác với các số trước đó. Các trọng số được đào tạo thu được sau cùng một số epoch (giữ cùng một dữ liệu và các tham số khác) như trước đó sẽ khác nhau. Vấn đề là mô hình của bạn không thể tái tạo được nữa, đó là mỗi khi bạn huấn luyện mô hình của mình từ đầu, nó cung cấp cho bạn các trọng số khác nhau. Điều này là do mô hình đang được khởi tạo bởi các số ngẫu nhiên khác nhau mỗi lần.

Điều gì sẽ xảy ra nếu mỗi khi bạn bắt đầu đào tạo từ đầu, mô hình được khởi tạo thành cùng một tập các trọng số khởi tạo ngẫu nhiên? Trong trường hợp này mô hình của bạn có thể trở thành tái sản xuất. Điều này đạt được bởi numpy.random.seed (0). Bằng cách đề cập đến hạt giống () cho một số cụ thể, bạn luôn luôn giữ một bộ số ngẫu nhiên.


3

Hãy tưởng tượng bạn đang chỉ cho ai đó cách mã hóa thứ gì đó bằng một loạt các số "ngẫu nhiên". Bằng cách sử dụng hạt giống numpy, họ có thể sử dụng cùng một số hạt giống và nhận được cùng một bộ số "ngẫu nhiên".

Vì vậy, nó không hoàn toàn ngẫu nhiên vì một thuật toán tạo ra các con số nhưng nó trông giống như một bó được tạo ngẫu nhiên.


0

Một hạt giống ngẫu nhiên chỉ định điểm bắt đầu khi một máy tính tạo ra một chuỗi số ngẫu nhiên.

Ví dụ: giả sử bạn muốn tạo một số ngẫu nhiên trong Excel (Lưu ý: Excel đặt giới hạn 9999 cho hạt giống). Nếu bạn nhập một số vào hộp Hạt giống ngẫu nhiên trong quá trình, bạn sẽ có thể sử dụng lại cùng một bộ số ngẫu nhiên. Nếu bạn đã gõ vào 77 77 vào hộp và gõ vào 77 77 vào lần tới khi bạn chạy trình tạo số ngẫu nhiên, Excel sẽ hiển thị cùng một bộ số ngẫu nhiên đó. Nếu bạn gõ vào 99 99, bạn sẽ nhận được một bộ số hoàn toàn khác. Nhưng nếu bạn quay trở lại hạt giống 77, thì bạn sẽ nhận được cùng một bộ số ngẫu nhiên mà bạn đã bắt đầu.

Ví dụ: Nhận một số x, thêm 900 + x, sau đó trừ 52. Để quá trình bắt đầu, bạn phải chỉ định một số bắt đầu, x (hạt giống). Hãy lấy số bắt đầu 77:

Thêm 900 + 77 = 977 Trừ 52 = 925 Theo cùng một thuật toán, số thứ tự ngẫu nhiên thứ hai sẽ là:

900 + 925 = 1825 Trừ 52 = 1773 Ví dụ đơn giản này theo một mẫu, nhưng các thuật toán đằng sau việc tạo số máy tính phức tạp hơn nhiều


0

Tất cả các số ngẫu nhiên được tạo sau khi đặt giá trị hạt giống cụ thể là giống nhau trên tất cả các nền tảng / hệ thống.



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

Điều này tạo ra đầu ra sau: array([5, 0, 3, 3, 7]) Một lần nữa, nếu chúng ta chạy cùng một mã, chúng ta sẽ nhận được kết quả tương tự.

Bây giờ nếu chúng ta thay đổi giá trị hạt giống 0 thành 1 hoặc khác:

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

Điều này tạo ra đầu ra sau: array([5 8 9 5 0])nhưng bây giờ đầu ra không giống như trên.


0

Tất cả các câu trả lời ở trên cho thấy việc thực hiện np.random.seed()trong mã. Tôi sẽ cố gắng hết sức để giải thích ngắn gọn tại sao nó thực sự xảy ra. Máy tính là máy được thiết kế dựa trên các thuật toán được xác định trước. Bất kỳ đầu ra nào từ máy tính là kết quả của thuật toán được thực hiện trên đầu vào. Vì vậy, khi chúng tôi yêu cầu một máy tính tạo ra các số ngẫu nhiên, chắc chắn chúng là ngẫu nhiên nhưng máy tính không chỉ xuất hiện ngẫu nhiên!

Vì vậy, khi chúng ta viết np.random.seed(any_number_here)thuật toán sẽ xuất ra một tập hợp các số cụ thể duy nhất cho đối số any_number_here. Nó gần giống như một tập hợp các số ngẫu nhiên cụ thể có thể thu được nếu chúng ta vượt qua đối số chính xác. Nhưng điều này sẽ đòi hỏi chúng ta phải biết về cách thức hoạt động của thuật toán khá tẻ nhạt.

Vì vậy, ví dụ nếu tôi viết np.random.seed(10)bộ số cụ thể mà tôi có được sẽ vẫn giữ nguyên ngay cả khi tôi thực hiện cùng một dòng sau 10 năm trừ khi thuật toán thay đổi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.