NLTK corpus readers for NECTEC BEST and ORCHID corpora

ความเดิมจากตอนที่แล้ว ทดลองสร้าง corpus reader ใน NLTK

ตอนนี้แก้การ encode ให้ใช้ได้กับ nltk.Text() แล้ว (แทนที่จะเก็บเป็น unicode ก็เก็บเป็น utf-8 encoded str แทน)

พร้อมกับเพิ่มตัวอ่านสำหรับคลังข้อความ BEST และ ORCHID ด้วย

ตัวอ่านคลัง BEST ในรุ่น 0.3 นี้ เรียกดูเป็นหมวดได้ (ข่าว วรรณกรรม สารานุกรม บทความ) เรียกดูข้อมูลกำกับขอบเขตคำ (word boundaries) ได้ แต่ยังไม่รองรับ <NE>named-entities</NE> กับ <AB>คำย่อ</AB> เนื่องจาก BEST ไม่มีข้อมูลขอบเขตประโยค ตัวอ่านคลังจะสร้างขึ้นเอง โดยสมมติ \n เป็นขอบเขตประโยค

ส่วนตัวอ่านคลัง ORCHID ในรุ่น 0.3 นี้ เรียกดูข้อมูลกำกับขอบเขตคำและชนิดคำ (Part-of-Speech) ได้ แต่ยังไม่รองรับขอบเขตย่อหน้า และยังเรียกดูเป็นรายเอกสารไม่ได้ (รุ่นนี้ทำงานกับคลัง ORCHID แบบที่ถูกเอา document-related metadata ออกไป)

ดาวน์โหลด & ติดตั้ง

แพ็คเกจ rotic รุ่น 0.3 ซอร์สโค้ดเผยแพร่ด้วยสัญญาอนุญาต GNU GPLv2 ตาม NLTK – ดาวน์โหลด rotic-0.3.tar.gz

วิธีติดตั้ง อ่าน README.TXT และ INSTALL.TXT – อย่าลืมดาวน์โหลดคลังข้อความมาติดตั้งด้วย รายละเอียดและสัญญาอนุญาตของข้อมูลแต่ละชุด อยู่ใน CORPORA.TXT

มีคำแนะนำอะไร เขียนมาบอกกันได้ครับ อยากจะลองทำให้มันเอาไปใช้ในการเรียนการสอนได้ – ไม่เฉพาะสำหรับนักเรียนคอมพิวเตอร์เท่านั้น แต่สำหรับนักเรียนภาษาศาสตร์ ฯลฯ ด้วย

ตอนนี้ความเร็วไม่ค่อยดีเท่าไหร่ โดยเฉพาะการโหลดตัว ORCHID ซึ่งใหญ่มาก ส่วนหนึ่งเป็นเพราะโค้ดยังซ้ำซ้อนอยู่หลายจุด เช่นตรงการแปลง utf-8 ที่น่าจะทำได้ตั้งแต่ระดับแรก ๆ ที่อ่านเข้ามาเลย ไม่ใช่มาแปลงเอาตอนหลัง-ต้องวนลูปอีกหนึ่งครั้งแบบขณะนี้ โค้ดยัง refactor ได้อีกเยอะ ใครคล่อง Python ก็ช่วยดูหน่อยนะครับ ผมแค่พอเขียนไถ ๆ ได้ ขอบคุณครับ 🙂

ตัวอย่างจาก example.py

1. พิมพ์ข้อความมั่ว ๆ ขึ้นมาจากตัวแบบ n-gram ที่สร้างจากคำในคลัง foosci :


foosci_text = nltk.Text(foosci.words())
foosci_text.generate()

ผลลัพธ์ :

… ซึ่ง ทฤษฎี สรุป ความรู้ ของ เรา เอา ไส้เดือน ไป ปล่อย ใน พื้นที่ ๆ มี ความ สงสัย ระหว่าง ความ เชื่อ เรื่อง มิติ ใหม่ นี้ …

2. พิมพ์ คำ/ชนิดคำ จาก 5 ประโยค แรกของคลัง ORCHID
โปรดสังเกตว่า เราใช้ชุดชนิดคำ (POS/tagset) แบบง่าย สามารถสลับชุดชนิดคำได้โดยสลับค่า simplify_tags :


for sent in orchid.tagged_sents(simplify_tags=True)[0:5]:
    print "[",
    for (word, tag) in sent:
        print word + "/" + tag,
    print "]"

