Processing EEG signal for Classification (Brain Code Camp 2023)

Jirayu Supasil (Charlie)
5 min readNov 3, 2023

--

สวัสดีครับ บทความนี้เป็นบทความแรกของผมที่ได้เขียนบน medium เลย แต่ก่อนผมเห็นเพื่อนๆที่คอยเขียนบทความลง medium เป็นของตัวเองแล้วมันดู cool มาก ผมเลยวางแผนมาตลอดว่าวันนึงจะลองเขียนบทความตัวเองดูมาก แต่ที่ผ่านมาถ้าไม่ลืมก็ขี้เกียจเขียนมาตลอดเลย จนวันนึงผมได้ assignment ให้เขียนเกี่ยวกับ project ที่ตัวเองทำลงใน Brain Code Camp ปี 2023 นี้ โดยถ้าผมไม่เขียนเขาจะไม่ให้ผมจบครับ (แหะๆ 😅) เลยถือเป็นโอกาสอันดีที่ผมจะได้เริ่มเขียนบทความแรกแล้ว ดู cool เหมือนเพื่อนๆได้แล้ว (โดนบังคับครับ😅)

เริ่มเลย พื้นหลังของผมผมจบโทฟิสิกส์ครับ และไม่มีความรู้เบื้องต้นเกี่ยวกับ neuroscience เลย แต่ช่วงนี้ผมกำลังสนใจอยากศึกษาเทคโนโลยีที่เชื่อมต่อสมองคนกับเครื่องจักรเพื่อสั่งการหรือรับความรู้สึกได้เสมือนเป็นอวัยวะอีกชิ้นหนึ่ง ซึ่งแนวคิดนี้ ตัวหัวข้อที่ใกล้เคียงที่สุดคงจะเป็นงานแนว brain computer interface (BCI) บางครั้งก็เรียกว่า brain machine interface (BMI) นั่นเลยเป็นเหตุผลให้ผมลองมาสมัครโครงการ Brain Code Camp ปีนี้ดู

โดยไอเดียที่ผมอยากลองฝึกทำในงานนี้คือสร้างระบบที่ประยุกต์งาน BCI กับเครื่องใช้ไฟฟ้าต่างๆ แบบงาน internet of thing ที่เราสามารถเพ่งสมาธิแล้วให้เครื่องอ่านสัญญาณเดาว่าเรากำลังอยากเปิดใช้งาน device ตัวไหนอยู่ อาจจะเป็นหลอดไฟ แอร์ ทีวี หรือแม้แต่คุม droid ให้หยิบแก้วน้ำมาให้ ดังนั้นสิ่งที่ผมต้องการเพื่อที่จะทำระบบนี้ได้เลยคือ

  1. สัญญาณสมองที่เอามาแปลงผลได้แบบ real time
  2. ตัว model ที่ไว้สำหรับแยกความต่างของสัญญาณแบบต่างๆเพื่อแปลงรหัสเป็นคำสั่งที่เจ้าของสมองต้องการจะสื่อสารออกไป

ประเด็นแรกสัญญาณสมอง ผมต้องตัดสินใจว่าจะเอาสัญญาณแบบไหนดีที่เหมาะกับงานผม โดยอิงจากบทเรียนที่สอนใน BrainCode 101 ของโครงการเดียวกัน มีกล่าวถึงวิธีการเก็บข้อมูลจากสมองแบบต่างๆ จากที่นั่งฟังเลคเชอร์แม้จะมีหลายวิธียิบย่อยลงไป แต่วิธีที่ใหญ่ๆ ที่ฟังแล้วจำง่ายสุดสำหรับผมก็มี Single unit recording ซึ่งเป็นวิธีทำวัดเซลล์ประสาทโดยตรง EEG (Electroencephalography) เป็นวิธีวัดสัญญาณไฟฟ้าจากภายนอก และ fMRI (Functional magnetic resonance imaging) เป็นวิธีวัดสัญญาณผ่านการดูการไหลเวียนโลหิตในสมอง ซึ่งแต่ละแบบจะมีจุดเด่นจุดด้อยแตกต่างกันไป โดยตัวแปรที่เราจะพิจารณาถึงคุณภาพการวัดนั้นๆ มีหลักๆ อยู่ด้วยกัน 2 ด้าน

  1. Time Resolution ความละเอียดทางด้านเวลา
  2. Spatial Resolution ความละเอียดทางตำแหน่ง
