ย้ายบล็อกไปที่ bact.cc แล้วนะครับ

พ.ร.บ.คอมพิวเตอร์
หยุด ร่างพ.ร.บ.คอมพิวเตอร์
พื้นที่เก็บข้อมูลออนไลน์ ฟรี 2GB จาก Dropbox (sync กับ Windows, Linux, Mac, iPhone, Android ฯลฯ ได้)
Showing posts with label text processing. Show all posts
Showing posts with label text processing. Show all posts

2009-12-07

Web Character Simplification Chart 0.1 #opendream

ก่อนจะประมวลผลข้อความ เราจำเป็นต้องทำความสะอาดข้อความเสียหน่อย ทั่ว ๆ ไปที่จำเป็นต้องทำ ก็เช่น แปลง new line (\r\n หรือ \n), หรือแปลงให้อยู่ในชุดอักขระ (character set) ที่โปรแกรมใน processing pipeline จะทำงานได้ เช่นแปลง ä เป็น ae หรือแปลง “ ” เป็น " ", หรือการ normalize ลำดับอักขระ เช่น น.หนู+สระอำ+ไม้โท → น.หนู+ไม้โท+สระอำ, หรือไปถึงขั้นซับซ้อน อย่างแก้ตัวสะกด

(กรณีเป็นงานลักษณะจดหมายเหตุ หรือ archival ก็อาจจำเป็นต้องเก็บตัว raw text ก่อนแปลงเอาไว้ด้วย เพราะการแปลงอาจจะ(และมักจะ)เป็น lossy คือแปลงไปแล้วแปลงกลับมาได้ไม่เหมือนเดิม เช่นตัวอย่างข้างบน ที่แปลง “ ” เป็น " ")

การทำความสะอาดข้อความ หรือ text cleansing นี้ มีจุดประสงค์หลายอย่าง อย่างหนึ่งก็เพื่อเพิ่มความต้องตรงกัน (integrity) ภายในเนื้อข้อความ ซึ่งกรณีถ้าจะเอาข้อความนี้ไปประมวลผลทางสถิติ เช่นเอาไปฝึกเครื่อง (machine learning) ความต้องตรงกันภายในข้อความนี้ ก็มีผลต่อความแม่นยำของตัวแบบที่จะฝึกได้

จุดประสงค์อีกอย่างของการทำความสะอาดข้อความ ก็เพื่อลดความซับซ้อนของการประมวลผลด้วย ไม่ว่าจะเป็นการลดความซับซ้อนของตัวแบบ หรือการลดความซับซ้อนของเงื่อนไขในโปรแกรม เช่น ทำให้เขียน regular expression ได้สะดวกขึ้น

สำหรับแอปพลิเคชั่นการค้นหาและการทำดัชนี การทำความสะอาดข้อความ รวมไปถึงการทำให้ข้อความมันซับซ้อนน้อยลง (ไม่ว่าจะในทางลำดับอักษร ซึ่งจะมีผลต่อขนาดของ word set หรือการลดขนาดของ character set ด้วยการยุบตัวอักษรบางตัวเข้าด้วยกัน) จะช่วยให้ดัชนีมีขนาดเล็กลงด้วย และถ้าใช้ประกอบกับตารางการแทนอักษร/คำ (replacement table) ก็จะช่วยให้โอกาสการเจอคำที่ค้นหา มีมากขึ้น เนื่องจากลดผลกระทบจากการสะกดไม่ตรงกัน (spelling variations) (จริง ๆ จะใช้ replacement table อย่างเดียวก็ได้ แต่กรณีนั้น search space ก็จะใหญ่ขึ้น มีผลต่อประสิทธิภาพ)

ในตอนที่เขียน JavaScript สำหรับใช้กับ Roti ก็คิดไว้าว่าจะเจอปัญหาลักษณะนี้ ซึ่งจะมีผลต่อการคำนวณหาบล็อกโพสต์ที่ใกล้เคียง (ดูตัวอย่างได้ที่ท้ายโพสต์นี้ ตรงที่เขียนว่า 'roti thinks you may like these posts...') เลยให้จาวาสคริปต์ทำความสะอาดข้อความนิดหน่อย ก่อนจะส่งไปเซิร์ฟเวอร์

