Saran Khotsathian
botnoi-classroom
Published in
5 min readSep 1, 2020

--

ไหนใครอยากเป็นเศรษฐี… มาทำนายกันดูว่า งวดหน้าจะออกเลขอะไรด้วย Genetic Algorithm กันเถอะ [DSE G18 Botnoi Week2–3]

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

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

สำหรับอาทิตย์นี้ คอร์ส DataScience Essential ได้สอนในหัวข้อของ Machine Learning Pipeline ซึ่งจะประกอบไปด้วย

  1. Get Data
  2. Clean Data
  3. Extract Features
  4. Train Model
  5. Evaluation

สามารถเปิด Colab เพื่อดูตามได้เลย >>> [จิ้มเบาๆที่นี่นะ]

มาเริ่มต้นกันเลย

[คำเตือน] การลงทุนมีความเสี่ยง ผู้ลงทุนควรศึกษาข้อมูลก่อนการตัดสินใจลงทุน

1. Get Data

หลังจากได้หัวข้อมา เราก็ต้องหาข้อมูลกันก่อนเลย จนได้ข้อมูลย้อนหลังหวยจาก แทน แท่น แท๊นนนนน…

โดยในข้อมูล มีประวัติการออกหวยย้อนหลัง ทั้งสิ้น 20 ปี หรือรวม 477 งวด ซึ่งในข้อมูลเราจะเจาะจงไปที่ รางวัลเลขท้าย 2 ตัว และเมื่อได้ลองสำรวจและพล็อตสถิติเลขที่เคยออก ได้ดังนี้

แนวนอนคือ เลขท้าย2ตัวที่ออก และ แนวตั้งคือ จำนวนครั้งที่ออก

ที่น่าสนใจคือ เลข 85 ออกบ่อยครั้งที่สุดในขณะที่ 84 ยังไม่เคยออกมาก่อนเลยตลอด 20 ปีที่ผ่านมา!!!

หน้าตาข้อมูลที่ดึงมาจากเว็บ

ทำความรู้จักกับข้อมูลกันนิดนึง

ผลการออกของหวย หรือล็อตเตอรี่นั้น เนื่องจากเป็น ข้อมูลที่เรียกกันว่า Non-Deterministic data types หรือก็คือเป็น Data ที่เราไม่สามารถคาดคะเนผลได้ การจับแต่ละครั้งจะได้ผลลัพธ์ที่แตกต่างกันออกไป

Computer, Algorithm, And Random?

การสุ่มนั้นถ้าเป็นการสุ่มบนคอมพิวเตอร์โดยทั่วไป จะเรียกว่า Pseudo-Random Number Generator (PRNG) คือเป็นการสุ่มแบบเทียม โดยจะมีตัวสร้างชุดตัวเลขสุ่มแบบเทียม หรือที่เรียกว่า Deterministic random bit generator(DRBG) ซึ่งจะมี Algorithm ในการสร้างชุดตัวเลขสุ่มที่ใกล้เคียงกับการสุ่มจริง(แต่ก็ไม่ใช่การสุ่มที่แท้จริงอยู่ดี)

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

ตัวอย่างการสุ่มค่า 00–99 โดยแสดงให้เห็นทั้งการกำหนดให้ Seed = 0

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

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

เอาละ ความปวดหัวก็อยู่ที่ตรงนี้แล้วว่า ถ้าเราคาดเดาไม่ได้ แล้วเราจะทำนายผลกันอย่างไรหล่ะทีนี้ [ตรงนี้จะกล่าวต่อในหัวข้อของการสร้างและ Train model]

2. Clean Data

เมื่อเราได้ข้อมูลมาจากแหล่งข้อมูล เราก็จะมาเช็คความสมบูรณ์ของข้อมูล โดย จะมีข้อมูลเป็นเดือนภาษาไทย และ ปีพุทธศักราช เราจึงแปลงข้อมูล ให้อยู่ในรูปสากล ดังนี้

และเราได้ลองแยกตัวเลขเป็นเลขตัวหน้า และ เลขตัวหลัง ด้วยการ คำสั่งดังนี้