แผนผังการวัดสัญญาณสอมงแบบต่างๆ ที่กระจายตามความสามารถในการวัด โดยแกนตั้งคือความละเอียดเชิงพื้นที่ และแกนนอนคือความละเอียดเชิงเวลา (Sejnowski, Churchland, & Movshon, 2014)

เนื่องจากผมอยากวัดสัญญาณแบบ real time ได้จึงควรใช้การเก็บข้อมูลที่ มี Time Resolution สูง ซึ่งในบทเรียนได้มีตารางสรุปขอบเขตของการวัดแบบต่างๆ มาให้ โดยจะเห็นว่า วิธีวัดที่เหมาะและค่อนข้างรู้จักกันอย่างแพร่หลายน่าจะเป็นไม่ EEG ก็ Single unit แต่เนื่องจากการทำ Single unit มีข้อจำกัดด้านการติดตั้งมากกว่า EEG เลยเป็นทางเลือกที่เหมาะที่สุดสำหรับผมครับ

ในส่วนประเด็นเรื่อง model ทีจะใช้ควรเป็น model ประเภทใดดี ผมจินตนาการว่าหากเราสั่งการ device ต่างๆผ่านสมอง device ควรทำอย่างไรกับสัญญาณสมองนั้น ซึ่งแน่นอน ตัว device คงต้องการที่จะแยกได้ว่าสัญญาณแบบไหนเราอยากให้เปิด/ปิด สัญญาณไหนอยากให้ เพิ่มเสียง/เบาเสียง หรือรูปแบบอื่นๆ ดังนั้น model ที่ค่อนข้างเข้ากับโจทย์ปัญหานี้น่าจะเป็น classification model โดยในงานนี้คงยังไม่ลงลึกว่า classification model ที่เอามาใช้แต่ละอันมีรายละเอียดอย่างไร แต่ผมจะยกแค่ตัวอย่างจากที่เจอในบทเรียนใน code camp นี้มาลองทดสอบดูซึ่ง model ที่ผมหยิบยกมาจะเป็น logistic regression, support vector machine (SVM), k-nearest neighbor (KNN) และ random forest

หลังจากได้โจทย์ละว่าตัวเองอยากทำอะไรในโปรเจ็กนี้ ขั้นต่อไปก็คือการค้นหา data set สำหรับมาเล่นกับ idea ของตัวเองดู โดยในโครงการนี้เปิดให้เราหา data มาเองหรือ ใช้ data set ที่มีการตระเตรียมไว้ให้ก็ได้ ซึ่งแน่นอนผมต้องหา data set เกี่ยวกับ EEG เป็น keyword แรกก่อนเลย ซึ่งสุดท้ายผมได้ data set จาก paper หัวข้อเรื่อง

“Alpha-Band Oscillations Enable Spatially and Temporally Resolved Tracking of Covert Spatial Attention” (Foster, J. J., Sutterer, D. W., Serences, J. T., Vogel, E. K., & Awh, E. ,2017)

ซึ่งเป็นหัวข้อที่ศึกษาการเพ่งสมาธิที่ตำแหน่งต่างๆ เทียบกับสัญญาณ EEG โดยตัว paper จะสนใจในช่วงคลื่น Alpha band เป็นหลัก

(ภาพซ้าย) ภาพแสดงวิธีติดตั้งการวัดสัญญาณ EEG โดยติดตัวเซนเซอร์วัดกระจายรอบหัว (ภาพขวา) ภาพสัญญาณที่วัดได้ออกมา (ที่มา: Electroencephalography — Wikipedia)

โดยปกติสัญญาณ EEG จะถูกวัดจากตัววัดสัญญาณไฟฟ้าที่ติดรอบหัวหลายตัว โดยสัญญาณที่ได้ออกมาจะมีลักษณะเป็นคลื่นระลอก และด้วยความซับซ้อนของสัญญาณนี้เอง ทำให้มีการคิดวิธีที่เราจะวิเคราห์สัญญาณโดยเปลี่ยนข้อมูลดิบเดิมที่วัดในหน่วยแกนเวลา (time domain) เป็นแกนความถี่ (frequency domain) ซึ่งในหลายกรณีการเปลี่ยนแกนก็ช่วยให้เราอ่านข้อมูลและวิเคราะห์สัญญาณง่ายขึ้น