เนื่องจาก Roti ทำงานกับเอกสารเว็บ ซึ่งมี 'ปัญหา' อีกอย่าง คือการใช้ HTML/XML entities แทนตัวอักษร เช่นใช้ & เพื่อแทนอักษร & ดังนั้นก่อนจะทำอะไรกับข้อความ จึงควร decode entities พวกนี้ออกมาก่อน

กรณีของ HTML entities ถ้าใช้ PHP สามารถใช้ฟังก์ชั่น html_entity_decode($text) ได้เลย แต่ในจาวาสคริปต์มันไม่มี (หรือผมไม่รู้ว่ามันมี) ก็เลยใช้แทนที่สตริงแบบบ้าน ๆ ไป

ตารางข้างล่างปรับแก้มาจากตัวจาวาสคริปต์ roticlient.js และใส่รายละเอียดเพิ่มเติมนิดหน่อย ยินดีรับคำแนะนำครับ

possible replacements ในตารางนั้น เป็นเพียงคำแนะนำตั้งต้น การจะเลือกใช้อะไร ขึ้นอยู่กับแอปพลิเคชั่นด้วย เช่น ตัวเลือกที่เหมาะกับการเอาไปทำดัชนี ก็อาจจะไม่เหมือนกับตัวเลือกที่เหมาะกับการเอาไปแสดงผล เช่น zero-width space ถ้าทำดัชนี การแทนด้วย space น่าจะเหมาะ แต่ถ้าจะเอาไปแสดงผล การลบมันทิ้งไปเลย น่าจะเหมาะกว่า

Web Character Simplification Chart 0.1

Throw away extra semantics for a simpler text processing. This is only a suggestion. Apply to your needs accordingly.

Character NameCharacterUnicodeASCII range?HTML EntitiesPossible Replacements
Space  yes  
Non-breaking space U+00A0yes (space)
Zerowidth space U+200B  (space), <delete>
 
Soft hyphen U+00ADyes&shy;<delete>
 
Hyphen-Minus-U+002Dyes  
Hyphen-U+2010  - (hyphen-minus)
Minus sign−U+2212 &minus;-
Figure dash‒U+2012  -
En dash–U+2013 &ndash;-, --
Em dash—U+2014 &mdash;-, ---
Horizontal bar―U+2015  -
Armenian hyphen֊U+058A  -
Hebrew magaf־U+05BE  -
Mongolian todo hyphen᠆U+1806  -
Japanese chōonpuーU+30FC  -
 
Hyphen bullet⁃U+2043  * (star), -, <delete>
Small bullet•U+2022  *, -, <delete>
 
Tilde~U+007Eyes&tilde; 
Swung dash˜U+2053  ~ (tilde)
Wave dash〜U+301C  ~
Wavy dash〰U+3030  ~

ด้านล่างนี้ เป็นตัวอย่างโค้ดที่แทนที่ตัวอักษรต่าง ๆ จาก roticlient.js