3. Extract Features

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

แต่!!! โหราศาสตร์ก็ดูเหมือนจะไปไม่รอด ด้วยความที่ว่าตัวเลขมันสุ่ม สุ่มซะจน Model ไม่สามารถ Predict ได้ผลลัพธ์ที่จะน่าพอใจเสียเท่าไหร่

แผนการหมอดูคู่หมอเดา จึงต้องพับเก็บไป เพราะไม่คุ้มกับการลงแรง

จึงกลับมาใช้ข้อมูลเท่าที่มี ก็คือเลขท้าย 2 หลัก

โดยวิธีที่เราจะใช้ สามารถดูได้ในหัวข้อต่อไป!!!

4. Train Model

หลังจากหน่วยมือปืน นั่งคิด นอนคิด ตะแคงคิด ตีลังกาคิดก็แล้ว มีหลายโมเดลที่มีไอเดียที่น่าสนใจ ไม่ว่าจะ

  • CNN โดยสร้าง Matrix ของความถี่การออก ความสัมพันธ์ระหว่างตัวเลข
  • ใช้ข้อมูลโหราศาสตร์
  • Multi-Armed Bandit
  • Epsilon-Greedy และอื่นๆ

ก็ได้ศึกษาโมเดลต่างๆ และลองทำความเข้าใจ และมาจบลงที่ตัวนี้

— Genetic Algorithm

Credit: https://www.discovermagazine.com/planet-earth/race-is-real-but-its-not-genetic

ก่อนที่จะอธิบายว่า Genetic Algorithm มันมีลักษณะการทำงานอย่างไร มาเริ่มทำความรู้จักกับ Machine Learning เพิ่มขึ้นกันซักนิดนึง

ในการทำ Machine Learning นั้นเราอาจมองในอีกมุมนึงได้ว่าเป็นการทำ Optimization โดยให้ Cost หรือ Lost ของ model มีค่าน้อยที่สุด หรือที่เราเรียกว่า Minimization

ทีนี้การทำ Optimization จริงๆ แล้วไม่ได้มีแค่การ Minimization เพื่อลด Lost เพียงอย่างเดียว แต่มีการทำ Maximization เพื่อหาจุดที่มากที่สุด เช่น อาจจะสร้างกำไรมากที่สุด หรือมีคะแนนมากที่สุด เป็นต้น

จุดที่เป็นจุดสูงสุด กับ จุุดต่ำสุดเราจะเรียกรวมๆว่า Extrema point

กราฟแสดงจุด Extrema ทั้ง 4 แบบ บน Search Space

จากนั้นในการหาจุดที่จะเป็น Maximum หรือ Minimum จะใช้สองวิธีใหญ่ๆ ก็คือ

  • การทำ Exploitation โดยจะเป็นการโฟกัสไปที่จุดที่เราสนใจอยู่และพัฒนาให้จุดนั้นดีขึ้น เพื่อหาจุด Extrema
  • การทำ Exploration โดยจะเป็นการหาส่วนที่ยังไม่เคยถูกค้นพบให้มากที่สุดเท่าที่เป็นไปได้

โดยหากเราใช้แค่วิธี Exploitation เราก็จะมีโอกาสที่จะติดอยู่แค่ Local Extrema แต่หากเราใช้แค่ Exploration อย่างเดียวก็จะได้ค่าที่สุ่มมั่วกระจายบน Search spaceไปหมด จึงต้องมีการกำหนดอัตราส่วนของทั้งสองวิธีให้ดีและบาลานซ์กัน

ทีนี้หลักการของ Genetic Algorithm นั้นจะเลียนแบบหลักการของ Charles Darwin ในเรื่องของ Natural Selection หรือการคัดเลือกทางธรรมชาติ

คุณสมบัติของ Genetic Algorithm จะเป็น Search Heuristic

ในการออกแบบ Genetic Algorithm นั้น จะต้องมีการออกแบบ

  • ตัวแปร(Parameter) ซึ่งก็คือ Gene
  • หลายตัวแปร(Parameters) มารวมกัน เป็น Chromosome