ผลลัพธ์ :

[ การ/FIX ประชุม/V ทาง/N วิชาการ/N /PUNC ครั้ง/C ที่_1/DETN ]
[ โครงการวิจัยและพัฒนา/N อิเล็กทรอนิกส์/N และ/CONJ คอมพิวเตอร์/N ]
[ ปีงบประมาณ/N /PUNC 2531/N ]
[ เล่ม/C /PUNC 1/DETN ]
[ ศูนย์เทคโนโลยีอิเล็กทรอนิกส์และคอมพิวเตอร์แห่งชาติ/N ]

3. หาค่าการกระจายของสองคำ การ และ ความ ใน 4 หมวดของคลัง BEST
โปรดสังเกตว่า ตรงคำที่เราจะป้อนเข้าไปให้ฟังก์ชั่นต่าง ๆ ของ NLTK เราจะแปลงมันเป็น utf-8 encoded str ก่อน :

cfd = nltk.ConditionalFreqDist( (genre, word) for genre in best.categories() for word in best.words(categories=genre)) genres = ['news', 'encyclopedia', 'novel', 'article'] prefixs = [w.encode("utf-8") for w in [u'การ', u'ความ']] cfd.tabulate(conditions=genres, samples=prefixs) read more

playing around Thai blog corpus with NLTK

อยากจะลองเล่น NLTK กับข้อมูลภาษาไทยดู คิดไปคิดมา เอาข้อมูลจาก foosci.com มาลองดูละกัน เขาเปิดให้ใช้ เป็น ครีเอทีฟคอมมอนส์ แสดงที่มา-อนุญาตแบบเดียวกัน (CC by-sa)

แต่ไม่อยากไปดึงมาเอง ขี้เกียจ เห็นว่าโครงการโรตี (อัลฟ่า) โดย Opendream ดูดบล็อกไทยจำนวนหนึ่งมาเก็บไว้ได้ระยะหนึ่งแล้ว เพื่อใช้ในการแนะนำลิงก์ (ดูตัวอย่างที่ keng.ws ที่ท้ายแต่ละโพสต์) ก็เลยเอาจากตรงนั้นมาใช้ละกัน

ข้อมูลที่มีเป็น XML ที่ dump มาจาก MySQL เราก็เขียนสคริปต์ก๊อก ๆ แก๊ก ๆ ดึงเฉพาะที่อยากได้ออกมา ด้วย xml.etree.cElementTree (ตอนแรกใช้ ElementTree แตน ๆ แต่อืดเกิน เนื่องจากแฟ้มมันใหญ่)
เอา HTML tags ออกด้วย Beautiful Soup แล้วตัดคำด้วย python-libthai ตัดประโยคแบบถึก ๆ ด้วย .split(‘\n’) จะได้ข้อมูลออกมาหน้าตาประมาณนี้ (จะเห็นว่าข้อมูลมันไม่ได้สมบูรณ์มาก มีแท็ก HTML โผล่มาด้วย-อันนี้เป็นที่ข้อมูลป้อนเข้าที่ dump มา) :

<?xml version="1.0" encoding="utf-8"?> <roti> <entry id="4947" url="http://www.foosci.com/node/401" ...> <tags> <tag>LHC</tag> <tag>quantum physics</tag> ... </tags> <title> <w>บิดา</w> <w>ของ</w> <w>อนุภาค</w> ... </title> <content> <s> <w>p</w> <w>นัก</w> <w>วิทยาศาสตร์</w> ... </s> <s> <w>pcenter</w> <w space="1"> </w> <w>ภาพ</w> ... </s> ... </content> </entry> <entry> ... </roti> read more

encode("UTF-8", "ignore") ข้าม ๆ เรื่องที่ทำไม่ได้ใน Python

หลังจากเอา python-libthai ของวีร์มาใช้กับข้อมูลที่ได้มาจากเว็บ ก็พบปัญหาเรื่อง character encoding นิดหน่อย read more

modifying setup.py for libthai Python binding in MacPorts environment

(ปรับปรุง 2009.04.21 พบท่าง่ายกว่าเดิม ดูด้านล่าง)

เอา libthai Python binding ที่วีร์ทำเอาไว้มาใช้บน Mac OS X + MacPorts ต้องดัดแปลง setup script นิดนึง

