φυβλαςのβλογ
บล็อกของ phyblas



numpy & matplotlib เบื้องต้น บทที่ ๑๕: การสุ่ม
เขียนเมื่อ 2016/06/11 22:35
ภาษาไพธอนมีมอดูลชื่อ random ซึ่งเก็บรวบรวมฟังก์ชันที่เกี่ยวกับการสุ่ม อ่านรายละเอียดได้ใน https://phyblas.hinaboshi.com/20160508

แต่ว่ากรณีที่ต้องการสุ่มข้อมูลทีละจำนวนมากๆใช้ numpy ช่วยอาจจะเร็วกว่ามาก

numpy มีมอดูลย่อยชื่อ random ซึ่งมีฟังก์ชันสำหรับสุ่มข้อมูลจำนวนมากที่มีประสิทธิภาพสูง ใช้คู่กับอาเรย์ได้ดี

ในที่นี้จะขอแนะนำฟังก์ชันส่วนหนึ่งจากมอดูลย่อยนี้ที่ใช้บ่อย



การสุ่มแบบแจกแจงสม่ำเสมอ
ฟังก์ชัน np.random.rand จะสร้างอาเรย์ที่มีขนาดและมิติตามที่เรากำหนด โดยมีค่าสุ่มในช่วง 0 ถึง 1

ตัวอย่าง
import numpy as np
print(np.random.rand(3,4))
# ได้
# [[ 0.13841332  0.05870797  0.09343369  0.66872065]
#  [ 0.61801752  0.60977038  0.25617062  0.64403814]
#  [ 0.83894127  0.99375777  0.06242056  0.34824402]]

ลองวาดฮิสโทแกรมแสดงการแจกแจงดู
import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(1000,6)
bara = plt.hist(x,bins=10,stacked=1)
plt.show()



จะเห็นว่าแต่ละชุดจะมีจำนวนในแต่ละช่วงเท่าๆกันหมด โดยมีค่าเฉลี่ยที่ประมาณ จำนวนข้อมูลแต่ละชุดหารด้วยจำนวนช่องที่แบ่ง = 1000/10 = 100

np.random.rand นั้นทำการแจกแจงได้แค่ในช่วง 0 ถึง 1 เท่านั้นแต่หากต้องการให้การแจกแจงอยู่ในช่วงอื่นใดๆซึ่งเรากำหนดขึ้นเองก็อาจเลือกใช้ np.random.uniform

np.random.uniform ต้องการอาร์กิวเมนต์ ๓ ตัวคือ ค่าต่ำสุด, ค่าสูงสุด และขนาดของอาเรย์ โดยที่ขนาดของอาเรย์ต้องใส่เป็นทูเพิลหรือลิสต์คู่อันดับ จะไม่ใส่ขนาดของอาเรย์ก็ได้ หากไม่ใส่ก็จะได้ผลเป็นค่าเลขตัวเดียวไม่ใช่อาเรย์

ตัวอย่าง
print(np.random.uniform(10,12,[5,5]))
# ได้
# [[ 11.90063992  11.23890703  10.20759811  11.61095323  11.927567  ]
#  [ 10.5614266   11.35633258  11.20055723  11.42188658  10.36799342]
#  [ 10.82890397  10.34821344  10.02067618  11.67635054  10.74097174]
#  [ 10.99379641  10.16120106  11.1839129   11.0085007   10.6263869 ]
#  [ 11.68345769  11.24997368  10.64367458  11.91462817  10.63300529]]



การแจกแจงแบบปกติ
np.random.randn จะทำการสร้างอาเรย์ที่มีขนาดตามที่ระบุโดยมีค่าสุ่มตามการแจกแจงแบบปกติที่ มีค่าศูนย์กลาง (μ) เป็น 0 และความกว้างของการกระจาย (σ) เป็น 1

ตัวอย่าง
print(np.random.randn(3,5))
# ได้
# [[-0.80200003 -0.9494691   0.99710938  3.19348425  0.93456897]
#  [ 0.92803985  0.83077379  1.96311357  0.95209212 -0.832348  ]
#  [ 0.39231038  0.19578248 -0.13636935 -0.47126378  0.37539167]]

