Python에서 numpy.random과 random.random의 차이점


100

Python에 큰 스크립트가 있습니다. 나는 다른 사람들의 코드에서 영감을 얻었 기 때문에 numpy.random일부 작업 (예 : 이항 분포에서 가져온 난수 배열 생성)을 위해 모듈을 사용하고 다른 곳에서는 모듈을 사용했습니다 random.random.

누군가가 둘의 주요 차이점을 말해 줄 수 있습니까? 두 가지 각각에 대한 문서 웹 페이지를 보면 numpy.random더 많은 방법이있는 것 같지만 난수 생성이 어떻게 다른지 확실하지 않습니다.

내가 묻는 이유는 디버깅 목적으로 메인 프로그램을 시드해야하기 때문입니다. 하지만 가져 오는 모든 모듈에서 동일한 난수 생성기를 사용하지 않으면 작동하지 않습니다. 맞습니까?

또한 다른 게시물에서 NOT using에 대한 토론을 읽었 numpy.random.seed()지만 이것이 왜 그렇게 나쁜 생각인지 이해하지 못했습니다. 누군가가 왜 그런지 설명해 주시면 정말 감사하겠습니다.

답변:


120

이미 많은 정확한 관찰을했습니다!

두 임의 생성기를 모두 시드하지 않으려면 장기적으로 하나 또는 다른 생성기를 선택하는 것이 더 간단 할 것입니다. 하지만 둘 다 사용해야한다면 서로 독립적으로 난수를 생성하기 때문에 둘 다 시드해야합니다.

의 경우 numpy.random.seed()가장 큰 어려움은 스레드로부터 안전하지 않다는 것입니다. 즉, 두 개의 다른 스레드가 동시에 함수를 실행하는 경우 작동이 보장되지 않기 때문에 실행 스레드여러 개 있는 경우 사용하는 것이 안전 하지 않습니다. 쓰레드를 사용하지 않고 앞으로 이런 식으로 프로그램을 다시 작성할 필요가 없다고 합리적으로 기대할 수 있다면 numpy.random.seed()괜찮을 것입니다. 나중에 스레드가 필요할 수 있다고 의심 할 이유가있는 경우 제안 된대로 수행 하고 numpy.random.Random클래스 의 로컬 인스턴스만드는 것이 장기적으로 훨씬 안전 합니다 . 내가 말할 수있는 한 random.random.seed()스레드로부터 안전합니다 (또는 적어도 반대의 증거를 찾지 못했습니다).

numpy.random라이브러리는 일반적으로 과학 연구에 사용되는 몇 가지 추가 확률 분포뿐만 아니라 임의의 데이터의 배열을 생성하는 편리한 기능 몇 가지가 포함되어 있습니다. random.random라이브러리는 좀 더 가볍고, 당신은 과학적 연구 또는 통계 작업을 다른 종류의 일을하지 않는 경우 잘해야한다.

그렇지 않으면 둘 다 Mersenne 트위스터 시퀀스 를 사용하여 난수를 생성하고 둘 다 완전히 결정적입니다. 즉, 몇 가지 핵심 정보를 알고 있다면 다음에 올 숫자 를 절대적으로 확실하게 예측할 있습니다. 이러한 이유로 numpy.random도 random.random도 심각한 암호화 용도에 적합하지 않습니다 . 그러나 시퀀스가 ​​매우 길기 때문에 데이터를 리버스 엔지니어링하려는 사람들에 대해 걱정하지 않는 경우 난수를 생성하는 데 둘 다 좋습니다. 이것은 또한 임의의 값을 시드해야하는 이유이기도합니다. 매번 같은 위치에서 시작하면 항상 같은 순서의 난수를 얻게됩니다!

참고로, 암호화 수준의 임의성 필요하다면 secrets 모듈을 사용 하거나 Python 3.6 이전의 Python 버전을 사용하는 경우 Crypto.Random 과 같은 것을 사용해야 합니다.