ในที่นี้เนื่องจากเราใช้คอมพิวเตอร์ในการหาตัวเลขที่จะถูกสุ่มขึ้นเราจะกำหนดให้ ตัวแปรคือ Seed (สามารถย้อนกลับไปอ่านในทำความรู้จักข้อมูลใต้หัวข้อ Get Data) ที่จะใช้หาลำดับตัวเลขของการออกผลสลากเลขท้าย2 ตัว

โดยเราจะออกแบบ Chromosome ให้ 1 Chromosome มี 5 Seed ที่จะสร้างลำดับตัวเลข โดยจุดมุ่งหมายคือ

หา Seed 5 ตัวที่ทำให้เรามีโอกาสถูกหวยมากที่สุด!!

ขั้นตอนของการทำ Genetic Algorithm ก็คือ

  1. Initial Population (สุ่มประชากรกลุ่มแรก เหมือน อดัมกับอีฟ)
  2. Calculate Fitness (คำนวนคะแนนความอยู่รอด ในที่นี้คือทำนายได้แม่นแค่ไหน)
  3. Selection (การคัดเลือก)
  4. Crossover (การส่งต่อ Chromosome ไปสู่ รุ่นลูก)
  5. Mutation (การกลายพันธุ์)
  6. จะได้ประชากรชุดต่อไปแล้ว ทำซ้ำข้อ 2–6. ต่อไปเรื่อยๆ

โดย Selection/Crossover จะเน้นไปเป็นการทำ Exploitation และ Mutation จะเป็นการทำ Exploration จากที่ได้กล่าวไปก่อนหน้านี้

หมายเหตุ ในบางครั้ง Selection เพื่อ Crossover สามารถมีความสุ่มเกิดขึ้นได้บางเพื่อขยาย Search Space

Initial Population

ในแต่ละ Generation เราจะกำหนดประชากรไว้ที่ 100 ตัว

โดยประชากรกลุ่มแรกจะเกิดจากการสุ่ม Seed ขึ้นมาจาก function นี้

โดยต่อไปเราจะเรียกประชากรแต่ละตัวว่า Agent โดยทำการสร้าง Class สำหรับ Agent ดังนี้

Population กลุ่มแรกจะถูกสร้างขึ้นมาโดยการ init Agent() เปล่าๆมาจำนวน 100 ตัว

Calculate Fitness

ในการคำนวนค่า Fitness เราได้ทำการทดลองสองแบบโดย

แบบแรก กำหนด Reward และ Penalty ด้วยจำนวนเงิน ที่เราจะได้และเสีย ซึ่งในรางวัลเลขท้าย 2 ตัวเราจะได้เงิน 2000 ต่อตัว และในทุกๆตัวที่เราซื้อ จะเสีย 80 บาทเป็นค่าสลาก

แบบที่สอง กำหนด Reward อย่างเดียว เป็นจำนวนครั้งที่ agent ทำนายแล้วถูกหวย

โดย function ที่สร้างขึ้นมา เทียบว่า agent ทำนายว่าออกอะไร แล้วของจริงออกเลขอะไร จะคืนค่าเป็นคะแนนของ agent ในงวดนั้นๆ แล้วจะนำคะแนนที่ได้ในแต่ละงวดมารวมกัน

หมายเหตุ penalty_mult มีไว้สำหรับปรับ weight ของ penalty ขณะ runtime ได้

Selection

หลังจากที่เราได้คำนวนหาคะแนน fitness score ของ agent แล้ว เราจะทำการคัดเลือก ผู้ที่จะส่งถ่าย Gene ให้สู่รุ่นลูกต่อๆไป

โดย การ Selection ที่เราใช้นั้น จะมีชื่อว่า Tournament Selection โดยมีขั้นตอนคือสุ่มจากประชากรมีจำนวน K ตัว(เราใช้ K=5) แล้วเทียบคะแนน เอาตัวที่คำแนนสูงที่สุดมา 1 ตัว