ลองสร้างอาเรย์ใหญ่ๆมาแล้ววาดฮิสโทแกรมแสดงการแจกแจงดู
x = np.random.randn(500,5)
plt.hist(x,bins=50,stacked=1)
plt.show()



np.random.normal ก็เป็นฟังก์ชันที่สร้างการสุ่มที่มีการแจกแจงแบบปกติเช่นกัน เพียงแต่สามารถกำหนดค่า μ และ σ ได้

โดยอาร์กิวเมนต์ที่ต้องใส่ ตัวแรกคือ μ ตัวที่สองคือ σ และตัวที่สามคือขนาดของอาเรย์ที่ต้องการ ถ้าไม่ใส่ขนาดของอาเรย์จะได้เป็นค่าตัวเลขสุ่มค่าเดียวออกมา

ตัวอย่างการกระจายด้วยฮิสโทแกรม
x = np.random.normal(50,10,(1000,6))
c = ['#%d0%d7%d3'%(i+3,i+4,9-i) for i in range(6)]
bara = plt.hist(x,bins=50,stacked=1,color=c)
plt.show()



นอกจากนี้ยังมีการแจกแจงชนิดอื่นๆอีกเช่น np.random.binomical, np.random.poisson, np.random.beta, ฯลฯ



การสุ่มจำนวนเต็ม
ฟังก์ชันที่ใช้สุ่มจำนวนเต็มมีอยู่ ๒ ตัวคือ
np.random.randint
np.random.random_integers

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

ส่วน random_integers จะคล้าย randint แต่ต่างกันตรงที่จะสุ่มในช่วงตั้งแต่อาร์กิวเมนต์ตัวแรกไปจนก่อนถึง อาร์กิวเมนต์ตัวที่สอง ความต่างก็คือไม่รวมอาร์กิวเมนต์ตัวที่สองด้วยเท่านั้น

ตัวอย่าง
print(np.random.randint(2,4,20)) # ได้ [2 2 3 3 2 3 2 3 3 2 3 3 3 3 3 3 3 3 2 3]
print(np.random.random_integers(2,4,20)) # ได้ [4 4 3 4 2 2 2 4 4 2 2 2 4 2 4 2 3 3 2 4]
print(np.random.randint(3,7,(3,8)))
# ได้
# [[4 4 5 6 5 6 4 3]
#  [3 6 3 6 4 6 4 5]
#  [5 4 6 4 4 3 3 5]]



การสุ่มข้อมูลจากอาเรย์
np.random.choice เป็นฟังก์ชันที่ทำการสุ่มหยิบข้อมูลออกมาจากอาเรย์หรือลิสต์เพื่อมาสร้างอาเรย์ที่มีขนาดตามที่กำหนด

อาร์กิวเมนต์ของฟังก์ชันนี้ตัวแรกคืออาเรย์ที่ต้องการให้สุ่มสมาชิก และตัวที่สองคือขนาดของอาเรย์ที่ต้องการสร้าง

ตัวอย่าง
a = np.array([2,2,2,2,3,5])
ar = np.random.choice(a,(2,20))
print(ar)
# ได้
# [[2 2 2 2 2 2 2 2 3 2 2 3 5 3 2 2 2 5 2 5]
#  [2 5 2 2 2 2 2 2 2 3 2 3 2 2 2 2 3 2 2 5]]

เราสามารถกำหนดน้ำหนักความน่าจะเป็นในการสุ่มได้แต่ละค่าได้ด้วยโดยเพิ่มคีย์เวิร์ด p

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

ถ้าลองสุ่มตัวเลขจำนวนเต็มตั้งแต่ 1 ถึง 20 แล้วให้น้ำหนักในการสุ่มเป็นสัดส่วนกันกับค่าของตัวเลขพอเขียนฮิสโทแกรมแล้ว ก็จะได้เป็นแท่งที่สูงขึ้นเรื่อยๆ
a = np.arange(1,21)
p = a/sum(a) # น้ำหนักเป็นค่าของแต่ละตัวหารด้วยค่าผลรวม
x = np.random.choice(a,10000,p=p)
plt.hist(x,bins=20)
plt.show()





