สวัสดีครับ การแข่งขัน Quora Insincere Questions Classification เป็นการแข่งขัน AI ในมุมของ NLP ด้าน text classification ที่กำลังดุเดือด โดย ณเวลาที่ผู้เขียนกำลังเขียนกระทู้นี้ ก็เข้าสู่ช่วงเดือนสุดท้ายของการแข่งขันแล้ว และทีม ThAIKeras เองก็ลงแข่งในงานนี้ด้วย และอยู่ในลำดับที่มีศักยภาพที่จะคว้าเหรียญรางวัลมาได้
จริงๆ แล้วนี่เป็นเหตุผลที่ว่า ทำไม ThAIKeras จึงยังไม่ได้เปิดตัวอย่างจริงจัง (ในอนาคต ถ้าเพื่อนๆ มาพบกระทู้นี้ และบทความในเว็บของเราจะเห็นว่า เอ เขียนมานานก่อนที่เราจะรู้จักเว็บนี้ -- สาเหตุที่เพื่อนๆ หลายๆ คนไม่รู้จักเว็บเราในช่วงแรกเพราะทีมงานมัวแต่แข่ง จึงไม่มีเวลาจัดการเว็บให้สมบูรณ์ครับ แหะๆ)
หลายรูปในกระทู้นี้ ได้รับความอนุเคราะห์จาก Mlwhiz.com ซึ่งเป็นเพื่อนร่วมการแข่งขันครั้งนี้เองครับ
Update (07 / 02 /2019): การแข่งขันจบลงไปแล้วครับ และจะประกาศผลวันที่ 26 กุมภาพันธ์ ซึ่งไม่ว่าผลจะเป็นอย่างไร เราก็ได้ประสบการณ์ที่ล้ำค่าตลอด 3 เดือนที่ผ่านมาครับ --- การแข่งครั้งนี้นั้นมีทีมลงแข่งจากทั่วโลกถึง 4,037 ทีม (ในรูปข้างบนตอนเขียนกระทู้มีราวๆ 3พันทีม) ซึ่งทำให้การแข่งดุเดือด และสู้กันสูสีมากครับ
เกริ่นกันก่อนว่า Quora นี่ก็มาจากเว็บไซต์ถาม-ตอบระดับโลก นั่นก็คือ Quora.com ซึ่งอาจเปรียบเสมือน Pantip.com ของบ้านเรา แต่มีความแตกต่างหลักๆ ตรงที่ส่วนใหญ่จะเป็นการถามตอบปัญหาทางวิชาการ หรือถามตอบเรื่องชีวิตประจำวันแบบจริงจัง (ใน Pantip บางทีอาจมีกระทู้ที่ผู้เขียนแค่อยากหาเพื่อนคุย)
ผู้ที่เข้ามาตอบส่วนใหญ่จะใช้ชื่อจริง นามสกุลจริง และจุดเด่นของ Quora ทีี่ไม่เหมือนที่อื่นก็คือ ผู้รู้ นักวิชาการระดับโลกทั้งหลายมักจะมาตอบคำถามใน Quora ด้วยตนเอง ทำให้คำตอบนั้นมีมนต์ขลังเป็นอย่างมาก
ตัวอย่างในรูปข้างบนก็มี คนมาถามว่าถ้าอยากจะทำงานเป็นนักวิจัย AI โดยเน้นเรื่อง Generative Adversarial Networks (หรือ GANs อันโด่งดัง) ควรจะเรียนปริญญาตรีและปริญญาโทแบบไหนดี
คำถามนี้ก็มี Ian Goodfellows ผู้คิดค้น GANs มาแนะนำด้วยตนเอง
จะมีคำแนะนำไหน วิเศษไปกว่านี้ครับ!?
อธิบายปัญหา แม้จะเป็นเว็บที่เพียบพร้อมไปด้วยปัญญาชนจากทั่วโลก แต่ใน Quora.com เองก็มีการตั้งคำถามที่มีเจตนาไม่ดีแอบแฝงเช่นกัน ซึ่งทาง Quora เรียกกระทู้เหล่านี้ว่า "กระทู้ที่มีเจตนาไม่บริสุทธิ์ใจ" (Insincere Topics) หรือถ้าพูดแบบบ้านๆ ก็คือ "ไม่จริงใจ" หรือคำถามที่มีเจตนาร้ายอยู่เบื้องหลัง
และนี่ก็เป็นที่มาของการแข่งขันครั้งนี้นั่นเอง นั่นก็คือ Quora นั้นท้านักวิจัย AI จากทั่วโลกให้สร้างระบบที่ "คัดกรอง" กระทู้จำพวก Insincere แบบอัตโนมัตินั่นเองครับ
รายละเอียดการแข่งขันครั้งนี้ก็คือ Quora นั้นได้เตรียม "หัวเรื่อง" กระทู้ให้ผู้เข้าแข่งขันทั้งหมดราว 1.3 ล้านกระทู้ โดยแบ่งเป็นกระทู้ที่ Insincere ราวๆ 8หมื่นกระทู้ หรือ 6% ซึ่งเป็นความยากของการแข่งขันครั้งนี้เรื่องนึงก็คือ ประเภทข้อมูล (Sincere vs. Insincere) นั้นมีความไม่สมดุลย์ (Imbalance) เป็นอย่างมาก ซึ่งความ Imbalance นี้เป็น 1 ในปัญหา classic ทางสถิืติและ machine learning มาแต่ยาวนาน
หน้าที่ของเราก็คือให้ AI เรียนรู้จากข้อมูล 1.3 ล้านกระทู้นี้ จนกระทั่งมีความสามารถที่จะคัดกรองหรือจำแนกกระทู้ Insincere ได้ โดยในช่วงแรกจะวัดผลลัพธ์การเรียนรู้โดยให้ AI ของเราทดสอบไปยัง test data จำนวน 5.6 หมื่นกระทู้ ซึ่งผลลัพธ์ความแม่นยำบน 5.6 หมื่นกระทู้นี้จะถูกจัดลำดับใน Public Leaderboard ในช่วง 3 เดือนแรกของการแข่งขันครับ https://www.kaggle.com/c/quora-insincere-questions-classification/leaderboard
และเมื่อสิ้นสุดเวลาการแข่งขััน ทีก่ำหนดไว้ 3 เดือน ทาง Kaggle/Quora ก็จะสับเอา test data 5.6 หมื่นกระทู้นี่ออก แล้วเปลี่ยนเอา test data ชุดใหม่จำนวน 3.5 แสนกระทู้เข้ามาวัดผล AI ของผู้เข้าแข่งขันแทน ซึีงอันดับสุดท้ายหรือ Private Leaderboard จะวัดกันจาก test data ชุดที่สองนี่ครับ
ตัวอย่างกระทู้ Sincere (คัดกรองโดยทีมงาน Quora)
- Is Trump starting a trade war against the whole world?
- Why would any one ask such a dumb question?
- Why does everyone always say im going to have a child when I dont want a girlfriend kr children?
ตัวอย่างประโยค Insincere
- Is there such thing as straight women like, do they exist?
- Why are general category people in Indian are so much against reservation based on caste?
- Is it a good idea to call a complete stranger a cunt on Facebook? What does it say about you if you block them from responding?
จะเห็นว่าบางกระทู้ เราอ่านแล้วก็ไม่แน่ใจว่า sincere หรือไม่ ซึ่งความกำกวมนี้ก็เป็นความยากของการแข่งขันครั้งนี้ครับ นอกจากนี้ความโหดอีกอย่างก็คือ ประโยค insincere มีราวๆ 6% ของข้อมูลทั้งหมดเท่านั้น ซึ่งข้อมูลสอนที่ไม่สมดุลย์อย่างมากนี้ (highly imbalance) ก็ทำให้ปัญหายากขึ้นมากๆ ครับ
Text Classification Problem
ปัญหาคัดกรองกระทู้ว่าเจตนาดีหรือไม่นั้น มองในแง่คณิตศาสตร์ก็คือการสร้างฟังก์ชั่นที่ map จาก sentence space ไปยัง binary space ครับ นั่นคือ
"ประโยคหัวข้อกระทู้" ---> [ฟังก์ชัน] ---> 0/1 (0 = เจตนาดี , 1=เจตนาไม่ดี)
สิ่งที่แตกต่างจากคณิตศาสตร์ทั่วไปที่พวกเราเรียนกันก็คือ sentence space ที่คนทั่วไปอาจไม่คุ้นเคย (ส่วนใหญ่เราใช้งานแค่ Euclidean Space) ซึ่งเราสามารถ map จาก sentence space ไป Euclidean space ได้ด้วยเทคโนโลยี "word embedding" ที่อธิบายในโพสต์ข้างล่างครับ
ปัญหาทำนองนี้จัดอยู่ในปัญหาคลาสสิกของ NLP ที่เรียกว่า "Text Classification" ครับ ซึ่งประยุกต์ใช้งานได้หลากหลาย เช่น
- ทำนายการรีวิวร้านอาหาร หรือโรงแรม ว่า "ชอบ" หรือ "ไม่ชอบ" หรือถ้าให้ละเอียดขึ้นก็ทำนายว่าได้กี่คะแนน (0-5 หรือ 0-10)
- คัดกรองคอมเม้นท์ไม่สุภาพ และอันตรายใน Facebook
- คัดกรองโฆษณาสินค้าต่างๆ ว่าจริงหรือหลอก หรือมีเจตนาแอบแฝงหรือไม่
จะเห็นว่า Text Classifcation มีประโยชน์มากมายเลยครับ ทั้งนี้เพราะมนุษย์เรา "ใช้ชีวิต" กันด้วย "ภาษา" นั่นเอง ดังนั้นการตีความภาษาได้ของ AI จึงสำคัญมากๆ
การแข่งขันรูปแบบพิเศษ -- Kernel Only
การแข่งขัน Quora เพื่อตรวจสอบ insincere topics นี้มีรูปแบบพิเศษคือ โปรแกรม AI จะต้องรันบน Kaggle Kernel เท่านั้น และจำกัดเวลาทำงานไม่เกิน 2 ชั่วโมงในกรณีใช้ GPU ถ้าผิดไปจากนี้ จะไม่สามารถส่งผลการรันเพื่อจัดอันดับในการแข่งขันได้
อนึ่ง ถ้าใช้เฉพาะ CPU จะสามารถทำงานได้ 6 ชั่วโมง แต่อย่างที่เราทราบกันดีว่า GPU นั้นประมวลผล Algorithm deep learning ได้เร็วกว่า CPU นับสิบเท่า ดังนั้น ในการแข่งครั้งนี้ทุกคนจึงใช้ GPU และต้อง optimize program ให้ทำงานเสร็จใน 2 ชั่วโมงครับ
นอกจากนี้ การแข่งขันครั้งนี้ยังไม่อนุญาตให้ใช้ "external data" หรือข้อมูลต่างๆ ใดๆ ที่เราสามารถโหลดจาก internet มาได้ (การแข่งขันส่วนใหญ่ไม่มีข้อจำกัดนี้ ทำให้เราสามารถโหลดข้อมูลหรือโมเดลงานวิจัยล่าสุด ที่เผยแพร่ทางสาธารณะ เข้ามาช่วยในการแก้ปัญหาได้)
อย่างไรก็ดี Quora ได้เตรียม pretrained word embedding vectors ให้เราใช้งานได้ 4 รูปแบบ ซึ่งเป็นหัวใจสำคัญของการแข่งนี้ และเราจะพูดถึงในกระทู้ล่างครับ
การแข่งแบบ Kernel only นี้มีข้อดีอย่างหนึ่งก็คือ ผู้เข้าแข่งขันทุกคนจะมีทรัพยากรประมวลผลที่เท่าเทียมกัน ซึ่งตรงกันข้ามกับการแข่งขันประเภทอื่น เช่น รู้จำภาพ Doodle ที่อนุญาตให้ใช้เครื่องตนเองได้ และผู้ชนะเลิศ (ซึ่งฝีมืออันดับต้นๆ ของโลกอยู่แล้ว) ก็มักจะมีเครื่องประมวลผลที่มีประสิทธิภาพสูงกว่าผู้เข้าแข่งคนอื่นมากนั่นเอง ในการแข่งเหล่านั้นเรียกได้ว่าผู้เข้าแข่งบ้านๆ แทบจะหมดสิทธิไปเลยก็ว่าได้
Plan of Attack
ในการแข่งครั้งนี้ มีกำหนดระยะเวลาสามเดือน ซึ่งทีมงาน ThaiKeras ได้วางแผนเตรียมการเรื่องต่างๆ ดังนี้ครับ
A) จัดการ Data — ทำความเข้าใจข้อมูล / Data Cleaning & preprocessing / Tokenizing
B) ออกแบบ และ ค้นหา Deep Learning Architectures
C) จูน parameters และ hyperparameters ของ architectures
D) ออกแบบวิธีการ Ensemble ของ architectures ที่มีความหลากหลาย
E) ออกแบบวิธีการประเมินความถูกต้องของระบบ หรือ Validation process ที่มีความ robust
F) การวางแผน Series of Experiments และ Improvement Plans
G) การออกแบบกระบวนการ Performance & Error analysis ต่างๆ เพื่อค้นหาทางปรับปรุง
H) การ proactive เพื่อค้นหาไอเดียใหม่ๆ ที่สร้างสรรค์เพิ่มเติมตลอดระยะเวลา 3 เดือน อาทิเช่น Transductive Learning, Pseudo Labelling, Multi-task learning
I) การศึกษาวิธีการ Implementation และ Libraries ต่างๆ ที่จำเป็นทั้ง Keras, Pytorch, Panda, NLTK และ TextBlob
J) จัดเตรียมแผนการทำงาน การประชุม และการผ่อนคลายที่เหมาะสม เนื่องจากการแข่งขัน Kaggle ไม่ใช่การวิ่ง 100 เมตร แต่เป็นการวิ่งมาราธอนที่เราต้องยืนระยะให้ได้ในตลอด 3 เดือน ซึ่งต้องการความสม่ำเสมอ หัวใจนักสู้ และการประเมินสถานการณ์และเปลี่ยนกลยุทธที่สามารถพลิกผันตลอดเวลา (อาทิเช่น มี publish kernel ที่มีนัยยะสำคัญต่อการแข่งขัน)
แหล่งข้อมูลที่สำคัญ
- Public Kernel
- Competition Discussions
- การแข่งขันครั้งก่อนๆ ที่เกี่ยวข้องบน Kaggle เช่น Toxic Classification ของ Jigsaw.ai
- Literatures ที่เกี่ยวข้อง
- Basic Deep Learning & NLP (ลับมีดให้คม)
รู้จัก Word Embedding Vectors
word vectors เป็น 1 ในเทคโนโลยี/งานวิจัย NLP ที่ดีที่สุดในรอบ 10 ปีที่ผ่านมา ซึ่งทางทีมงาน ThaiKeras จะหาเวลาเขียนถึงอย่างละเอียดในโอกาสถัดไปครับ
อธิบายย่อๆ word vectors นั้นเป็นเทคนิกที่เปลี่ยน "คำ" ในภาษามนุษย์ ไปเป็นเวกเตอร์คณิตศาสตร์นั่นเองครับ
แนวคิดนี้ทรงพลังมากครับ คิดเล่นๆ ว่ามนุษย์สื่อสารกันด้วยประโยคสนทนา ซึ่งประโยคก็ประกอบไปด้วยคำต่างๆ ดังนั้นถ้าเราสามารถเปลี่ยน "คำ" ไปเป็นเวกเตอร์ได้แล้ว เราก็สามารถเปลี่ยน "ประโยค" ให้เป็นคณิตศาสตร์ได้
เมื่อเรา "ย้าย" ภาษามนุษย์ให้อยู่ในรูปคณิตศาสตร์ได้แล้ว การแก้ปัญหาต่างๆ ด้านภาษา หรืองานด้าน NLP ซึ่งเป็นหนึ่งในความท้าทายที่ยากที่สุดสำหรับ AI ซึ่งปกติเราต้องแก้ด้วยความรู้ด้านไวยากรณ์ หรือความรู้ด้านภาษาศาสตร์ ก็จะเปลี่ยนแปลงไปทั้งหมด เพราะเมื่อย้ายประโยคเข้ามาอยู่ในรูปเวกเตอร์แล้ว เรามีเครื่องมือที่ทรงพลังทางคณิตศาสตร์มากมาย ไม่ว่าจะเป็น Algebra, Calculus หรือ Geometry เพื่อแก้ปัญหา NLP นั่นเอง
แนวคิดนี้ปฏิวัติวงการ NLP อย่างมีนัยสำคัญในช่วง 10 ปีที่ผ่านมา และงานวิจัยด้าน NLP ล่าสุดจาก Google, Facebook, หรือมหาลัยชั้นนำต่างก็มีไอเดียพื้นฐานจาก word vectors ทั้งสิ้น
pretrained word vectors ที่ Quora เตรียมไว้ให้นี้จะเปลี่ยน "คำ" ต่างๆในภาษามนุษย์เป็นเวกเตอร์ 300มิติบน Euclidean space (ตัวเลข 300 มิตินี่เกิดจากการทดลองที่ใช้งานได้ดี ในการเขียนโปรแกรม เรามักจะกำหนด constant EMBED_DIM = 300 ไว้แทนตัวเลขนี้ครับ)
คำสองคำใดๆ ที่มนุษย์ใช้ในความหมายที่ใกล้เคียงกัน เวกเตอร์ของสองคำนี้ก็จะมี Euclidean distance ที่ใกล้กันไปด้วย
คุณสมบัติมหัศจรรย์ที่ได้รับการกล่าวถึงบ่อยที่สุดก็คือ การนำ operator + และ - มาใช้กับ word vectors เหล่านี้มักจะได้ผลลัพธ์ที่น่าตื่นตะลึงยิ่ง เช่น
พระราชา - ผู้ชาย + ผู้หญิง จะได้คำตอบคือ "พระราชินี"!
กรุงเทพ - ไทย + อังกฤษ จะได้คำตอบคือ "ลอนดอน"!
ขอขอบคุณภาพสวยๆ จาก mlwhiz.com ครับ
ในปัจจุบันมี pretrained word vectors ให้เราเลือกใช้มากมาย และในการแข่งครั้งนี้ Kaggle และ Quora อนุญาตให้เราใช้ Pretrained word vectors ได้ 4 กลุ่มครับ คือ
1) Word2Vec ของ Google 2) GloVe ของ Stanford 3) FastText ของ Facebook และ 4) Paragram ของ Toyota Tech Institute of Chicago
การ clean data เบื้องต้น
หลายๆ คนอาจจะจินตนาการว่าการทำงาน AI หรือ Deep Learning คือการออกแบบ Neural Networks สวยๆ ยิ่งใหญ่ แล้วเรานำข้อมูล training data เข้าไป ..... ตูม!! .... Neural networks ก็จะเรียนรู้ข้อมูลทั้งหมดแบบอัตโนมัติ และมีความฉลาดตามที่เราต้องการง่ายๆ เลย
จริงๆ แล้วขั้นตอนที่กินเวลามากที่สุด โดยที่อาจจะยังไม่เกี่ยวกับการออกแบบ Neural Network Architecture สวยๆ เลยก็คือ การที่เราต้องมาจัดการข้อมูลให้เรียบร้อยก่อน หรือที่เรียกกันว่า data cleaning นั่นเองครับ และผลแพ้ชนะในการแข่งขันบางทีอาจจะวัดกันที่ความละเอียดอ่อนในการ clean data ของแต่ละทีมก็เป็นได้
Training data ของเรานั้นประกอบไปด้วยกระทู้ราว 1.3ล้านกระทู้ โดยในแต่ละกระทู้นั้น ข้อมูลจะประกอบไปด้วย "ประโยคหัวข้อกระทู้" (ไม่มีรายละเอียดอื่น) ซึ่งจากประโยคภาษาอังกฤษนี้เราจะต้องตัดประโยคเพื่อแบ่งเป็น "list ของ คำ"
เช่นประโยค “Why Donald TRUMP is able to win an election on 2016?”
ต้องถูก process เป็น [“Why”, “Donald”, “TRUMP”, “is”, “able”, “to”, “win”, “an”, “election” “on” “2016?”]
ในกรณีที่ง่ายที่สุด เราสามารถนำคำแต่ละคำใน list นี้ไปหา query เพื่อหา word vector ที่ต้องการได้เลย โดยคำต่างๆ ที่ไม่มีในพจนานุกรมของ pretrained embedders ก็จะถูกนำออกไป หรือว่าถูกแทนด้วย random vector ครับ
ในทางปฏิบัตินั้น ถ้าเราต้องการประสิทธิภาพที่ดี เราต้องลงรายละเอียดมากขึ้นหน่อย โดย ต่อไปนี้เป็นเรื่องที่ควรพิจารณาในการทำความสะอาดข้อมูล
1) เปลี่ยนจาก upper case เป็น lower case (เปลี่ยนอักษรพิมพ์ใหญ่ เป็นพิมพ์เล็ก) ทั้งนี้เพื่อเป็นการลดจำนวนคำศัพท์ (แทนที่จะจำ Why/why กับ TRUMP/trump เป็นคนละคำ) และถ้าเราเห็นว่าตัวพิมพ์ใหญ่ไม่ได้มีประโยชน์อะไรในการทำนาย ซึ่งสมมติฐานนี้อาจจะไม่จริงในบางปัญหา ดังนั้นเราต้องพิจารณาหรือทดสอบสมมติฐานอย่างรอบคอบ
2) ตัดคำให้ถูกต้อง เช่น “2016?” อาจจะเกิดจากการพิมพ์ผิด (ลืมเคาะช่องว่าง) เป็น “2016”, “?”
3) process ตัวเลข เนื่องจากตัวเลขมีมากมายเหลือเกิน และเราอาจไม่มี word embedding ทุกจำนวน เราอาจเปลี่ยนตัวเลขทั้งหมดเป็น “1” เช่น “2016” —> “1” ทั้งนี้ การกระทำเช่นนี้มีทั้งข้อดีและข้อเสีย โดยข้อดีคือ ตัวเลขที่ไม่มีใน pretrained word vectors ก็จะถูกแทนที่ด้วย “1” ซึ่งอย่างน้อยก็มีความหมายในเชิงตัวเลข ส่วนข้อเสียก็คือ ตัวเลขเช่น “2” หรือ “100” ซึ่งอาจจะมีการใช้งานแตกต่างจาก “1” ก็จะสูญเสีย information ไป
4) ตัดตัวอักษรพิเศษทิ้งไป เช่น “?” เปลี่ยนเป็น “” (null string)
5) ตัด stop words หรือ กลุ่มคำที่ปรากฏบ่อย และไม่น่าจะช่วยให้การทำนายถูกต้องได้มากขึ้น เช่น “an” หรือคำอื่นๆ เช่น “to” “on” ก็อาจจะเข้าข่าย โดย stop words คำไหนควรตัดไม่ควรตัด เราอาจต้องไปทำการทดลองเพื่อทดสอบสมมติฐานอีกครั้ง
6) อื่นๆ เช่น - เดาคำที่สะกดผิดว่าควรสะกดถูกอย่างไร. (เช่น Drump --> Trump สามารถทำได้โดยใช้ Levenstein Distance : https://www.python-course.eu/levenshtein_distance.php)
- ตัด latex tag เนื่องจาก Quora มีการมาถามปัญหาคณิตศาสตร์กันมากและมักมี latex equations อยู่มากมาย (ซึ่ง word embedding ไม่สามารถตีความได้) เราจึงอาจจะตัดทุกคำภายใต้ \( ... \) ออกทั้งหมดหรือเปลี่ยนเป็นวลีสั้นๆ เช่น ["mathematical","equation"]
ตัวอย่างโค้ด Python ที่ใช้เว้นวรรคอักขระพิเศษออกมาจาก word ทั่วๆ ไปครับ ซึ่งในการแข่งนี้เพื่อความง่ายเรา hard code อักขระพิเศษทั้งหลายตรงๆ และเก็บไว้ใน list ที่มีชื่อว่า puncts (ย่อมาจาก punctuations) แล้วก็วนลูปไล่เช็คทุกอักขระพิเศษ ในทุกกระทู้ตรงๆ เลย สำหรับโค้ด pre-process อื่นๆ ก็เขียนในลักษณะคล้ายๆ กัน รอดูได้ใน notebook ฉบับเต็มครับ
# Some preprocesssing that will be common to all the text classification methods you will see. puncts = [',', '.', '"', ':', ')', '(', '-', '!', '?', '|', ';', "'", '$', '&', '/', '[', ']', '>', '%', '=', '#', '*', '+', '\\', '•', '~', '@', '£', '·', '_', '{', '}', '©', '^', '®', '`', '<', '→', '°', '€', '™', '›', '♥', '←', '×', '§', '″', '′', 'Â', '█', '½', 'à', '…', '“', '★', '”', '–', '●', 'â', '►', '−', '¢', '²', '¬', '░', '¶', '↑', '±', '¿', '▾', '═', '¦', '║', '―', '¥', '▓', '—', '‹', '─', '▒', ':', '¼', '⊕', '▼', '†', '■', '’', '▀', '¨', '▄', '♫', '☆', 'é', '¯', '♦', '¤', '▲', 'è', '¸', '¾', 'Ã', '⋅', '‘', '∞', '∙', ')', '↓', '、', '│', '(', '»', ',', '♪', '╩', '╚', '³', '・', '╦', '╣', '╔', '╗', '▬', 'ï', 'Ø', '¹', '≤', '‡', '√', ] def clean_text(x): x = str(x) for punct in puncts: if punct in x: x = x.replace(punct, f' {punct} ') return x