ทำอย่างนี้สองรอบ จะได้ agent มาเป็น พ่อพันธุ์ และ แม่พันธุ์ที่จะถ่ายทอด Chromosome ต่อไปสู่รุ่นลูกต่อไป

Crossover

เมื่อเราได้พ่อพันธุ์ แม่พันธุ์แล้ว เราจะนำ Chromosome ของ agent ทั้งสองตัวมา Crossover กันโดยวิธีการที่เราใช้จะเรียกว่า

Single-Point Crossover

ซึ่งจะมีจุดตัดจุดเดียว โดยตำแหน่งที่เป็นจุดตัดก็จะเกิดจากการสุ่ม

ตัวอย่างการทำ Single-Point Crossover โดยมีจุดตัดที่เส้นสีแดง ด้านซ้ายมือจะเป็น Parent และด้านขวามือจะเป็น Children

ภาพจาก https://www.tutorialspoint.com/genetic_algorithms/genetic_algorithms_crossover.htm

โดยหลังจาก Crossover เสร็จเราจะใส่เข้าไปรอเป็นประชากรชุดต่อไป

Mutation

พูดถึงการกลายพันธุ์ บางคนอาจนึกถึงเหมือนอย่างในหนังเรื่อง X-Men ที่จะมีพลังวิเศษ พลังจิต แหม่ ก็ไม่ถึงขนาดนั้น

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

Mutation เปลี่ยนบิท 1 เป็น 0

5. Evaluation

ในการประเมิณผลอย่างแรกคือเราจะดูว่า Model มีการโตขึ้นดีไหม หากไม่ดี ก็จะปรับอัตราส่วนระหว่างส่วนของ Exploitation กับ Exploration ต่อไป

จากนั้นก็ทำการวัดผลว่าจากทั้งหมด 477 งวดที่ในชุดข้อมูลที่เรามีอยู่ สามารถทำนายผลได้ถูกทั้งหมดกี่งวด คิดเป็นอัตราส่วนกี่เปอร์เซ็นต์

เทียบผลลัพธ์จากการใช้ Fitness Function ที่ใช้เงินรางวัล และราคาหวยเป็น Reward Penalty

โดยมีการปรับ Weight ของ penalty เพิ่มขึ้น ทุกๆ 25 generation สูงสุดที่ Generation 200

Best agent parameters: 
[6537606333339024989, 4046116087100411627, 428995388868369595, 8934892049055765104, 5191939758171052651]
Total won times is 64 out of 477
The chance of winning lottery if playing with this seeds is 13.417190775681343 %
Next lotto-draw will be
[81, 77, 56, 30, 46]

ซึ่งหมายความว่าหากเราเล่นหวยด้วย Seed นี้ไปเรื่อย

ทุกๆ 100 งวด เราจะถูก 13.41 งวด

เทียบผลลัพธ์จากการใช้ Fitness Function ที่นับจำนวนงวดที่ถูกหวย

Best agent parameters: 
[4390144449906031803, 8207737778911746883, 1384534071542546901, 2246224606278164369, 2211375093533678110]
Total won times is 70 out of 477
The chance of winning lottery if playing with this seeds is 14.675052410901468 %
Next lotto-draw will be
[39, 64, 20, 57, 28]

หมายความว่าถ้าเราเล่นด้วย Seed นี้ไปเรื่อยๆ

ในทุกๆ 100 งวดจะมีโอกาสถูก 14.67 งวด

ลองเพิ่มจำนวน Generation ที่ใช่ในการหา เพื่อเพิ่มโอกาสในการหาเจอ

5000 Generation

Best agent parameters: 
[9199730571349864107, 4757595859748546175, 2648605935258513740, 6982533059843676715, 1327435637300285540]
Total won times is 75 out of 477
The chance of winning lottery if playing with this seeds is 15.723270440251572 %

หมายความว่าถ้าเราเล่นด้วย Seed นี้ไปเรื่อยๆ

ในทุกๆ 100 งวดจะมีโอกาสถูก 15.72 งวด

10000 Generation