การสุ่มสลับข้อมูลในอาเรย์
ในการสลับจัดเรียงข้อมูลในอาเรย์ใหม่นั้นมีฟังก์ชันอยู่ ๒ ตัวคือ np.random.permutation และ np.random.shuffle

ฟังก์ชันทั้ง ๒ ตัวนี้จะทำการสลับอาเรย์ในแกนแรกสุด

ข้อแตกต่างก็คือ np.random.permutation จะแค่คืนค่าของอาเรย์ที่ถูกจัดเรียงแล้วออกมา แต่อาเรย์ตัวเดิมก็ยังอยู่

ส่วน np.random.shuffle จะเป็นการแก้ไขเขียนทับอาเรย์ตัวที่ถูกทำ
a = np.arange(20).reshape(4,5)
print(a)
# ได้
# [[ 0  1  2  3  4]
#  [ 5  6  7  8  9]
#  [10 11 12 13 14]
#  [15 16 17 18 19]]

print(np.random.permutation(a))
# ได้
# [[ 5  6  7  8  9]
#  [10 11 12 13 14]
#  [ 0  1  2  3  4]
#  [15 16 17 18 19]]

print(a)
# ได้
# [[ 0  1  2  3  4]
#  [ 5  6  7  8  9]
#  [10 11 12 13 14]
#  [15 16 17 18 19]]

print(np.random.shuffle(a)) # ได้ None
np.random.shuffle(a)
print(a)
# ได้
# [[10 11 12 13 14]
#  [15 16 17 18 19]
#  [ 0  1  2  3  4]
#  [ 5  6  7  8  9]]



การสร้างเมล็ดในการสุ่ม
เช่นเดียวกับมอดูล random ใน np.random เองก็มีฟังก์ชันสำหรับการสร้างเมล็ดในการสุ่ม ชื่อ np.random.seed

รายละเอียดให้ไปดูในบทความที่เขียนเรื่องมอดูล random (ลิงก์อยู่ด้านบน) จะไม่ขอกล่าวซ้ำ

ตัวอย่าง
for i in range(5):
    np.random.seed(1)
    print(np.random.randn(1,4))

ได้
[[ 1.62434536 -0.61175641 -0.52817175 -1.07296862]]
[[ 1.62434536 -0.61175641 -0.52817175 -1.07296862]]
[[ 1.62434536 -0.61175641 -0.52817175 -1.07296862]]
[[ 1.62434536 -0.61175641 -0.52817175 -1.07296862]]
[[ 1.62434536 -0.61175641 -0.52817175 -1.07296862]]



อ้างอิง


<< บทที่แล้ว     บทถัดไป >>
หน้าสารบัญ


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> numpy

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

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
python
-- numpy
-- matplotlib

-- pandas
-- pytorch
maya
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
เรียนภาษาจีน
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

หลักการเขียนทับศัพท์ภาษาจีนกลาง
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
บ้านเก่าของจางเสวียเหลียงในเทียนจิน
เที่ยวจิ่นโจว ๓ วัน ๒ คืน 23 - 25 พ.ค. 2015
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
บันทึกการเที่ยวสวีเดน 1-12 พ.ค. 2014
แนะนำองค์การวิจัยและพัฒนาการสำรวจอวกาศญี่ปุ่น (JAXA)
เที่ยวฮ่องกงในคืนคริสต์มาสอีฟ เดินทางไกลจากสนามบินมาทานติ่มซำอร่อยโต้รุ่ง
เล่าประสบการณ์ค่ายอบรมวิชาการทางดาราศาสตร์โดยโซวเคนได 10 - 16 พ.ย. 2013
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
บันทึกการเที่ยวญี่ปุ่นครั้งแรกในชีวิต - ทุกอย่างเริ่มต้นที่สนามบินนานาชาติคันไซ
หลักการเขียนคำทับศัพท์ภาษาญี่ปุ่น
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ
ทำไมถึงอยากมาเรียนต่อนอก
เหตุผลอะไรที่ต้องใช้ภาษาวิบัติ?

บทความแต่ละเดือน

2019年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2018年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2017年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2016年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2015年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文