Python ตัดคำภาษาไทย ด้วย PyThaiNLP API ตัดคำ Word Tokenize ภาษาไทย ตัวอย่างการตัดคำภาษาไทย อัลกอริทึม deepcut, newmm, longest, pyicu, attacut – PyThaiNLP ep.2
ใน ep นี้เราจะมาเรียนรู้ หนึ่งในงาน NLP ภาษาไทย ที่เป็นที่ต้องการมากที่สุด เนื่องจากภาษาไทย เป็นภาษาที่เขียนติดกันหมด ไม่มีการเว้นคำด้วย Space เหมือนภาษาอังกฤษ ทำให้การตัดคำภาษาไทย หรือ Tokenization มีความซับซ้อน และ การตัดคำที่ถูกต้องมีความสำคัญ ต่อการนำข้อมูลคำศัพท์ ไปประมวลผลต่อ เช่น Feed เข้าโมเดล Machine Learning, Deep Learning ต่อไป
ตัวอย่างการตัดคำภาษาไทย
Copy 'จัง|หวัด|เชียง|ราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|'
PyThaiNLP ฟังก์ชัน word_tokenize
API ฟังก์ชันตัดคำของ PyThaiNLP ถูกออกแบบมาให้รองรับการตัดคำ Word, Sentence หลายอัลกอริทึม เช่น
newmm – Dictionary-based Thai Word Segmentation using maximal matching algorithm and Thai Character Cluster (TCC). The code is based on the notebooks created by Korakot Chaovavanich.
longest – Dictionary-based longest-matching Thai word segmentation. Implementation based on the code from Patorn Utenpattanun.
multi_cut – Multi cut – Thai word segmentation with maximum matching. The original source code is from Korakot Chaovavanich.
pyicu – Wrapper for PyICU word segmentation. This wrapper module uses icu.BreakIterator with Thai as icu.Local to locate boundaries between words from the text.
deepcut – Wrapper for deepcut Thai word segmentation. deepcut is a Thai word segmentation library using Deep Neural, specifically, 1D Convolution Neural Network.
attacut – Wrapper for AttaCut – Fast and Reasonably Accurate Word Tokenizer for Thai by Pattarawat Chormai
tcc – The implementation of tokenizer according to Thai Character Clusters (TCCs) rules purposed by Theeramunkong et al. 2000.
etcc – Enhanced Thai Character Cluster (ETCC) Python implementation by Wannaphong Phatthiyaphaibun (19 June 2017)
โดยอัลกอริทึมใหม่ล่าสุด และเป็น Default ของ PyThaiNLP tokenize ณ ขณะนี้ คือ newmm ที่ใช้ อัลกอริทึม หา maximum matching จากใน Dictionary ที่ทำงานได้อย่างรวดเร็ว และถูกต้อง
เรามาเริ่มกันเลยดีกว่า
Check it out on github Last updated: 02/07/2020 11:16:12
เนื่องจากภาษาไทย เป็นภาษาที่เขียนติดกันหมด ไม่มีการเว้นคำด้วย Space เหมือนภาษาอังกฤษ ทำให้การตัดคำภาษาไทย หรือ Tokenization มีความซับซ้อน และ การตัดคำที่ถูกต้องมีความสำคัญ ต่อการนำข้อมูลคำศัพท์ ไปประมวลผลต่อ เช่น Feed เข้าโมเดล Machine Learning ต่อไป
0. Install
In [0]:
Copy % reload_ext autoreload
% autoreload 2
% matplotlib inline
Install Library ที่จำเป็น แล้ว Restart RuntimeIn [2]:
Copy try :
% tensorflow_version 2. x
except :
pass
Copy TensorFlow 2.x selected.
In [0]:
Copy # dev version
# !pip install https://github.com/PyThaiNLP/pythainlp/archive/dev.zip
# release version
! pip install pythainlp
!pip install epitran
!pip install sklearn_crfsuite
!pip install tensorflow deepcut
!pip install attacut
Restart Runtime เพื่อให้ใช้ Library เวอร์ชัน ที่เพิ่ง Install ลงไป
ในเคสนี้ เราจะปิด Warning ไว้ก่อน จะได้อ่านผลลัพท์ง่ายIn [0]:
Copy import warnings
warnings . filterwarnings ( 'ignore' )
1. Import
Import Library ที่จะใช้ ในที่นี้คือ PyThaiNLPIn [5]:
Copy import pythainlp
pythainlp . __version__
Out[5]:
2. PyThaiNLP ตัดคำภาษาไทย
2.1 word_tokenize ตัดคำ Word, Sentence
ฟังก์ชันตัดคำของ PyThaiNLP ถูกออกแบบมาให้รองรับหลายอัลกอริทึม เช่น
newmm - Dictionary-based Thai Word Segmentation using maximal matching algorithm and Thai Character Cluster (TCC). The code is based on the notebooks created by Korakot Chaovavanich.
longest - Dictionary-based longest-matching Thai word segmentation. Implementation based on the code from Patorn Utenpattanun.
multi_cut - Multi cut – Thai word segmentation with maximum matching. The original source code is from Korakot Chaovavanich.
pyicu - Wrapper for PyICU word segmentation. This wrapper module uses icu.BreakIterator with Thai as icu.Local to locate boundaries between words from the text.
deepcut - Wrapper for deepcut Thai word segmentation. deepcut is a Thai word segmentation library using Deep Neural, specifically, 1D Convolution Neural Network.
attacut - Wrapper for AttaCut - Fast and Reasonably Accurate Word Tokenizer for Thai by Pattarawat Chormai
tcc - The implementation of tokenizer accorinding to Thai Character Clusters (TCCs) rules purposed by Theeramunkong et al. 2000.
etcc - Enhanced Thai Character Cluster (ETCC) Python implementation by Wannaphong Phatthiyaphaibun (19 June 2017)
โดยอัลกอริทึมใหม่ล่าสุด และเป็น Default ของ PyThaiNLP tokenize ณ ขณะนี้ คือ newmm ที่ใช้ อัลกอริทึม หา maximum matching จากใน Dictionary ที่ทำงานได้อย่างรวดเร็ว และถูกต้องพอสมควร
เราจะ Import sent_tokenize ที่ตัดคำจาก Space, Full stop, New line เหมือนที่ใช้ในภาษาอังกฤษ และ word_tokenize พระเอกของเรา ฟังก์ชันตัดคำภาษาไทยIn [0]:
Copy from pythainlp import sent_tokenize , word_tokenize
In [0]:
Copy text = "เมืองเชียงรายมีประวัติศาสตร์อันยาวนาน เป็นที่ตั้งของหิรัญนครเงินยางเชียงแสน"
In [8]:
Copy print ( "sent_tokenize:" , sent_tokenize (text))
print ( "word_tokenize:" , word_tokenize (text))
print ( "no whitespace:" , word_tokenize (text, keep_whitespace = False ))
Copy sent_tokenize: ['เมืองเชียงรายมีประวัติศาสตร์อันยาวนาน', 'เป็นที่ตั้งของหิรัญนครเงินยางเชียงแสน']
word_tokenize: ['เมือง', 'เชียงราย', 'มี', 'ประวัติศาสตร์', 'อัน', 'ยาวนาน', ' ', 'เป็นที่ตั้ง', 'ของ', 'หิรัญ', 'นคร', 'เงิน', 'ยาง', 'เชียงแสน']
no whitespace: ['เมือง', 'เชียงราย', 'มี', 'ประวัติศาสตร์', 'อัน', 'ยาวนาน', 'เป็นที่ตั้ง', 'ของ', 'หิรัญ', 'นคร', 'เงิน', 'ยาง', 'เชียงแสน']
2.2 เปรียบเทียบตัดคำภาษาไทย ด้วยอัลกอริทึมต่าง ๆ
In [0]:
Copy text = "งานเทศกาลลิ้นจี่และของดีเมืองเชียงราย เทศกาลที่ชาวเกษตรกรต่างนำผลผลิตทางการเกษตรของตนมาออกร้าน โดยเฉพาะลิ้นจี่ที่มีชื่อเสียงมากของเชียงราย "
In [10]:
Copy print ( "newmm :" , word_tokenize (text)) # default engine is "newmm"
print ( "longest :" , word_tokenize (text, engine = "longest" ))
print ( "multi_cut:" , word_tokenize (text, engine = "multi_cut" ))
print ( "pyicu :" , word_tokenize (text, engine = "pyicu" ))
print ( "deepcut :" , word_tokenize (text, engine = "deepcut" ))
print ( "tcc :" , word_tokenize (text, engine = "tcc" ))
print ( "etcc :" , word_tokenize (text, engine = "etcc" ))
print ( "ulmfit :" , word_tokenize (text, engine = "ulmfit" ))
Copy newmm : ['งานเทศกาล', 'ลิ้นจี่', 'และ', 'ของดี', 'เมือง', 'เชียงราย', ' ', 'เทศกาล', 'ที่', 'ชาว', 'เกษตรกร', 'ต่าง', 'นำ', 'ผลผลิต', 'ทาง', 'การเกษตร', 'ของ', 'ตน', 'มา', 'ออกร้าน', ' ', 'โดยเฉพาะ', 'ลิ้นจี่', 'ที่', 'มีชื่อเสียง', 'มาก', 'ของ', 'เชียงราย', ' ']
longest : ['งานเทศกาล', 'ลิ้นจี่', 'และ', 'ของดี', 'เมือง', 'เชียงราย', ' ', 'เทศกาล', 'ที่', 'ชาว', 'เกษตรกร', 'ต่าง', 'นำ', 'ผลผลิต', 'ทางการ', 'เกษตร', 'ของ', 'ตน', 'มา', 'ออกร้าน', ' ', 'โดยเฉพาะ', 'ลิ้นจี่', 'ที่', 'มีชื่อเสียง', 'มาก', 'ของ', 'เชียงราย', ' ']
multi_cut: ['งานเทศกาล', 'ลิ้นจี่', 'และ', 'ของดี', 'เมือง', 'เชียงราย', ' ', 'เทศกาล', 'ที่', 'ชาว', 'เกษตรกร', 'ต่าง', 'นำ', 'ผลผลิต', 'ทางการเกษตร', 'ของ', 'ตน', 'มา', 'ออกร้าน', ' ', 'โดยเฉพาะ', 'ลิ้นจี่', 'ที่', 'มีชื่อเสียงมาก', 'ของ', 'เชียงราย', ' ']
pyicu : ['งานเทศกาล', 'ลิ้นจี่', 'และ', 'ของดี', 'เมือง', 'เชียงราย', ' ', 'เทศกาล', 'ที่', 'ชาว', 'เกษตรกร', 'ต่าง', 'นำ', 'ผลผลิต', 'ทาง', 'การเกษตร', 'ของ', 'ตน', 'มา', 'ออกร้าน', ' ', 'โดยเฉพาะ', 'ลิ้นจี่', 'ที่', 'มีชื่อเสียง', 'มาก', 'ของ', 'เชียงราย', ' ']
deepcut : ['งาน', 'เทศกาล', 'ลิ้นจี่', 'และ', 'ของ', 'ดี', 'เมืองเชียงราย', ' ', 'เทศกาล', 'ที่', 'ชาว', 'เกษตรกร', 'ต่าง', 'นำ', 'ผล', 'ผลิต', 'ทาง', 'การ', 'เกษตร', 'ของ', 'ตน', 'มา', 'ออก', 'ร้าน', ' ', 'โดย', 'เฉพาะ', 'ลิ้นจี่', 'ที่', 'มี', 'ชื่อเสียง', 'มาก', 'ของ', 'เชียงราย', ' ']
tcc : ['งานเทศกาล', 'ลิ้นจี่', 'และ', 'ของดี', 'เมือง', 'เชียงราย', ' ', 'เทศกาล', 'ที่', 'ชาว', 'เกษตรกร', 'ต่าง', 'นำ', 'ผลผลิต', 'ทาง', 'การเกษตร', 'ของ', 'ตน', 'มา', 'ออกร้าน', ' ', 'โดยเฉพาะ', 'ลิ้นจี่', 'ที่', 'มีชื่อเสียง', 'มาก', 'ของ', 'เชียงราย', ' ']
etcc : ['งานเทศกาล', 'ลิ้นจี่', 'และ', 'ของดี', 'เมือง', 'เชียงราย', ' ', 'เทศกาล', 'ที่', 'ชาว', 'เกษตรกร', 'ต่าง', 'นำ', 'ผลผลิต', 'ทาง', 'การเกษตร', 'ของ', 'ตน', 'มา', 'ออกร้าน', ' ', 'โดยเฉพาะ', 'ลิ้นจี่', 'ที่', 'มีชื่อเสียง', 'มาก', 'ของ', 'เชียงราย', ' ']
ulmfit : ['งานเทศกาล', 'ลิ้นจี่', 'และ', 'ของดี', 'เมือง', 'เชียงราย', ' ', 'เทศกาล', 'ที่', 'ชาว', 'เกษตรกร', 'ต่าง', 'นำ', 'ผลผลิต', 'ทาง', 'การเกษตร', 'ของ', 'ตน', 'มา', 'ออกร้าน', ' ', 'โดยเฉพาะ', 'ลิ้นจี่', 'ที่', 'มีชื่อเสียง', 'มาก', 'ของ', 'เชียงราย', ' ']
2.3 เพิ่มคำใน Dictionary
ในกรณีที่ข้อความของเรา มีคำแปลก ๆ ที่ไม่มีใน Dictionary ทั่วไป เราสามารถเพิ่มคำเหล่านั้น เข้าไปใน Dictionary ที่ใช้ตัดคำได้ดังตัวอย่างด้านล่าง
หรือเราจะสร้าง Dictionary ของเราเองจาก set()
ว่าง ตั้งแต่ต้นเลยก็ได้In [0]:
Copy # Tokenizer??
# thai_words??
In [12]:
Copy from pythainlp import word_tokenize , Tokenizer
from pythainlp . tokenize import dict_trie
from pythainlp . corpus . common import thai_words
text = "เป็งปุ๊ด หรือ เพ็ญพุธ เป็นประเพณีตักบาตรเที่ยงคืนค่อนรุ่งเข้าสู่วันเพ็ญขึ้น15 ค่ำที่ตรงกับวันพุธ ตามวัฒนธรรมและความเชื่อของบรรพบุรุษล้านนาไทย"
print ( "newmm :" , word_tokenize (text)) # default engine is "newmm"
print ( "longest:" , word_tokenize (text, engine = "longest" ))
words = [ "เป็งปุ๊ด" , "เพ็ญพุธ" ]
custom_words_list = set ( thai_words ())
## add multiple words
custom_words_list . update (words)
## add word
# custom_words_list.add('เป็งปุ๊ด')
# custom_words_list.add('เพ็ญพุธ')
trie = dict_trie (dict_source = custom_words_list)
custom_tokenizer = Tokenizer (custom_dict = trie, engine = 'newmm' )
print ( "custom :" , custom_tokenizer. word_tokenize (text))
Copy newmm : ['เป็ง', 'ปุ๊', 'ด', ' ', 'หรือ', ' ', 'เพ็ญ', 'พุธ', ' ', 'เป็น', 'ประเพณี', 'ตักบาตร', 'เที่ยงคืน', 'ค่อน', 'รุ่ง', 'เข้าสู่', 'วันเพ็ญ', 'ขึ้น', '15', ' ', 'ค่ำ', 'ที่', 'ตรง', 'กับ', 'วัน', 'พุธ', ' ', 'ตาม', 'วัฒนธรรม', 'และ', 'ความเชื่อ', 'ของ', 'บรรพบุรุษ', 'ล้านนา', 'ไทย']
longest: ['เป็ง', 'ปุ๊', 'ด', ' ', 'หรือ', ' ', 'เพ็ญ', 'พุธ', ' ', 'เป็น', 'ประเพณี', 'ตักบาตร', 'เที่ยงคืน', 'ค่อน', 'รุ่ง', 'เข้าสู่', 'วันเพ็ญ', 'ขึ้น', '15', ' ', 'ค่ำ', 'ที่', 'ตรง', 'กับ', 'วัน', 'พุธ', ' ', 'ตาม', 'วัฒนธรรม', 'และ', 'ความเชื่อ', 'ของ', 'บรรพบุรุษ', 'ล้านนา', 'ไทย']
custom : ['เป็งปุ๊ด', ' ', 'หรือ', ' ', 'เพ็ญพุธ', ' ', 'เป็น', 'ประเพณี', 'ตักบาตร', 'เที่ยงคืน', 'ค่อน', 'รุ่ง', 'เข้าสู่', 'วันเพ็ญ', 'ขึ้น', '15', ' ', 'ค่ำ', 'ที่', 'ตรง', 'กับ', 'วัน', 'พุธ', ' ', 'ตาม', 'วัฒนธรรม', 'และ', 'ความเชื่อ', 'ของ', 'บรรพบุรุษ', 'ล้านนา', 'ไทย']
2.4 Performance
ในการใช้งานจริง ความเร็วในการตัดคำก็เป็นเรื่องสำคัญ ยิ่งถ้าเรามีข้อมูลขนาดใหญ่ Streaming เข้ามา ฟังก์ชันตัดคำเป็นด่านแรกที่ต้องทำงานให้ทัน โดยเฉพาะอย่างยิ่งกับงานที่ Online Real-timeIn [0]:
Copy speedtest_text = """
เมืองเชียงรายมีประวัติศาสตร์อันยาวนาน เป็นที่ตั้งของหิรัญนครเงินยางเชียงแสน
ซึ่งเป็นนครหลวงก่อนการกำเนิดอาณาจักรล้านนา มี "คำเมือง" เป็นภาษาท้องถิ่น
มีเอกลักษณ์เฉพาะตัวทั้งด้านศิลปะ ประเพณีวัฒนธรรมที่มีความหลากหลายทางชาติพันธุ์ในรูปแบบล้านนา
ไทใหญ่ ไทเขิน และไทลื้อจากสิบสองปันนาผสมผสานกัน นอกจากนี้จังหวัดเชียงรายยังขึ้นชื่อว่าเป็น
"เมืองศิลปะ" และเป็นที่เกิดของศิลปินที่มีอิทธิพลอย่างมากในวงการศิลปะไทย โดยเฉพาะ ถวัลย์ ดัชนี
ผู้สร้างสรรค์บ้านดำ และ เฉลิมชัย โฆษิตพิพัฒน์ ผู้สร้างสรรค์วัดร่องขุ่นและหอนาฬิกาเมืองเชียงราย
สถานที่ท่องเที่ยวสำคัญของเชียงรายที่มีเอกลักษณ์เฉพาะของศิลปิน
และเป็นแบบอย่างของวัดร่องเสือเต้นซึ่งเป็นอีกสถานที่ท่องเที่ยวสำคัญ
ครั้นต่อมาเมื่อล้านนาตกไปอยู่ในปกครองของพม่า ในปี พ.ศ. 2101
พม่าได้ตั้งขุนนางปกครองเมืองเชียงรายเรื่อยมา หลังจากนั้น พ.ศ. 2317
เจ้ากาวิละแห่งลำปางได้สวามิภักดิ์ต่อกรุงเทพฯ ทำให้หัวเมืองล้านนาฝ่ายใต้ตกเป็นประเทศราชของสยาม
ขณะที่เชียงรายและหัวเมืองล้านนาฝ่านเหนืออื่น ๆ ยังคงอยู่ใต้อำนาจพม่า
ล้านนากลายเป็นพื้นที่แย่งชิงอำนาจระหว่างสยามกับพม่า ในช่วงเวลาดังกล่าวเมืองเชียงรายเริ่มร้างผู้คน
ประชาชนอพยพหนีภัยสงครามไปอยู่เมืองอื่น บ้างก็ถูกกวาดต้อนลงไปทางใต้ พ.ศ. 2247
เมืองเชียงแสนฐานที่มั่นสุดท้ายของพม่า ถูกกองทัพเชียงใหม่ ลำปาง และน่าน ตีแตก
เมืองเชียงรายจึงกลายสภาพเป็นเมืองร้างตามเมืองเชียงแสน
โครงสร้างเศรษฐกิจของจังหวัดเชียงรายมาจากการเกษตร ป่าไม้ และการประมงเป็นหลัก
พืชสำคัญทางเศรษฐกิจของจังหวัดเชียงราย ได้แก่ ข้าวจ้าว ข้าวโพดเลี้ยงสัตว์ สัปปะรด มันสัมปะหลัง
ส้มโอ ลำไย และลิ้นจี่ ซึ่งทั้งคู่เป็นผลไม้สำคัญที่สามารถปลูกได้ในทุกอำเภอของจังหวัด
นอกจากนี้จังหวัดเชียงรายยังขึ้นชื่อสำหรับการเพาะปลูกชา อันเป็นพืชเศรษฐกิจใหม่ของจังหวัดเชียงรายในปี
พ.ศ. 2561 นอกจากนี้จังหวัดเชียงรายยังเป็นจังหวัดที่มีความสำคัญในเชิงการท่องเที่ยว
มีจำนวนผู้เยี่ยมเยียนจังหวัดเชียงรายทั้งหมดราว 3,600,000 คนในปี 2561 มากเป็นอันดับที่สองนภาคเหนือ
รองจากจังหวัดเชียงใหม่ การท่องเที่ยวสร้างรายได้ให้กับจังหวัดมากกว่า 28,500 บาท
"""
Wrapper ฟังก์ชัน word_tokenize()
เราจะเรียกใช้อัลกอริทึมต่าง ๆ ผ่าน Wrapper ฟังก์ชัน word_tokenize()
ulmfitIn [36]:
Copy %%timeit
tokens = word_tokenize(speedtest_text, engine="ulmfit")
Copy 100 loops, best of 3: 6.07 ms per loop
etccIn [37]:
Copy %%timeit
tokens = word_tokenize(speedtest_text, engine="etcc")
Copy 100 loops, best of 3: 6.4 ms per loop
tccIn [38]:
Copy %% timeit
tokens = word_tokenize (speedtest_text, engine = "tcc" )
Copy 100 loops, best of 3: 6.45 ms per loop
deepcutIn [39]:
Copy %%timeit
tokens = word_tokenize(speedtest_text, engine="deepcut")
Copy 1 loop, best of 3: 971 ms per loop
attacutIn [47]:
Copy %% timeit
tokens = word_tokenize (speedtest_text, engine = "attacut" )
Copy 10 loops, best of 3: 72.1 ms per loop
pyicuIn [40]:
Copy %%timeit
tokens = word_tokenize(speedtest_text, engine="pyicu")
Copy 100 loops, best of 3: 6.29 ms per loop
longestIn [41]:
Copy %%timeit
tokens = word_tokenize(speedtest_text, engine="longest")
Copy 1 loop, best of 3: 1.77 s per loop
newmmIn [42]:
Copy %%timeit
tokens = word_tokenize(speedtest_text, engine="newmm")
Copy 100 loops, best of 3: 6.09 ms per loop
newmm-safeIn [48]:
Copy %%timeit
tokens = word_tokenize(speedtest_text, engine="newmm-safe")
Copy 100 loops, best of 3: 7.31 ms per loop
จะเห็นได้ว่าความเร็วไม่ต่างกันมาก ไม่เกิน 10 Millisecond ยกเว้น attacut ใช้เวลา 100 Millisecond deepcut กับ longest ที่ใช้เวลาหลักวินาที ช้ากว่าถึง 100 เท่า
Directly call
ลองเรียก แบบโดยตรง ไม่ผ่าน Wrapper Function word_tokenize()
newmm แบบเรียกโดยตรงIn [49]:
Copy %% timeit
tokens = pythainlp . tokenize . newmm . segment (speedtest_text)
Copy 100 loops, best of 3: 6.07 ms per loop
newmm-safe แบบเรียกโดยตรงIn [50]:
Copy %% timeit
tokens = pythainlp . tokenize . newmm . segment (speedtest_text, safe_mode = True )
Copy 100 loops, best of 3: 7.34 ms per loop
3. All Possible Segments
ดูความเป็นไปได้ทุกแบบในการตัดคำIn [0]:
Copy from pythainlp . tokenize . multi_cut import find_all_segment , mmcut , segment
# text = "เมืองเชียงรายมีประวัติศาสตร์อันยาวนาน"
text = "จังหวัดเชียงรายตั้งอยู่ตอนเหนือสุดของประเทศไทย"
In [0]:
Copy # mmcut??
# segment??
# find_all_segment??
In [85]:
Copy find_all_segment (text)
Out[85]:
Copy ['จัง|หวัด|เชียง|ราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จัง|หวัด|เชียง|ราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จัง|หวัด|เชียง|ราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จัง|หวัด|เชียง|ราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประ|เทศ|ไทย|',
'จัง|หวัด|เชียง|ราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้ง|อยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียง|ราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้งอยู่|ตอน|เหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียง|ราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้ง|อยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียง|ราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียง|ราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จัง|หวัด|เชียงราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|',
'จังหวัด|เชียงราย|ตั้งอยู่|ตอนเหนือ|สุด|ของ|ประเทศ|ไทย|']
In [86]:
Out[86]:
Copy ['จังหวัด', 'เชียงราย', 'ตั้งอยู่', 'ตอนเหนือ', 'สุด', 'ของ', 'ประเทศ', 'ไทย']
In [87]:
Out[87]:
Copy ['จังหวัด', 'เชียงราย', 'ตั้งอยู่', 'ตอนเหนือ', 'สุด', 'ของ', 'ประเทศ', 'ไทย']
4. Subword Tokenization
เราสามารถทำ Tokenization ระดับย่อยลงไปกว่า Word ได้อีก เรียกว่า Subword มี 2 วิธีได้แก่ Syllable (พยางค์) และ Thai Character Cluster (TCC)
4.1 Thai Character Cluster (TCC)
In [0]:
Copy from pythainlp import subword_tokenize
In [93]:
Copy text = "จังหวัดเชียงราย"
subword_tokenize(text) # default subword unit is TCC
Out[93]:
Copy ['จัง', 'ห', 'วัด', 'เชีย', 'ง', 'รา', 'ย']
4.2 Syllable (พยางค์)
In [94]:
Copy subword_tokenize(text, engine="ssg") # use ssg for syllable
Out[94]:
Copy ['จัง', 'หวัด', 'เชียง', 'ราย']
4.3 Low-level TCC
ใช้ Low-level ฟังก์ชัน ของ TCC ในการทำ Pre-processing เช่น ในการเช็คการตัด String เพื่อขึ้นบรรทัดใหม่In [95]:
Copy from pythainlp.tokenize import tcc
tcc.segment(text)
Out[95]:
Copy ['จัง', 'ห', 'วัด', 'เชีย', 'ง', 'รา', 'ย']
tcc_pos()
คำนวน ตำแหน่งที่ตัดIn [96]:
Copy tcc.tcc_pos(text) # return positions
Out[96]:
Copy {3, 4, 7, 11, 12, 14, 15}
tcc() สร้าง GeneratorIn [97]:
Copy for ch in tcc.tcc(text): # TCC generator
print(ch, end='-')
Copy จัง-ห-วัด-เชีย-ง-รา-ย-
ศึกษาเพิ่มเติม
Credit
Syllable segmentation is using ssg
, a CRF syllable segmenter for Thai by Ponrawee Prasertsom.
Reference : https://www.bualabs.com/archives/3740/python-word-tokenize-pythainlp-example-algorithm-deepcut-newmm-longest-python-pythainlp-ep-2/