different treatments of Mai Yamok in BEST Corpus

In the first release of BEST Word Segmented Corpus (free registration required for corpus download), I found different segmentations for May Yamok (repetition mark):

  • |พร้อม|ๆ| |กับ|
  • |ร้อย|ๆ |ปี|
  • |ทั้งๆ ที่|
  • |ต่างๆ| |ดัง|
  • |ย่อ|ๆ| |ว่า|
  • |ย่อ|ๆ |ว่า|

(Real data, taken from encyclopedia_00005.txt. ‘|’ is word/token boundary)

These are probably intended. Or inconsistency ? Not quite sure, will ask people around.

BEST เป็นการประเมินประสิทธิภาพอัลกอริธึม/ซอฟต์แวร์ประมวลผลภาษาไทย ปีนี้จัดแข่งขันซอฟต์แวร์ตัดคำไทย ในงาน NSC ครั้งที่ 11 – สนใจร่วมได้ read more

swath 0.3.4 Released

โปรแกรมตัดคำ swath ออกรุ่น 0.3.4 แล้ว

Swath 0.3.4 released. Swath (Smart Word Analysis for THai) is a word segmentation for Thai. Swath offers 3 algorithms: Longest Matching, Maximal Matching and Part-of-Speech Bigram. The program supports various file input format such as html, rtf, LaTeX as well as plain text.

Changes from 0.3.1 (the most recent version in Ubuntu repo is 0.3.1)

  • More secure temporary file handling.
  • Fix regression introduced during portability fix in 0.3.2. (Bug report by Pisut Tempatarachoke)
  • Fix bug that prevent ‘-u u,u’ from working. (Bug report by Neutron Soutmun)
  • Minor code and doc improvements.
  • Fix char signedness portability issues.
  • Improved messages and documentation.

Get the latest version from ftp://linux.thai.net/pub/thailinux/software/swath/ read more

BEST: Word Segmentation

BEST จัด “แข่งขัน” ซอฟต์แวร์ตัดคำไทย

ประโยชน์ของการแข่งขันนี้ นอกจากด้านซอฟต์แวร์แล้ว ยังมีเรื่องของการพัฒนาคลังข้อความ (corpus) และค้นหาความหมายของสิ่งที่เรียกว่า “คำ” ในภาษาไทยอีกด้วย read more

Using dictionary with ICU4J BreakIterator

การสร้างและเรียกใข้พจนานุกรมสำหรับตัดคำ ใน ICU4J

จดวิธีการตัดคำด้วย DictionaryBasedBreakIterator ของ ICU4J และการสร้างพจนานุกรมตัดคำเอง

(เฮ้! นี่คือ “จาวา” ขวัญอ่อน? รักสวยรักงาม? .. ระวังถูกงับมือ! เราเตือนคุณแล้วนะ :P)

การสร้างไฟล์พจนานุกรมสำหรับตัดคำ

ใช้โปรแกรม BuildDictionaryFile สร้างไฟล์พจนานุกรม, วิธีใช้คือ:

BuildDictionaryFile input [encoding] [output] [list]
  • input = ข้อมูลเข้า ไฟล์พจนานุกรม เป็นไฟล์ชนิดข้อความ หนึ่งคำต่อหนึ่งบรรทัด
  • encoding = รหัสตัวอักษรของไฟล์พจนานุกรม เช่น TIS-620, UTF-8 (ถ้าไม่ใส่จะใช้ค่าปริยาย คือ UTF-8)
  • output = ข้อมูลออก ผลลัพธ์ เป็นไฟล์ชนิดไบนารี (จะใช้เป็นอินพุตของคอนสตรัคเตอร์ของคลาส DictionaryBasedBreakIterator ต่อไป)
  • list = ข้อมูลออก รายการคำที่ถูกบรรจุในพจนานุกรม (output) เป็นไฟล์ชนิดข้อความ หนึ่งคำต่อหนึ่งบรรทัด ใช้รหัสตัวอักษร UTF-8 (ไม่ใส่ก็ได้)

เช่น ถ้าไฟล์ข้อความที่เราจะแปลงเป็นพจนานุกรมตัดคำ ชื่อ tdict.txt ก็สั่ง:

# java com.ibm.icu.dev.tools.rbbi.BuildDictionaryFile tdict.txt \
    TIS-620 tdict.dic tdict-list.txt

รอซักพัก เราก็จะได้ไฟล์ tdict.dic ไปใช้ละ