14
먼 관련 메모로서 메르 센 트위스터는 암호화 (및 일부 특이한 과학적) 목적에 충분한 임의의 엔트로피 시퀀스를 생성하지 않기 때문에 둘 다 사용할 필요가 없습니다. 드문 경우에, OS 특정 엔트로피 소스를 사용하여 단독 으로 사용할 수있는 것보다 훨씬 더 높은 품질의 비 결정적 무작위 시퀀스를 생성 할 수있는 Crypto.Random 이 자주 필요합니다 random.random. 하지만 일반적으로 필요하지 않습니다.
SingleNegationElimination

Hannnele 감사합니다. 귀하의 통찰력은 정말 매우 유용했습니다! 내 프로그램의 일부가 무작위를 사용하는 다른 프로그램을 호출하기 때문에 단일 난수 생성기 만 사용할 수 없다는 것이 밝혀졌습니다 (무작위가 이항 분포를 생성하지 않기 때문에 numpy가 필요합니다). 두 발전기를 시드해야합니다.
Laura

2
"지금 가지고있는 숫자를 안다면 다음에 올 숫자를 절대적으로 확실하게 예측할 수 있습니다." 이 진술에는 약간의 설명이 필요할 수 있습니다. 즉 , 생성기 의 내부 상태 를 알고 있으면 시퀀스를 재현 할 수 있습니다. 이는 생성기를 시드 할 때 수행하는 작업입니다. 생성기의 단일 숫자 출력이 주어지면 다음 숫자를 예측할 수 없습니다. 기간이 너무 커서 의사 난수 시퀀스의 위치를 ​​계산하여 다음 시퀀스를 예측하려면 긴 숫자 시퀀스가 ​​필요할 수 있습니다.
Kaushik Ghose 2014 년

12

에서 데이터 분석을위한 파이썬 모듈은 numpy.random파이썬를 보충 random효율적 확률 분포의 많은 종류의 샘플 값의 전체 어레이를 생성하는 기능.

대조적으로 Python의 내장 random모듈은 한 번에 하나의 값만 샘플링하지만 numpy.random매우 큰 샘플을 더 빠르게 생성 할 수 있습니다. IPython 매직 기능을 사용하면 %timeit어떤 모듈이 더 빨리 수행되는지 확인할 수 있습니다.

In [1]: from random import normalvariate
In [2]: N = 1000000

In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)]
1 loop, best of 3: 963 ms per loop

In [4]: %timeit np.random.normal(size=N)
10 loops, best of 3: 38.5 ms per loop

1
다른 방법에는 해당되지 않습니다. NumPy np.random.randint(2)와 비교하면 더 느 렸습니다 . NumPy : 1.25 us 및 Random : 891ns. 또한에 대해 동일한 관계 와 . random.randrange(2)np.random.rand()random.random()
Shayan Amani

3

시드의 소스와 사용 된 배포 프로파일이 출력에 영향을 미칠 것입니다. 암호화 임의성을 찾고 있다면 os.urandom () 시드는 장치 채터 (예 : 이더넷 또는 디스크)에서 거의 실제 임의의 바이트를 얻습니다 (예 : / BSD의 dev / random)

이것은 당신이 시드를 제공하지 않고 결정적인 난수를 생성하는 것을 피할 것입니다. 그러나 무작위 호출을 사용하면 숫자를 분포에 맞출 수 있습니다 (내가 과학적 무작위성이라고 부르는 것-결국 원하는 것은 무작위 숫자의 종 곡선 분포이며, numpy는이를 가장 잘 파악할 수 있습니다.

그래서 네, 하나의 생성기를 고수하되 원하는 임의의 것을 결정하십시오-임의적이지만 distrubtuion 곡선에서 적절하지 않거나 양자 장치없이 얻을 수있는 임의의 것입니다.


폴 감사합니다. 귀하의 답변은 정말 유용했습니다! 나는 암호화 무작위성을 찾고 있지 않고 수학적 모델링을하고 있으며 의사 난수만으로도 충분합니다. 이항 분포를 위해 numpy가 필요하고 내 프로그램이 무작위를 사용하는 다른 프로그램을 호출하기 때문에 내가 원하는대로 하나의 생성기를 고수 할 수 없다는 것이 밝혀졌습니다 :(
Laura
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.