26 มกราคม 2560

Published มกราคม 26, 2560 by with 6 comments

Word2Vec ด้วย Gensim ใน Python


Word2Vec คืออะไร ?


ภาพจาก http://gensim.narkive.com/RavqZorK/gensim-4914-graphic-representations-of-word2vec-and-doc2vec

Word2Vec เป็นอัลกอริทึมสอนคอมพิวเตอร์ให้เรียนรู้ภาษาของมนุษย์ โดยอัลกอริทึม Word2Vec จะเรียนรู้ทิศการดำเนินการแทนของคำ ( learning vector representations of words) ที่เรียกว่า "word embeddings" พัฒนาโดย  Mikolov et al นักวิจัยจากกูเกิล


แหล่งข้อมูลอ้างอิง : https://opensource.googleblog.com/2013/08/learning-meaning-behind-words.html และ https://en.wikipedia.org/wiki/Word2vec




สำหรับ Word2Vec ในภาษา Python มีโมดูลที่ชื่อว่า Gensim ซึ่งเป็นโมดูลด้าน Vector Space Modelling ในภาษา Python
ติดตั้งได้ด้วยคำสั่ง : pip install -U gensim

สำหรับในบทความนี้จะเริ่มต้น Word2Vec กับภาษาไทยเลย เพื่อเป็นแนวทางให้ผู้สนใจนำไปใช้งานศึกษาต่อไป

ก่อนอื่นให้ทำการติดตั้ง pythainlp ด้วยคำสั่ง (รองรับเฉพาะ Python 3 เท่านั้น)  : pip3 install pythainlp

เมื่อทำการติดตั้งเสร็จแล้ว ต่อไปมาลองทำ Word2Vec ภาษาไทยในภาษา Python ด้วยโมดูล Gensim กัน
from gensim.models import Word2Vec
from pythainlp.tokenize import word_tokenize
a = ['ฉันรักภาษาไทยเพราะฉันเป็นคนไทยและฉันเป็นคนไทย' ,'ฉันเป็นนักเรียนที่ชื่นชอบวิทยาศาสตร์และเทคโนโลยี' ,'ฉันไม่ใช่โปรแกรมเมอร์เพราะฉันทำมากกว่าคิดเขียนพัฒนาโปรแกรมทดสอบโปรแกรม','ฉันชื่นชอบวิทยาศาสตร์ชอบค้นคว้าตั้งสมมุติฐานและหาคำตอบ']
b = [list(word_tokenize(i)) for i in a] # ทำการตัดคำแล้วเก็บใน list จะได้เป็น [['ฉัน',...],['ฉัน',...]...]
model = Word2Vec(b, min_count=1)
aa=model.similar_by_word('เป็น')
print(aa)

ผลลัพธ์

[('ที่', 0.1925012469291687), ('ทดสอบ', 0.15317942202091217), ('คิด', 0.14165477454662323), ('โปรแกรมเมอร์', 0.12399782985448837), ('คำตอบ', 0.10198801755905151), ('รัก', 0.08067327737808228), ('เขียน', 0.06275061517953873), ('เทคโนโลยี', 0.04377558082342148), ('วิทยาศาสตร์', 0.023449702188372612), ('ภาษาไทย', 0.01843630149960518)]

หากเราต้องการผลลัพธ์ที่แม่นยำยิ่งขึ้น ต้องเพิ่มข้อมูลอีกจำนวนมากลงไปให้ Word2Vec ต่อไป เราจึงนำข้อมูลจากวิกิพีเดีย มาใช้งานกับ Word2Vec ดังนี้
คำเตือน !
กรุณาทำในคอมพิวเตอร์ที่มี CPU 1.5 Ghz ขึ้นไป แรมว่างขั้นต่ำ 2 GB เนื้อที่ว่าง 10 GB ขึ้นไป

ให้ทำการโหลดไฟล์ข้อมูลวิกิพีเดียภาษาไทยจาก https://dumps.wikimedia.org/thwiki/latest/thwiki-latest-pages-articles.xml.bz2

ให้ทำการสร้างไฟล์ process_wiki.py และ train_word2vec_model.py โดยมีโค้ดตามนี้
ไฟล์ process_wiki.py

ไฟล์ train_word2vec_model.py


แล้วรันคำสั่ง :
python process_wiki.py thwiki-latest-pages-articles.xml.bz2 wiki.th.text
python train_word2vec_model.py wiki.th.text wiki.th.text.model wiki.th.text.vector

