Text Analysis ใน Elasticsearch

Mart — Tanathip Viriya
3 min readDec 18, 2020

--

Text analysis เป็นวิธีการอย่างนึงของ Elasticsearch ที่ช่วยให้เราสามารถทําการ Full text search ได้ โดยผลลัพธ์ที่ออกมาจะได้ใกล้เคียงกับสิ่งที่เราค้นหามากกว่าการทําเทียบ word by word

ตัวอย่างเช่น ถ้าเรามีกล่องค้นหาในเว็ปไซต์ เขียนโค้ดด้วย SQL statement เราอาจจะใช้สิ่งที่เรียกว่า wildcard ในการค้นหา ซึ่งหน้าตาจะออกมาเป็น

SELECT * FROM WebContent WHERE header like ‘%search%’

ซึ่งวิธีแบบนี้จะไม่สามารถทําให้เราทําการค้นหาได้อย่างมีประสิทธิภาพ เช่นถ้า User ค้นหาด้วยคําว่า best thai food in bangkok เพื่อหาร้านอาหารไทยในระบบ แต่ใน WebContent ที่เราเก็บข้อมูลไว้เราเก็บเป็น Best thai restaurants in Bangkok แค่นี้ก็จะไม่สามารถค้นหาเจอได้แล้ว (context เดียวกัน)

นั้นเป็นเลยสิ่งที่ Text Analysis เข้ามาช่วยแก้ปัญหาในส่วนนี้ ใน Elasticsearch เราจะมีขบวนการที่เรียกว่า

  • Tokenization ที่ทําหน้าที่ในการแบ่งคําออกมาเป็น chunks หรือเรียกว่า tokens โดยปกติแล้วให้นึกถึงการแบ่งคําแบบ วลี (Phrase) ลงมาเป็น คําๆ (Word)
  • Normalization ถึงแม้ Phrase จะกลายเป็น Word แล้ว แต่ในภาษามันมีหลายสิ่งที่มีความหมายเดียวกันเช่น QUICK และ quick จริงๆมันคือคําเดียวกันแค่เป็นตัวอักษรใหญ่และเล็ก หรือ fox และ foxes ซึ่งมันก็คือ หมาจิ้งจอกนั้นแหละ ดังนั้นหลังจากการ Tokenization แล้วการ Normalization ของคําก็เลยเป็นสิ่งที่จําเป็นมาก

โดยตัวอย่างรูปด้านล่างเป็นตัวอย่างการทํา text analysis ด้วย phrase ว่า “The QUICK brown foxes jumped over the Dog!”

The main concept of ES Text Analysis

Analyzer ตัวหลักของ Text Analysis

ทีนี้การทํางานของ Text Analysis มันขึ้นอยู่กับสิ่งที่เรียกว่า Analyzer ซึ่งเจ้า Analyzer คือเป็นตัวหลักในการจัดการดังภาพข้างบน โดยเราจะสามารถแบ่งออกเป็น 3 ส่วนคือ

  • Character Filters ทําหน้าที่รับ text/pharse เข้ามาแล้ว เพิ่ม,ลด,หรือเปลี่ยน character ออกเป็นส่วนๆๆ เช่น รับภาษา Hindu-Arabic numerals (٠‎١٢٣٤٥٦٧٨‎٩‎) แล้วแปลงเป็น Arabic-Latin equivalents (0123456789) เป็นต้น โดยสามารถมี Charcter filters ใช้หลายตัวพร้อมกันได้ตามลําดับ
  • Tokenizer หลังจากนั้นพอได้ stream ของ character แล้วเจ้า Tokenizer ก็จะทําการแบ่งออกมาเป็น tokens (words) นั้นเอง โดยนอกจากแบ่งคําแล้วยังทําหน้าที่จัด order และ ตําแหน่งของคําด้วย เช่นลําดับของคําที่เข้ามา
  • Token Filters ทีนี้หลังจากแบ่งคํา จัดออเดอร์แล้วสิ่งต่อไปก็คือ Filter นั้นเอง ในขั้นนี้ตัว analyzer จะสามารถเพิ่มหรือลด filter เข้าไปในขั้นตอนเพื่อให้มันทํางานได้อย่างมีประสิทธิ์ภาพมากขึ้น เช่น ถ้าเราแบ่งคําออกมาเป็น Quick แล้วต้องการให้มันเป็น quick เราก็เพิ่ม lowercase token filter เข้าไป ซึ่งเราสามารถตั้งให้ใช้งานหลายๆตัวได้นั้นเอง