ตัวอย่างของการเปรียบเทียบสัญญาณในแกนเวลาและแกนความถี่ (ที่มา: Teach Tough Concepts: Frequency Domain in Measurements — NI)

เครื่องมือหลักที่นิยมมากในการเปลี่ยนแกนเวลาเป็นแกความถี่คือ Fourier Transform ซึ่งในบทความนี้ผมจะยังไม่ลงสมการหรือรายละเอียดทาง math มากครับเพื่อประหยัดเวลา (เดี๋ยวเขียนเสร็จไม่ทันส่ง deadline ครับ 🥺) แต่เราสามารถมองมันเป็น tool หรือ box อย่างนึงที่ช่วยให้ดูสัญญาณได้ในอีกมุมมองนึงซึ่งอาจมีประโยชน์ในการวิเคราะห์สัญญาณต่อไปได้

ช่วงความถี่รูปแบบต่างๆของสัญญาณ EEG โดยมีการศึกษาที่แบ่งความเกี่ยวข้องของย่านต่างๆกับส่วนต่างๆของสมองที่ต่างกันไป เช่นใน alpha band ที่เกี่ยวโยงกับ spatial attention (ทีมา: Bandpower of an EEG signal (raphaelvallat.com))

ในส่วนของงานที่หยิบยกมา จากที่กล่าวไปก่อนหน้านี้ว่า ตัว paper สนใจคลื่นช่วง alpha band ย่าน 8 -12 Hz ซึ่งเป็นหนึ่งในย่านความถี่ต่างๆของสัญญาณ EEG โดย ข้อมูลใน paper ระบุว่าตัวสัญญาณย่านนี้อาจมีความเกี่ยวข้องกลับ การเพ่งเล็งสมาธิต่อตำแหน่งหรือ spatial attention

ในการทดลองเพื่อพิสูจน์สมมุติฐานนี้ หนึ่งในสองวิธีการทดลองที่ผมได้หยิบ data จากส่วนนี้มาเล่นในงานผม จะเป็นการทดลองโดยการให้ผู้ทดลองมองหาตำแหน่งที่มีตัวเลขปรกกฏจากตำแหน่งต่างๆ 8 ตำแหน่งรอบๆวงกลม แล้วจากนั้นจะมีการเก็บสัญญาณ EEG จากผู้ทดลอง โดยใช้ sensor 22 channels เก็บข้อมูล เป็นสัญญาณ EEG จริง 19 channels

การทดลองที่ให้ผู้ทดลองจดจ่อกับตำแหน่งต่างๆ แล้ววัดสัญญาณ EEG ออกมา

โดยข้อมูลดิบที่ได้มาเป็นค่าสัญญาณเทียบตามตำแหน่งเวลาจาก sampling rate 250 Hz ทั้งหมด 688 จุด หรือ time steps ต่อแต่ละตัว sensors ในงานนี้เราได้ทดลองกับข้อมูลของผู้ทดลองแค่คนเดียว ซึ่งมีการวัดทั้งหมด 1368 trials ทำให้ข้อมูลดิบที่ผมจะต้องเอามา pre-process ก่อนที่จะส่งไป train กับ model มีทั้งหมด #trials x #channels x #time steps = 1368 x 22 x 688

เนื่องจากเราสนใจช่วง alpha band ดังนั้น การใช้ Fourier Transform ย่อมเป็นสิ่งที่หลีกเลี่ยงไม่ได้ โดยแผนผมในการจัดการข้อมูลดิบเหล่านี้คือการแปลงสัญญาณดิบทั้ง 22 channels ไปเป็น frequency domain จากนั้นก็ตัดออกเอาแค่ข้อมูลของช่วง 5–15 Hz ซึ่งได้ data points ต่อแต่ละ channels 22 จุด เลือกเฉพาะ channels ทีเป็นของสัญญาณ EEG 18 channels ตอนนี้เราจะเหลือข้อมูลที่จะนำมาวิเคราะห์ต่อทั้งหมด 1368 x 18 x 22 และเป็นข้อมูลใน frequency domain

ขั้นตอนการ pre-process data ของ project นี้ โดยเริ่มจากแปลงเป็น frequency domain ด้วย Fourier Transform จากนั้นกรองเอาแค่ย่าน band ที่ต้องการช่วง 5–15 Hz