Best agent parameters: 
[4294147991847424952, 3407667145315663360, 8657109241803690336, 2944623869079110581, 744271235270839152]
Total won times is 73 out of 477
The chance of winning lottery if playing with this seeds is 15.30398322851153 %

หมายความว่าถ้าเราเล่นด้วย Seed นี้ไปเรื่อยๆ

ในทุกๆ 100 งวดจะมีโอกาสถูก 15.30 งวด

สำหรับในงวดวันที่ 01/09/2020 นั้นทางกลุ่มเราได้ใช้ Seed ชุด

[8847810355337583720, 2396593734501339735, 5019067308694769568, 2099661789863258109, 7304726439098963216]

ที่รันในครั้งแรกๆ (เดี๋ยวเลขเคลื่อน 55555 ) และกลุ่มเราก็นัดกันซื้อเลขเหล่านี้ไว้แล้ว

[42, 84, 89, 96, 96]

สามารถติดตามเลขเด็ดจากสำนัก Genetic Algorithm รุ่นหลวงปู่เค็ม ได้ผ่าน API ลิงค์นี้เลยครับ

https://lotto-flask.herokuapp.com/api/lotto

โดยเราได้ใช้ Python-Flask เพื่อ serve หน้าเว็บเป็น restful-api ผ่านทาง hosting อย่าง Heroku

— การต่อยอดทาง Business

นอกจากการใช้ Genetic Algorithm สามารถช่วยเพิ่มโอกาสในการคาดเดาสิ่งที่มีความแปรปรวนในระดับหนึ่งแล้ว ยังสามารถไปประยุกต์ใช้ร่วมกับ Machine Learning Algorithm อื่นๆได้ อย่าง Deep Learning หรือจำพวก Neural Network โดยให้ Weights / Parameters ของ Model แต่ละตัวคือ Gene ก็จะสามารถประยุกต์ใช้ในการใช้งานที่หลากหลาย ได้มากยิ่งขึ้น

สำหรับกลุ่มเรา… เราจะนำโมเดลนี้ไปพัฒนาต่อ เพื่อเปิดสำนักหวย G18 ขึ้นมา และเราจะเป็นเศรษฐีไปพร้อมๆกัน

และหากกกกกก…..

ถูกล็อตเตอรี่ต้องทำอย่างไรบ้าง ทำตามนี้เลยครับ

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

ขอให้ทุกคนโชคดีมีชัย โชคชัยมีวัว ถูกล็อตเตอรี่กันทุกๆคนครับ

โดยการพัฒนาต่อไปเราจะรันที่ Generation สูง หรือปรับปรุงอัตราส่วน Exploration Exploitation เพื่อให้สามารถหาชุดตัวเลขที่มีโอกาสถูกหวยได้สูงขึ้นต่อไปครับ

[อัพเดท ผลเลขที่ออกงวด 01/09/2020]

รางวัลเลขท้าย 3 ตัว 957, 342

รางวัลเลขท้าย 2 ตัว 98

และโมเดลที่เราใช้ทำนายไว้ว่า [42, 84, 89, 96, 96]

98 นี่มันเลขกลับ 89 ชัดๆ งานนี้ คอหวยอย่างพี่มือโปร Pridatakon ที่ได้กลับเลขเอาไว้แล้ว ก็ถูกไปเรียบร้อย และใครที่ซื้อ 42 ไว้ก็ได้ลุ้น 3 ตัวท้ายอย่างเลข 342

ไหนใครถูกหวยบ้าง ยกมือหน่อย แล้วอย่าลืมมาแชร์ว่าเลือกเลขจากอะไรยังไงกันบ้างนะครับ

[อัพเดท การรันโมเดลที่ 50,000 Generation 02/09/2020]

เราได้ Agent ที่มีความสามรถในการทำนายที่ถูก 86 งวด จาก 477 งวดที่เราได้เก็บข้อมูลออกมา แต่เราขออุปส์ตัวเลขที่เราทำนาย ไว้ก่อน แล้วอาจจะเปิดเป็น Subscribe ให้ เฉพาะสมาชิก อิอิ

--

--