การใช้โปรแกรม BuildDictionaryFile จำเป็นต้องมีไลบรารี ICU4J อยู่ใน classpath (ใช้ออปชั่น -cp ก็ได้)

ซอร์สโค้ด BuildDictionaryFile.java นั้น ไม่ได้เผยแพร่ออกมาพร้อมกับตัว ICU4J แต่หาดาวน์โหลดได้ในอินเทอร์เน็ต (update 2011.05.13: ไฟล์ BuildDictionaryFile.java ที่ ICT Trac) (ค้นอินเทอร์เน็ตด้วยคำว่า “BuildDictionaryFile.java” แล้วพยายามหาไฟล์รุ่นที่ใหม่ที่สุด ตัวที่ผมใช้อยู่นี้ อยู่ในแพคเกจ com.ibm.icu.dev.tools.rbbi ถ้ารุ่นเก่ากว่านี้มันจะอยู่ในแพคเกจ com.ibm.tools.rbbi คิดว่าเค้ามีการปรับแพคเกจใหม่นิดหน่อย)

การคอมไพล์ ต้องมีไลบรารี ICU4J อยู่ใน classpath (ใช้คลาส com.ibm.icu.util.CompactByteArray, com.ibm.icu.text.UnicodeSet และ com.ibm.icu.impl.Utility)

การใช้ไฟล์พจนานุกรมในการตัดคำ

คลาสที่เราใช้ในการตัดคำด้วยพจนานุกรม ใน ICU4J คือ คลาส DictionaryBasedBreakIterator ในแพคเกจ com.ibm.icu.text
(DictionaryBasedIterator นี้ เป็นซับคลาสของคลาส RuleBasedBreakIterator ซึ่งเป็นอินพลีเมนเตชันของแอบสแตรคคลาส BreakIterator อีกที)

คอนสตรัคเตอร์ของ DictionaryBasedBreakIterator ที่เราจะใช้ ต้องการพารามิเตอร์สองตัว
คือ กฎการตัดคำ (String) และ พจนานุกรม (InputStream)

ผมไม่รู้จะหากฎมาจากไหนดี ก็เลยไปเอามาจากที่เค้ามีอยู่แล้วละกัน อย่างนี้

String rules = (RuleBasedBreakIterator.getWordInstance(new Locale ("th"))).toString();

คำสั่งนี้ จะไปเรียกเอาตัวตัดคำด้วยกฎ (สำหรับคำภาษาไทย) มาจากคลาส RuleBasedBreakIterator
ซึ่งจริง ๆ ผมก็ไม่รู้แน่ ว่ามันมีอยู่หรือไม่ อย่างไรก็ตาม หากตัว RuleBasedBreakIterator ไม่มีตัวตัดคำสำหรับโลแคล (locale) ใด มันก็จะส่งคืนตัวตัดคำปริยาย (มาตรฐาน) มาให้เรา เอาเป็นว่าไม่ต้องห่วงละกัน (ยังนึกวิธีดี ๆ ไม่ออกน่ะ :P)
Update: 2006.12.28 พี่ป๊อกไขขาน สร้างความกระจ่างเรื่องที่ว่า กฎมันมาจากไหน ดูได้ที่ เสริม ICU4J ในนั้นยังแสดงวิธีการดึงกฎจากไฟล์กฎอีกด้วย (แต่จะสร้างไฟล์กฎยังไงหว่า? .. ต้องศึกษากันต่อไป)

หลังจากได้ตัวตัดคำด้วยกฎมาแล้ว เราก็ดึงกฎการตัดออกมาซะ ด้วยเมทธอด toString()
(ง่าย ๆ อย่างนี้แหละ .. แต่หาอยู่นาน – -“)

จากนั้น เราก็เตรียมพจนานุกรม ก็ไม่มีอะไรมาก แค่ชี้ไปหาไฟล์ที่เราสร้างมาจากโปรแกรม BuildDictionaryFile ตะกี้

InputStream dict = new FileInputStream("tdict.dic");

เท่านี้ล่ะ

จากนั้นเราก็สามารถสร้างอินสแตนซ์ของ DictionaryBasedBreakIterator ได้แล้ว

BreakIterator iter = DictionaryBasedBreakIterator(rules, dict);

การใช้งานก็เหมือนกับ BreakIterator ปกติ (ซึ่งก็คล้ายกับ iterator ทั่วไป)
โดยเริ่มแรกเราต้องส่งข้อความที่จะตัดไปให้ตัว BreakIterator เสียก่อน ด้วยเมธทอด setText()
จากนั้นเราก็ให้ iterator มันวนไปเรื่อย ๆ ด้วยเมทธอด next() จนกว่าจะจบข้อความ