จากนั้นจึงนำข้อมูลมา encode ใหม่เพื่อเตรียมเป็น features สำหรับ train model โดยผมได้นำข้อมูลทั้ง 22 จุดของแต่ละ channels ทั้งหมด 18 ตัว มาวางเรียงต่อเป็นแถวเดียวกันเพื่อปรับมิติข้อมูลใหม่ให้ง่ายต่อการนำมาใช้ต่อกับ model เป็น 18 x 22 = 396 data points ต่อ trial กลายเป็น matrix ขนาด 1368 x 396

นอกจาก features เรายังต้องเตรียม labels ซึ่งเป็นอีกชุดข้อมูลสำหรับ train model โดย features เป็นเหมือน input ให้ model และ labels เป็นส่วนที่ใช้สอน model ว่าควรจะทำนาย labels จาก features อันใหม่อย่างไร

โดยการ encode labels นั้นขึ้นอยู่กับปัญหาว่าเราอยากได้อะไรจาก model ซึ่งในงานนี้ผมอยากลองสร้าง model ทำนายว่าผู้ทดทองกำลังสนใจไปทางซ้ายหรือทางขวากันแน่ ดังนั้นผมจึงต้องแบบข้อมูลที่ตำแหน่งเลขเกิดทางซ้ายโดย encode เป็น 0 มีจำนวนทั้งหมด 513 trials และทางขวาจะ encode เป็น 1 ซึ่งเพื่อความสะดวกผมจะตัด trials ที่ภาพตัวเลขอยู่ตรงกลางทิ้ง ทำให้ trials ที่ใช้จะเหลือ 1026 จาก 1368 และ features ที่ใช้คู่กับ labels จะลดเหลือขนาด 1026 x 396

ตำแหน่งถูกเอามา encode เป็น 0 (ซ้าย) และ 1 (ขวา) ส่วนตรงกลางถูกตัดทิ้งไม่มาใช้
ข้อมูลที่ถูก encode เพื่อเตรียมสำหรับส่งต่อให้ model train ต่อไป โดย vector Y เป็นตัวเก็บ labels และ matrix X เป็นตัวเก็บ features

โดยก่อนที่จะส่งข้อมูลไป train ต่อ ผมได้ลอง plot ค่าเฉลี่ยของข้อมูลต่างๆโดยแยกประเภทแต่ละ labels ซึ่งพบว่าแม้ตัวกราฟจะคล้ายกันมาก แต่ก็มีจุดเหลื่อมลำ้กันเล็กน้อยซึ่งเชื่อว่าคงส่งให้ machine เรียนรู้ที่จะแยกกลุ่มข้อมูลเหล่านี้ได้ (ซึ่งจะกล่าวต่อไปว่าผมคิดผิดอย่างแรงได้อย่างไรครับ 😞)

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

ต่อไปขั้นตอนสุดท้ายคือส่งข้อมูลเหล่านี้ไปให้ model เรียนรู้ โดยก่อนอื่นต้องแบ่งข้อมูลเป็น 2 ส่วนสำหรับ train และ test โดยสัดส่วน train:test = 80:20 หรือจำนวน trials สัดส่วน 820:206 และแบ่งสัดส่วนแต่ละ label เท่าๆ กัน ทั้งใน test และ train set และนำไปทดสอง classification ทั้ง 4 ตัวได้แก่ logistic regression, support vector machine, k-nearest neighbors และ random forest โดยจะได้ accuracy ทั้งสิ้น 52.43%, 47.09% 50.49% และ 48.06% ตามลำดับ ซึ่งแทบจะเรียกได้ว่าเป็นการสุ่มแบบ random เลย 😭

ผลตารางค่า accuracy และ parameters ที่ใช้ในแต่ละ model รวมถึงรายละเอียดการ train ด้วย โดยปกติ model จะเรียนรู้จาก train set เพื่อให้ได้ accuracy สูงสำหรับการ train นั้นๆ จากน้ำจะเอา model นั้นมาทำนายค่า labels ใน train set เพื่อทดสอบต่อว่า model ยังคงมีประสิทธิภาพกับข้อมูลทั่วไปมากแค่ไหน
เนื่องจาก logistic regression ให้ค่า accuracy สูงสุดจึงได้ถูกนำมายกตัวอย่างรายละเอียดของผลการทดสอบ model เพิ่มเติมนอกจากค่า accuracy