return str.replace(/(&nbsp;|&#8208;|&#8210;|&ndash;|&#8211;|&mdash;|&#8212;|&#8213;|&#8275)/g, ' ') .replace(/(&shy;|&#xAD;|&#173;|&#x200B;|&#8203)/g,'') .replace(/[\u200b\u200d\u00ad]/g, '') .replace(/[!\?;:"'`“”^\*\+\-_\(\)\[\]\{\}#@&~\.,\\\/\|]/g, ' ') .replace(/\s+/g, ' ');

ติดตามการพัฒนา Roti ได้จาก Opendream's blog

(โพสต์นี้ให้ @pittaya เนื่องจากเคยถามเอาไว้เมื่อนานเมือกแล้ว)

technorati tags: , ,

2009-06-07

ช่วงช่วง หลินฮุ่ย เคอิโงะ เสื้อแดง เอ็นจีวี นักศึกษา แพนด้า SEO OCR

OCRopus โอเพ่นซอร์สทูลคิตสำหรับงาน OCR รุ่น 0.4 ออกแล้วครับ น่าจะคอมไพล์อะไรต่าง ๆ ได้ง่ายขึ้นบนแพลตฟอร์มที่ไม่ใช่ GNU/Linux ครับ

ดาวน์โหลดได้ทันทีที่เว็บไซต์ OCRopus (โอเพ่นซอร์ส Apache License 2.0)

ที่หน้าเว็บ Course: OCRopus สอนการใช้งานและปรับแต่ง OCRopus มีวิธีเขียน Lua และ C++ เพื่อเรียกใช้ OCRopus ด้วย

แม้ OCRopus จะรองรับการเพิ่มเติมภาษาใหม่ ๆ เข้าไปได้ แต่ก็ต้องลงแรงหน่อย ตอนนี้ยังใช้ไทยไม่ได้โดยทันที

สำหรับคนที่มองหาตัวที่อ่านภาษาไทยได้ และไม่แพงนัก ลองหา ArnThai (อ่านไทย) มาทดสอบดู มีทั้งบนวินโดวส์และลีนุกซ์ (รุ่นบนลีนุกซ์เก่ากว่าหน่อย) ติดต่อเนคเทคได้ ถ้าสนใจนำไปใช้ ที่เคยถาม สามารถตกลงสัญญาอนุญาตได้หลายแบบ

สำหรับตัวที่มีประสิทธิภาพดีกว่านั้นและมีความสามารถเพิ่มเติมอื่น ๆ ที่อ่านไทยได้ คือ ABBYY FindReader อ่าน PDF ได้ ใช้ได้หลายภาษา (ทายอัตโนมัติ) คง document logical structure, formatting, style, ฟอนต์, และตาราง อู้ฟู่หรูหรามาก (ขอบคุณ @sarasinb และ @thai101 สำหรับข้อมูล)

รีวิวซอฟต์แวร์ OCR ต่าง ๆ บนลีนุกซ์ : โดย groundstate, โดย Peter Selinger. บทความ optical cahracter recogntion ที่วิกิพีเดียภาษาอังกฤษ มีลิงก์ไปหาซอฟต์แวร์ต่าง ๆ ด้านล่างสุด.

technorati tags: , , , ,

2008-10-23

Gmail's smarter auto-responses

กูเกิลแล็บส์มาอีกแล้ว คราวนี้เพิ่มพลังจีเมลด้วย “canned responses” หรือระบบตอบจดหมายอัตโนมัติ ที่เราตั้งล่วงหน้าได้ว่า ถ้ามีจดหมายที่มีคำสำคัญนี้ จากคนนั้น ให้ตอบไปว่ายังไง ประหยัดเวลาตอบอีเมลซ้ำ ๆ ซาก ๆ :p

อย่างถ้ามีคำว่า “viagra” มาในเมล เราก็ตั้งให้ตอบกลับไปได้ว่า “Thanks. I do already have good sexes.” อะไรแบบนี้เป็นต้น :p

technorati tags: , ,

2008-04-07

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/

More info at http://linux.thai.net/node/117 (posted by thep)

(สะกด swath ยังไงครับ ? swath, Swath, SWATH ?)

technorati tags: , ,

2007-01-08

Newline in GATE

ใน GATE, ถ้าเราอยากรู้ว่า เอกสารที่เรากำลังทำงานอยู่เนี่ย มันใช้ อักขระขึ้นบรรทัดใหม่ (newline) แบบไหน ก็เรียกดูได้จากฟีเจอร์ที่ชื่อ “docNewLineType”
โดย docNewLineType นี้ เป็น String มีค่าได้ 4 อย่าง: { "CR", "LF", "CRLF", "LFCR" }

CR คือ Carriage Return — ปัดแคร่(ไปซ้ายสุด) (\r ในหลายภาษาโปรแกรม),
LF คือ Line Feed — เลื่อนบรรทัดใหม่ (\n)

เพื่อขึ้นบรรทัดใหม่ เครือญาติ UNIX อย่าง Linux กับ Mac OS X ใช้ LF ตัวเดียว,
ใน Mac OS (จนถึงรุ่น 9) ใช้ CR ตัวเดียว,
ส่วนเพื่อนรัก Windows ของเรา เป็นเด็กนอย ใช้มันสองตัวเลย CRLF กันเหนียว*, DOS ก็เช่นกัน
(* พูดจริง ๆ แล้ว DOS/Windows ทำตัวเลียนแบบเครื่องพิมพ์ดีดจักรกลได้เหมือนที่สุด คือต้องปัดแคร่ไปซ้ายสุดก่อน จากนั้นจึงค่อยเลื่อนกระดาษไปหนึ่งบรรทัดได้ เป็นการเริ่มบรรทัดใหม่)

นอกเรื่องซะไกล อ่ะ เขียนโค้ดได้อย่างนี้ (ตรงที่เป็นตัวหนา)


int nllen = 1;
String nl = (String) document.getFeatures().get("docNewLineType");
if (nl.equals("CRLF") || nl.equals("LFCR")) {
  nllen = 2;
}

ผมหาเจ้าความยาวของอักขระขึ้นบรรทัดใหม่ (nllen) นี่ไป เพื่อไปชดเชยออฟเซตเวลาประมวลผลเอกสาร
คือ ผมใช้เมทธอด readLine() ในคลาส *Reader ซึ่งมันจะอ่านทีละบรรทัดให้อัตโนมัติ สบายดี
แต่เวลานับตำแหน่งเนี่ย ต้องอย่าลืมนับเจ้าตัวอักขระขึ้นบรรทัดใหม่เข้าไปด้วย ไม่งั้นตำแหน่งมันจะคลาดกัน
ก็เลยต้องรู้ว่า ใช้อักขระขึ้นบรรทัดใหม่แบบไหน จะได้ชดเชยถูก

technorati tags: , ,

2006-04-11

Character set detection in Java

jchardet — a Java port of Mozilla's automatic charset detection algorithm.

Open Source HTML Parsers in Java

Open Source HTML Parsers in Java, a list by Java-Source.net

NekoHTML, HTML Parser, Java HTML Parser, Jericho HTML Parser, JTidy, TagSoup, HotSax

แถม Nux เหมือนจะทำอะไรได้หลายอย่างสารพัดเกี่ยวกับ XML (เป็น wrapper ของตัวอื่น ๆ ด้วย)

2005-09-01

Thai full-text search in MySQL - Draft Propsal

สถาบันส่งเสริมการจัดการความรู้เพื่อสังคม (สคส.) กำลังจะให้ทุนเพื่อพัฒนาความสามารถในการค้นหาข้อความภาษาไทย (Thai full-text search) ในระบบฐานข้อมูลโอเพนซอร์ส MySQL โดยมีงบประมาณ 200,000 บาท

โดยตอนนี้ มีร่างข้อเสนอสำหรับโครงการแล้ว และคณะทำงานเห็นว่า น่าจะรับฟังความเห็นของสาธารณะเสียหน่อย เกี่ยวกับร่างข้อเสนอนี้

ใครสนใจ ก็ลองอ่านดู แล้วแสดงความคิดเห็นกันได้ที่เว็บบอร์ด LTN ห้อง General ที่กระทู้นี้ครับ — ขอบคุณครับ :)

2005-04-01

Emdros - a database engine for annotated text

เมื่อคืนวีร์พูดถึง Emdros ว่าน่าสนใจ สำหรับงานฐานข้อมูลทางภาษาศาสตร์ ก็เลยเข้าไปดูเว็บซะหน่อย

Emdros is:

  • an opensource text database engine for storage and retrieval of analyzed or annotated text.
  • applicable especially in corpus linguistics and computational linguistics.
  • equiped with a powerful query-language MQL, based on the Extended MdF mathematical model of text.

A short paper explaninig Emdros.

ข้างบนจะเห็นคำว่า Extended MdF หรือที่ในเว็บ Emdros จะใช้คำว่า EMdF, ชื่อเต็มๆ ของมันคือ Extended Monads dot Feature โดยพัฒนาต่อมาจาก Monads dot Feature (book; review)

More about text database:

2005-02-09

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 ด้วย - อันตราย) แต่ยังไม่รู้จะแก้ไง ขอค้นก่อน

ThaiWrap bookmarklet/JavaScript, Release 5