โค้ดด้านล่างจะทำการพิมพ์คำที่ตัดได้ ตามด้วยตัวอักษร “|” ทีละคำ ๆ วนไปจนกว่าจะจบข้อความ

String text = "ข้อความที่จะตัดในนี้"; iter.setText(text); // iter คือ BreakIterator มาจากข้างบน int start = iter.first(); for (int end = iter.next(); end != BreakIterator.DONE; start = end, end = iter.next()) { System.out.print(text.substring(start,end)); System.out.print("|"); } read more

ZWSP with cttex

แทรก ZWSP (Zero Width Space ช่องว่างความกว้างศูนย์) ระหว่างคำไทยในเอกสาร HTML


# cttex -b "&#x200b;" < input.html > output.html

คำสั่งข้างบน ใช้กับ cttex-1.30w (ตั้งชื่อไว้งี้ชั่วคราว ย้ำว่าตัวนี้ไม่ใช่ตัวอย่างเป็นทางการ เป็นเพียง “hack” อันนึงเท่านั้น) ที่มีตัวเลือกใหม่ -b ไว้ให้กำหนดตัวแบ่งคำเองได้ read more

cttex 1.30 dict2state stack overflow on Windows

ทดลอง make cttex 1.30 บน Windows,
ปรากฎว่า ตอนแปลงพจนานุกรมเป็น map (โปรแกรม dict2state) เกิด stack overflow
เกิดขึ้นกับทั้ง gcc และ Visual C++ 2005 Express Edition
บน GNU/Linux + gcc ไม่พบปัญหา

ใครพอรู้สาเหตุ/วิธีแก้ ช่วยหน่อยนะครับ ในกระทู้ที่ LTN:
stack overflow ใน dict2state ใน cttex 1.30
ขอบคุณครับ 🙂 read more

ThaiWrap รุ่น 5

(บล็อกเก่า ThaiWrap bookmarklet, Auto thaiWrap())

รายการเปลี่ยนแปลง:

  • ตัวแบ่งคำ เปลี่ยนจาก <WBR> มาใช้ zero-width space (U+200B) แทน เนื่องจาก Opera ไม่รู้จัก <WBR>
  • เพิ่มการตรวจเบราเซอร์ เพื่อข้ามการทำงานทั้งหมด ถ้าใช้ Internet Explorer (เหตุผล: 1. จะได้ไม่เสียเวลา เพราะ IE ตัดคำได้อยู่แล้ว 2. IE แสดงผล zero-width space ไม่ได้)

ตอนนี้ยังเหลือปัญหา เรื่องไม่ทำงานกับเฟรมที่ซ้อนเฟรม ไล่ DOM reference ตะกี้นี้ เจอละว่ามันผิดตรงไหน (เราไปใช้ window.frames ซึ่งมันจะส่งค่ากลับเฉพาะ frames ระดับบนสุดเท่านั้น, คาดว่า. นอกจากนั้น มันยังไม่อยู่ใน spec ด้วย – อันตราย) แต่ยังไม่รู้จะแก้ไง ขอค้นก่อน read more

Auto thaiWrap()

จากการแนะนำของคริส (iChris) เขียนวิธีการใช้ฟังก์ชั่นตัดบรรทัด thaiWrap() กับอีเวนต์ onload ไว้แล้ว ที่นี่

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

จากข่าว ยกน้ำหนักหญิงไทย

ก่อนอื่นก็ขอแสดงความยินดีด้วย กับทั้งทีมเลย

ส่วนอันนี้จากข่าว ที่กรุงเทพธุรกิจ

—-

โฆษกประจำสำนักนายกรัฐมนตรี กล่าวว่า นายสุวัจน์ ยังได้ชี้แจงเกี่ยวกับข่าวที่เสนอว่าไปเอาเหรียญทองมาจากนางสาวอุดมพรมานั้น ความจริงคือนางสาวอุดมพร แจ้งต่อรองนายกรัฐมนตรีว่าอยากได้เหรียญที่เป็นทองคำแท้ จึงรับปากที่จะทำให้ โดยขอยืมเหรียญทองมาทำบล็อคในการทำเหรียญทองคำแท้ และจะส่งเหรียญตัวจริงกลับไป เพราะนางสาวอุดมพร จะต้องใช้ในการทำกิจกรรมต่าง ๆ อีก read more