แม้ว่าค่าเฉลี่ยข้อมูลจะมีความเหลื่อมล้ำกันเล็กน้อย แต่ตัว model ได้ถูกทดสอบแล้วว่าไม่สามารถ train ข้อมูลเหล่านี้ได้อย่างมีประสิทธิภาพ ทำให้ผมกลับมาวิเคราะห์ตัวกราฟอีกรอบและเมื่อเราได้นำ error bar ซึ่งคำนวณจาก sd ของแต่ละจุดใส่เข้ามาด้วยก็พบว่าช่วง range ของข้อมูลทับกันแทบจะพอดีเป๊ะ ซึ่งเป็นสาเหตุว่าทำไมแค่ค่าเฉลี่ยอย่างเดียวไม่ได้บอกได้ว่าเราน่าจะ train model สำเร็จไหม

กราฟ features เฉลี่ยของแต่ละ label เมื่อใส่ error bar ซึ่งเป็นค่า sd ใส่เข้ามาด้วย
(ภาพขวา) เมื่อนำ error bar ใส่เข้ามาด้วย จะทำให้เห็นว่า range ของ features ทั้งสอง labels ซ้อนทับกับกันพอดี แม้ว่า (ภาพซ้าย) ตัวค่าเฉลี่ยจะมีส่วนที่เหลื่อล้ำกันบ้าง

โดยสรุปจากโปรเจคนี้ ทำให้ได้เรียนรู้ว่าหากเราไม่สามารถ pre process ข้อมูลให้เหมาะสม จะแทบเป็นไปไม่ได้เลยที่เราจะส่งต่อให้ machine learning สร้าง model อย่างมีประสิทธิภาพ อย่างไรก็ตามในส่วนของงานนี้ แม้เวลาทำ project จะหมดลงแล้ว แต่ก็ยังพอมีแนวทางให้ pre-process ข้อมูลนี้ในรูปแบบอื่นๆได้อีกหลายแบบ เช่น เราอาจกลับมาใช้ time domain มาวิเคราะห์ดู หรือเราอาจลองดู band อื่นๆมาพิจารณาด้วย หรืออาจใช้ตัวแปรทางสถิติของข้อมูลชุดนั้นแทนตัวข้อมูลดิบๆ หรืออาจนับจำนวน peak ของสัญญาณ และอีกหลากหลายวิธีให้ลองเล่นจนกว่าจะสามารถ classified ข้อมูลได้อย่างมีประสิทธิภาพ

แนวทางอนาคตหากแก้ปัญหาเรื่อง pre-process ได้แล้ว ผมอยากลอง labels แกนอื่นบ้างเช่นบนล่าง หรือเอาทั้ง 4 ทิศ บนล่างซ้ายขวา หรือแม้แต่แยกให้ได้ครบ 8 ตำแหน่ง หากสามารถสร้าง model นี้ได้ อาจเป็นจุดเริ่มต้นที่ดีในการพัฒนา brain machine interface for internet of things ในอนาคต

สุดท้ายนี้ขอบคุณโครงการ BrainCode101 ที่ได้เปิดโอกาสให้คนนอกสายได้มาลองทำงานท้าทายสุด cool ของเหล่า neuroscientist (และ data scientist) และดูเหมือนว่ากิจกรรมของโครงการนี้ยังไม่จบแค่นี้ ยังมีโครงการอื่นๆที่กำลังเปิดต่อจากนี้ สำหรับคนที่สนใจอยากลองงานสายนี้ สามารถเข้ามาติดตามข่าวสารโครงการนี้ได้ทางช่องทางเหล่านี้

brainCode101

facebook.com

แล้วมาสนุกด้วยกันนะครับ!! 😈

เก็บตกตอน present

ตอนกำลัง present ว่างานตัวเอง fail มากแค่ไหน 😩
ก่อนปิดโครงการขอใส่หมวกเท่ๆหน่อย 😎
ทีมกรุ๊ป A ครับผม กลุ่มเราเลิกดึกเพราะเพื่อนขยัน 😇 ส่วนผมกินเวลาเพราะ bug ผมเยอะมาก 😵 รอดตายเพราะ skill last week miracle ครับ🤣

--

--