แล้ว Text Analysis ทํางานตอนไหนบ้างละ?

คําตอบคือ 2 ครั้ง นั้นก็คือตอน

  • เก็บ Index
  • และตอน Search

เพราะการจะทํา Text Analysis ที่ดีได้มันต้องเริ่มตั้งแต่ตอนเก็บ document เพื่อทํา indexed เลยละ เช่น Phrase

The QUICK brown foxes jumped over the dog!

ถ้าเราไม่ทํา Text Analysis มีหวังมันได้เก็บ single string แบบนี้แน่ๆๆ ดังนั้นมันเลยต้องผ่าน Index Analyzer ซึ่งจะทําการ Tokens และ Normalize ลงมาเป็น

[ quick, brown, fox, jump, over, dog ]

แล้วค่อย Indexed ลงไปใน ES ดังนั้นเวลาที่มีใครมา Search เจ้า ES ก็ค่อยเอา Phrase นะผ่าน Search Analyzer อีกที เช่นมีคนค้นหา

“Quick fox”

มันก็จะถูกแปลงไปเป็น

[quick, fox]

ดังนั้นเวลาเอาไปเทียบกับ document indexed (text filed) ก็จะเจอประโยคของ

The QUICK brown foxes jumped over the dog!

ที่ได้ทําการ indexed ไว้แล้วในรูปแบบ Tokens และ Normalized นั้นเอง!

นอกจากนั้นยังมีหลักการอื่นๆเพิ่มเติมคือ

  • Stemming ที่เป็นการทําหน้าที่ลดรูปของคําให้อยู่ในรูปแบบของ Root form เช่น Walking และ Walked คือมาจาก root word ที่เรียกว่า Walk ดังนั้นมันต้องถูกลดรูปให้เหลือ Walk นั้นเอง
  • Token graphs ที่เป็นคัวจัดการ ตําแหน่งและลําดับของคํา ถ้ายังจําได้นี่คือสิ่งที่อ้างอิงถึงใน Tokenizer concept ของ Analyzer นั้นเอง

Stemming

การลดรูปของ Stemming ง่ายมาก มันมีสองวิธีคือ

  • Algorithmic Stemmers คือเราสร้าง Rules ขึ้นมาเองเพื่อลดรูปของภาษาเช่น เจอ prefix ที่เป็น -s หรือ -es ให้ลดรูปหรือตัดพวกนั้นออกไปเป็นต้น ซึ่งจะทํางานได้ค่อนข้างเร็วเพราะมันเป็นอะไรที่เรา specific ไปแล้วว่าเราต้องการอะไร
  • Dictionary Stemmers ในทางกลับกันถ้าเราไม่อยากสร้าง Rules ขึ้นมาเอง เราก็มีหลักการณ์ของเทียบเลย เทียบใน Dictionary ว่ามีคําไหนบ้าง แล้วเอามาลดรูปออกไปตาม Dictionary นั้นๆๆ ซึ่งวิธีนี้นะมันทําให้ช้าหน่อยแต่คลอบคลุมทุกคําแน่นอน

Token Graphs

มันไว้จัดการ order และ position ของคํา แต่คําถามว่ามันทําไปเพื่ออะไร?

จริงๆแล้วการเรียงลําดับของคําและสร้าง graph สามารถทําให้เราใช้ประโยชน์ของการทํา Token Filter เข้ามาได้ด้วย เช่น ประโยคของ

quick brown fox

เมื่อเรามาเลียงลําดับลง Token Graphs จะได้รูปตามด้านล่างนี้

หลังจากนั้น Token Filter ใน Analyzer บางตัวสามารถนํามาใช้ประโยชน์จากมันได้

Synonyms

คําระหว่าง quick และ fast ความหมายเดียวกันเป็นต้น

Multi-position tokens

หรือ token filter บางตัวสามารถรวบเป็น multi-word synonyms ได้ แบบด้านล่าง domain name system ซึ่งมี abbreviation ว่า dns นั้นเอง

โดยการเก็บของ token graph จะมีสองส่วนหลักๆคือ

  • position ของ token แต่ละตัวใน stream
  • positionLength ตัวเลขของ position ที่ token span ออกไป (แบบตัวอย่างของ dns ที่มัน span ออกมา 3 token นั้นเอง)

References infomation

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis.html

--

--