Saturday, November 13, 2004

ทดสอบตัดคำไทยด้วย ICU4J 3.0

Post นี้ตัดคำไว้ให้แล้ว

ไปเห็นว่า ICU (International Components for Unicode) ของ IBM รุ่นล่าสุด 3.0 บนเว็บ อาจจะตัดคำไทยได้ดีกว่ารุ่นที่ฝังอยู่ใน Java VM โดยเขาเขียนไว้ว่า ความสามารถใหม่ของ 3.0 ข้อหนึ่ง คือ

Enhanced Word-Break Detection – Rule-based, supports Thai 
ก็เลยเอามาลองดูสักหน่อย จะเอามาแค่ .jar ก็ได้ แต่เนื่องจากโปรแกรมสาธิต (Demo) จะมีอยู่เฉพาะใน src ตกลงก็เลยเอามา Build เอง บนเครื่อง Linux ที่มี Java/Ant พร้อมอยู่แล้ว
$ mkdir XXX; cd XXX
$ wget ftp://www-126.ibm.com/pub/icu4j/3.0/icu4jsrc_3_0.jar
$ jar xf icu4jsrc_3_0.jar
$ ant all

all:
...
...
BUILD SUCCESSFUL
Total time: 42 seconds
เสร็จแล้วก็ทดสอบโดย
java -classpath ./classes 
     -DUnicodeData=./src/com/ibm/icu/dev/data/unicode 
     com.ibm.icu.dev.test.TestAll -nothrow
หน้าจอจะขึ้น ผ่าน ผ่าน ผ่าน (passed) เต็มไปหมด ไฟล์ที่ได้ตอนนี้มี
APIChangeReport.html  META-INF/  build.xml  classes/  doc/  
icu4j.jar  license.html  readme.html  src/
ยังไม่มี richedit ที่พูดถึงใน UserGuide แฮะ แปลกใจทำไม ant all ไม่ all จริง ต้องสั่งเพิ่มโดย
ant richeditJar
ก็จะได้ไฟล์มากขึ้นมาอีกหน่อย
APIChangeReport.html  META-INF/  build.xml  classes/  doc/  icu4j.jar  
license.html  readme.html  richedit/  src/
UserGuide บอกว่ามีโปรแกรมทดสอบตัดคำมาให้แล้วด้วย เรียกใช้ได้โดย
java -classpath classes com.ibm.icu.dev.demo.rbbi.TextBoundDemo
เขาบอกให้กด ctrl+P กับ ctrl+N เพื่อกระโดดไปมาระหว่างคำก่อนหน้ากับคำถัดไป ลองดูบน Windows ด้วย Java 1.5.0 กดเท่าไรก็ไม่มีอะไรเกิดขึ้น โปรแกรมเจ๊งหรือไงไม่รู้

เล่นโปรแกรมทดสอบไม่ได้ ก็เอาโปรแกรมเดิมที่เคยทำไว้ (อยู่ใน BLOG ตัดคำไทย ด้วย Java) มาแก้ให้ใช้ ICU4J นี่ดูก็แล้วกัน

เนื่องจาก API เหมือนเดิม ดูเหมือนจะไม่ต้องแก้มาก แค่เปลี่ยนบรรทัดตรงหัวบรรทัดเดียว ให้ใช้ BreakIterator จาก ICU ก็พอ (จาก java.text.BreakIterator เป็น com.ibm.icu.text.BreakIterator)

// import java.text.*;  
import com.ibm.icu.text.BreakIterator;
จากนั้นก็ดูผลที่ได้

เมื่อตัดด้วย ICU4J 3.0

เมื่อตัดด้วย Java VM เอง 1.5.0

ชอบของ Java VM เดิมๆมากกว่า อันใหม่จาก ICU4J 3.0 ตัดถี่เกินไป

5 comments:

bact' said...

ถ้าในตัว Java VM 1.5 ไม่มีการเปลี่ยนแปลงจาก 1.4
เค้าใช้พจนานุกรมนะครับ

ส่วนใน ICU4J เท่าที่เห็น เป็นกฏ

(ดูที่คำว่า "ทดสอบ" ก็น่าจะเป็นอย่างนั้น)

bact' said...

"ติดตาม" ด้วย

Hui/ฮุ้ย said...

ดูภายใน icu4j.jar ดูเหมือนจะมีไฟล์ข้อมูลเยอะเหมือนกัน ไม่รู้ว่ามีดิกหรือเปล่า

$ jar tvf Java/ICU4J/icu4j.jar | grep th
...
3270 Sat Nov 13 09:08:12 JST 2004 com/ibm/icu/impl/data/BreakIteratorRules_th.class
...
15684 Tue Jun 08 15:45:40 JST 2004 com/ibm/icu/impl/data/icudt30b/coll/th.res
85520 Tue Jun 08 15:45:34 JST 2004 com/ibm/icu/impl/data/icudt30b/line_th.brk
108072 Tue Jun 08 15:45:36 JST 2004 com/ibm/icu/impl/data/icudt30b/th.res
256 Tue Jun 08 15:45:36 JST 2004 com/ibm/icu/impl/data/icudt30b/th_TH.res
144 Tue Jun 08 15:45:36 JST 2004 com/ibm/icu/impl/data/icudt30b/th_TH_TRADITIONAL.res
46584 Tue Jun 08 15:45:38 JST 2004 com/ibm/icu/impl/data/icudt30b/word_th.brk
93616 Sat Nov 13 09:08:06 JST 2004 com/ibm/icu/impl/data/th.brk


แต่ในรุ่นภาษา C (ICU4C) มีไฟล์ที่มีชื่อว่า thaidict.brk เลย

bact' said...

ใน ICU4J, BreakIterator มี subclass หลัก 2 อัน คือ

RuleBasedBreakIterator กะ
DictionaryBasedBreakIterator
(ซึ่งจริงๆ ก็เป็น subclass ของ RuleBasedBreakIterator อีกที)

ถ้าไม่ได้ระบุอะไร เรียกใช้ BreakIterator เฉยๆ
ของ ICU4J รู้สึกจะใช้ตัว rule based นะครับ
ถ้าอยากใช้ดิก ลองเรียก DictionayBasedBreakIterator ตรงๆ ดู

แต่ตัวใน Java VM นี่ ไม่มีให้เลือก

----

เว็บนี้น่าอ่าน

Assessment of Thai usabilities and its implication on the JDK : Executive Summary
http://www-306.ibm.com/software/globalization/topics/jdk_thai/index.jsp

Hui/ฮุ้ย said...

ลอง DictionaryBasedBreakIterator แล้ว
ตอนเริ่มต้นเหมือนจะกินเวลามากขึ้น แต่ผลเหมือนเดิมทุกประการ

ลองใช้หลายๆแบบ ยังหาแบบที่ให้ผลแตกต่างไม่ได้

เอกสารนั้น

http://www-306.ibm.com/software/globalization/topics/jdk_thai/bdetection.jsp

ก็บอกแค่ให้ใช้ BreakIterator.getXXXInstance()

เปลี่ยนเป็น DictionaryBasedBreakIterator.getXXXInstance()
ก็แล้ว หรือลอง new DictionaryBasedBreakIterator(...,...)
กันตรงๆโดย ระบุ resource ที่ดูน่าจะเป็นไฟล์ดิก ก็แล้ว

ไม่มีอะไรแตกต่าง