Thursday, December 15, 2005

ตัดคำภาษาไทยด้วย Java

JDK สามารถตัดคำภาษาไทยได้มานานแล้วแต่ไม่ค่อยมีคนรู้ บังเอิญไปอ่านเจอใน Blog ของคุณฮุ้ย


เมื่อก่อนไม่ค่อยสนใจระบบภาษาไทยสักเท่าไหร่ สงสัยจะเป็นสาเหตุหนึ่งที่ผมพูดภาษาไทยไม่ค่อยรู้เรื่อง (อังกฤษยิ่งแย่) จากการทดสอบระบบตัดคำภาษาไทยใน JDK เทียบกับ ICU ให้ผลที่ต่างกัน จากสองตัวอย่างขอฟันธงว่า JDK ให้ผลที่ดีกว่า ICU ครับ

พระเอกของงานนี้คือตัว class BreakIterator ซึ่งมีให้ใช้ทั้งใน JDK เอง และ ICU ซึ่งเป็น library ของ IBM

ข้อความที่เอามาทดสอบคือ “ชั่วโมงอินเทอร์เน็ตต้อนรับปีจอ แถมมโหฬารนานสูงสุด 2 เท่า”

ผลการตัดคำภาษาไทยของ


JDK 1.4 BreakIterator

“ชั่วโมง-อิน-เทอร์เน็ต-ต้อนรับ-ปี-จอ- -แถม-มโหฬาร-นาน-สูง-สุด- -2- -เท่า-”

ICU BreakIterator

“ชั่วโมง-อินเทอร์เน็ต-ต้อน-รับ-ปี-จอ- -แถม-มโหฬาร-นาน-สูง-สุด- -2- -เท่า-”

DictionaryBasedBreakIterator

“ชั่วโมง-อินเทอร์เน็ต-ต้อน-รับ-ปี-จอ- -แถม-มโหฬาร-นาน-สูง-สุด- -2- -เท่า-”

อีกตัวอย่าง


source

ประธานาธิบดีสหรัฐฯ ยอมรับว่า เขาได้เซ็นคำสั่งลับเพื่ออนุญาตให้เจ้าหน้าที่ความมั่นคงแห่งชาติสามารถดัก ฟังโทรศัพท์ของประชาชนในสหรัฐฯจริง ขณะเดียวกันก็พยายามต่อสู้เพื่อให้มีการขยายเวลาการบังคับใช้กฎหมายแพทริออตเพื่อต่อต้านการก่อการร้ายออกไปอีก

ผลการตัดคำ

JDK 1.4 BreakIterator

ประธานาธิบดีสหรัฐฯ- -ยอม-รับ-ว่า- -เขา-ได้-เซ็น-คำสั่ง-ลับ-เพื่อ-อนุญาต-ให้-เจ้าหน้าที่-ความ-มั่นคง-แห่ง-ชาติ-สามารถ-ดัก- -ฟัง-โทรศัพท์-ของ-ประชาชน-ในสหรัฐฯ-จริง- -ขณะ-เดียวกัน-ก็-พยายาม-ต่อสู้-เพื่อให้-มี-การ-ขยาย-เวลา-การ-บังคับ-ใช้-กฎหมาย-แพ-ท-ริ-ออ-ต-เพื่อ-ต่อต้าน-การ-ก่อการ-ร้าย-ออก-ไป-อีก-

ICU BreakIterator

ประธานาธิบดี-สหรัฐฯ- -ยอม-รับ-ว่า- -เขา-ได้-เซ็น-คำ-สั่ง-ลับ-เพื่อ-อนุญาต-ให้-เจ้า-หน้าที่-ความ-มั่น-คง-แห่ง-ชาติ-สามารถ-ดัก- -ฟัง-โทรศัพท์-ของ-ประชาชน-ใน-สหรัฐฯ-จริง- -ขณะ-เดียว-กัน-ก็-พยายาม-ต่อ-สู้-เพื่อ-ให้-มี-การ-ขยาย-เวลา-การ-บังคับ-ใช้-กฎหมาย-แพ-ทริออ-ตเพื่อต่อต้านการก่อการร้ายอ-อก-ไป-อีก-

DictionaryBasedBreakIterator

ประธานาธิบดี-สหรัฐฯ- -ยอม-รับ-ว่า- -เขา-ได้-เซ็น-คำ-สั่ง-ลับ-เพื่อ-อนุญาต-ให้-เจ้า-หน้าที่-ความ-มั่น-คง-แห่ง-ชาติ-สามารถ-ดัก- -ฟัง-โทรศัพท์-ของ-ประชาชน-ใน-สหรัฐฯ-จริง- -ขณะ-เดียว-กัน-ก็-พยายาม-ต่อ-สู้-เพื่อ-ให้-มี-การ-ขยาย-เวลา-การ-บังคับ-ใช้-กฎหมาย-แพ-ทริออ-ตเพื่อต่อต้านการก่อการร้ายอ-อก-ไป-อีก-

code ที่ใช้

package th.co.inet.workbreak;

import java.text.BreakIterator;
import java.util.Locale;

//import com.ibm.icu.text.BreakIterator;
//import com.ibm.icu.text.DictionaryBasedBreakIterator;

/**

** @author Nont Banditwong
** TODO To change the template for this generated type comment go to
** Window - Preferences - Java - Code Style - Code Templates
*/

public class ThaiWorkbreak {

public static void printEachForward(BreakIterator boundary, String source) {

StringBuffer strout = new StringBuffer();
int start = boundary.first();
for (int end = boundary.next(); end != BreakIterator.DONE; start = end, end = boundary.next()) {

strout.append(source.substring(start, end) + “-”);
}

System.out.println(strout.toString());

}


public static void main(String[] args) {

Locale thaiLocale = new Locale(“th”);

String input = “ชั่วโมงอินเทอร์เน็ตต้อนรับปีจอ แถมมโหฬารนานสูงสุด 2 เท่า”;

BreakIterator boundary = BreakIterator.getWordInstance(thaiLocale);

//BreakIterator boundary = DictionaryBasedBreakIterator.getWordInstance(thaiLocale);

boundary.setText(input);

printEachForward(boundary, input);

}

}


ด้านล่างเป็นรูปจากโปรแกรมตัวอย่างของคุณฮุ้ย