เนื่องจากผมติดตั้ง libthai ผ่านทาง MacPorts (ด้วยคำสั่ง sudo port install libthai) ดังนั้นแฟ้มไลบรารี (libthai.a) กับแฟ้ม include (*.h) ทั้งหลาย จึงไม่ได้อยู่ในตำแหน่งปกติที่ apple-gcc จะวิ่งไปหา (ผมใช้ i686-apple-darwin9-gcc-4.0.1 ลองใช้ gcc-4.2, gcc-mp-4.4 ที่อยู่ในเครื่องแล้ว มันบอกไม่รู้จัก flag โน้น flag นี้ ผมก็เซ็ตไม่เป็นด้วย เลยใช้ gcc ตัวที่เขาให้มาแต่เดิมนี่แหละ) จึงจำเป็นต้องแก้ไข setup.py นิดหน่อย เพื่อบอกตำแหน่งของ include_dirs และ library_dirs ใหม่ ตามนี้ :


from distutils.core import setup, Extension

setup(name="libthai", version="0.0.1",
      ext_modules=[ 
        Extension('libthai', 
                  include_dirs = ['/opt/local/include'],
                  libraries = ['thai'],
                  library_dirs = ['/opt/local/lib'],
                  sources = ['libthai.c']
)])

ก็จะสามารถ build และ install ได้ครับ – ของใครอยู่ที่อื่น ก็แก้ไปตามนั้นครับ –
ผมดูตัวอย่างจากเอกสารหน้านี้ : 3. Building C and C++ Extensions with distutils

หมายเหตุ: libthai ที่ใช้นี้ยังเป็นรุ่น 0.1.9 อยู่ ตอนนี้รุ่นล่าสุดคือ 0.1.11 ออกมาไล่ ๆ กับ libdatrie และ swath ตัวใหม่ ติดตามข่าวได้ที่ linux.thai.net / ขอบคุณคุณวีร์ พี่เทพ และทุกท่าน

อัปเดต 2009.04.21: เพิ่งเจอท่าที่ง่ายกว่า ไม่ต้องแก้ setup.py คือเรากำหนดไดเรกทอรีได้ที่บรรทัดคำสั่งเลย ตอน build จากนั้นค่อยสั่ง install อีกที เช่น :


$ sudo python setup.py build_ext --include-dirs=/opt/local/include --library-dirs=/opt/local/lib
$ sudo python setup.py install

หรือจะกำหนดไว้ในแฟ้ม setup.cfg ก็ได้ เผื่อใช้หลายรอบ :

[build_ext] include-dirs=/opt/local/include library-dirs=/opt/local/lib read more

Abracadacaba

อยากลองลง Abraca (XMMS2 client) แต่ build ไม่ผ่าน
มันอยากได้ GTK+ 2.8.0 เรามี 2.11.6 🙁
แก้ไงก็ไม่รู้ด้วย ใช้ระบบ build แปลก ๆ ชื่อ “waf”
(เป็น Python หมดเลย อ่านง่าย แต่ไม่เข้าใจ :P)

ใน Banshee ถึงแม้เวลานำเพลงเข้าไลบรารีมันจะตั้งชื่อโฟลเดอร์ให้ตามชื่อศิลปินและอัลบั้ม
แต่พอเปลี่ยนชื่อทีหลัง มันไม่ยอมเปลี่ยนชื่อโฟลเดอร์+ย้ายให้เรา (iTunes ทำให้) read more

Exaile

จากที่บ่น ๆ เรื่องโปรแกรมฟังเพลงบนลีนุกซ์ ไปครั้งที่แล้ว ตอนนี้เราคิดว่าเจอตัวที่ถูกใจแล้วแหละ

ใช้ Exaile มาได้แล้วซักพัก ใช้ได้ดีทีเดียว เล่นเพลงที่อยู่ในไอพ็อดได้ ก๊อปเพลงไปได้ แต่ว่าไม่มีฟังก์ชั่น sync นะ มีฟังก์ชั่นที่ชอบและไม่เคยเห็นที่ไหนมาก่อน ก็คือ Dynamic Playlist เป็นการไปดูข้อมูล “เพลงแนะนำ” จาก Last.fm แล้วก็เพิ่มเพลงพวกนั้น (ถ้ามีในเครื่อง) ลงใน playlist อัตโนมัติ เข้าท่า read more