จะได้ไฟล์ข้อมูลพร้อมใช้งานสำหรับทำ Word2Vec ภาษาไทย

เมื่อได้ข้อมูลพร้อมใช้งานแล้ว ต่อไปมาเริ่มการนำไฟล์ข้อมูลมาใช้ทำ Word2Vec ภาษาไทย
import gensim
model = gensim.models.Word2Vec.load("wiki.th.text.model")
print(model.most_similar("แมว"))
ผลลัพธ์

[('แรด', 0.6538625359535217),
('ควาย', 0.6497683525085449),
('กระรอก', 0.6443219780921936),
('แพะ', 0.6345915198326111),
('หอย', 0.6138527393341064),
('แกะ', 0.6061760187149048),
('ปลา', 0.5980139374732971),
('กวาง', 0.5922517776489258),
('นกแก', 0.5808144211769104),
('ไก', 0.5719783306121826)]

เมื่อลองใช้ Word2Vec กับคำว่า "python"

print(model.most_similar("python"))

ผลลัพธ์

[('java', 0.8321578502655029),
('perl', 0.7901885509490967),
('javascript', 0.7829481959342957),
('ssl', 0.7799789905548096),
('txt', 0.7792744040489197),
('unicode', 0.7791136503219604),
('array', 0.7735886573791504),
('gel', 0.769564151763916),
('api', 0.7694711685180664),
('user', 0.7688018083572388)]
นอกจากนี้ยังมีวิธีการทำ Word2Vec ที่น่าสนใจอ่านได้ที่ thai2vec - Language Modeling, Word2Vec and Text Classification in Thai Language
อ่านเอกสาร gensim word2vec เพิ่มเติมได้ที่ https://radimrehurek.com/gensim/models/word2vec.html

เขียนบทความโดย นาย วรรณพงษ์  ภัททิยไพบูลย์ ที่ https://python3.wannaphong.com/

6 ความคิดเห็น:

  1. ผมเอาโค้ดไปลองแล้วมันมีคำว่า แมว คำว่า โรงพยาบาล แต่มันไม่มีคำหลายคำเลยครับ เช่นคำว่า เป็น

    print(model.most_similar('เป็น'))
    Traceback (most recent call last):
    File "", line 1, in
    File "/usr/local/lib/python3.6/site-packages/gensim/utils.py", line 1398, in new_func1
    return func(*args, **kwargs)
    File "/usr/local/lib/python3.6/site-packages/gensim/models/base_any2vec.py", line 696, in most_similar
    return self.wv.most_similar(positive, negative, topn, restrict_vocab, indexer)
    File "/usr/local/lib/python3.6/site-packages/gensim/models/keyedvectors.py", line 365, in most_similar
    mean.append(weight * self.word_vec(word, use_norm=True))
    File "/usr/local/lib/python3.6/site-packages/gensim/models/keyedvectors.py", line 274, in word_vec
    raise KeyError("word '%s' not in vocabulary" % word)
    KeyError: "word 'เป็น' not in vocabulary"

    แบบนี้ต้องทำยังไงครับ

    ตอบลบ
    คำตอบ
    1. https://github.com/Kyubyong/wordvectors ลองเจ้านี้ครับ แล้วทำเป็น .text ออกมา แล้วค่อยเอา .text ที่ตัดทำแล้วมาเข้าของเจ้านี้ต่อ

      ลบ
  2. ผม run
    คำสั่งนี้ python process_wiki.py thwiki-latest-pages-articles.xml.bz2 wiki.th.text
    แล้วขึ้นแบบนี้ครับ
    File "process_wiki.py", line 27, in
    list1=space.join(text)
    TypeError: sequence item 0: expected a bytes-like object, str found

    ตอบลบ
  3. ไม่ระบุชื่อ6 เมษายน 2562 เวลา 00:53

    space เป็นตัวแปร byte แต่ว่า text เป็น str ค่ะ
    ลองแก้สองที่ space = u" " แล้วก็บรรทัดที่ 27 แก้เป็น output.write((list1) + "\n")

    ตอบลบ
  4. มีโค้ดของไฟล์ process_wiki.py และ train_word2vec_model.py มั้ยคับ ผมหาไม่เจอ

    ตอบลบ

แสดงความคิดเห็นได้ครับ :)