POS Tagger Bahasa Indonesia dengan Python

Feb 2018

Posting sebelumnya: POS Tagger dengan Syntaxnet

Posting terkait: POS Tagger dan Dependency Parser dengan StanfordNLP

Secara bertahap, saya dan istri akan migrasi dari Java ke Python. Salah satu yang kami perlukan adalah POS (Part of Speech)-Tagger Bahasa Indonesia.

Ini cara yang paling sederhana  karena saya sudah sediakan modelnya, untuk cara trainingnya ada di bagian bawah.

Saya menggunakan CRFTagger, jadi library yang perlu diinstall: numpy, nltk dan python-crfsuite.

Lalu download pretrained model (1.6MB) yang saya buat berdasarkan data Fam Rashel (200rb-an token) di https://drive.google.com/open?id=12yJ82GzjnqzrjX14Ob_p9qnPKtcSmqAx

Untuk menggunakannya (sesuaikan path jika diperlukan):

from nltk.tag import CRFTagger
ct = CRFTagger()
ct.set_model_file('all_indo_man_tag_corpus_model.crf.tagger')
hasil = ct.tag_sents([['Saya','bekerja','di','Bandung']])
print(hasil)

Hasilnya akan seperti ini:

[[(‘Saya’, ‘PRP’), (‘bekerja’, ‘VB’), (‘di’, ‘IN’), (‘Bandung’, ‘NNP’)]]

Selesai… gampang kan 🙂

Jika ada yang berminat untuk training sendiri, ada beberapa dataset POS-Tag Bahasa Indonesia:

https://github.com/UniversalDependencies/UD_Indonesian
https://github.com/famrashel/idn-tagged-corpus
http://www.panl10n.net/english/OutputsIndonesia2.htm
https://lindat.mff.cuni.cz/repository/xmlui/handle/11234/1-1989

Saya menggunakan data milik Fam Rashel, code untuk training-nya adalah sbb (mungkin belum efisien, saya masih belajar Python):

from nltk.tag import CRFTagger

jumSample = 500000
namaFile = "/home/yudiwbs/dataset/pos-tag-indonesia/idn-tagged-corpus-master/Indonesian_Manually_Tagged_Corpus.tsv"
with open(namaFile, 'r', encoding='utf-8') as f:
    lines = f.read().split('\n')

pasangan = []
allPasangan = []

for line in lines[: min(jumSample, len(lines))]:
    if line == '':
        allPasangan.append(pasangan)
        pasangan = []
    else:
        kata, tag = line.split('\t')
        p = (kata,tag)
        pasangan.append(p)

ct = CRFTagger()
ct.train(allPasangan,'all_indo_man_tag_corpus_model.crf.tagger')
#test
hasil = ct.tag_sents([['Saya','bekerja','di','Bandung'],['Nama','saya','Yudi']])
print(hasil)

Dokumentasi lengkap tentang lib POS-Tag NLTK dapat dilihat di: http://www.nltk.org/api/nltk.tag.html 

Untuk sekarang saya belum buat pengukuran kinerja model yang dihasilkan.

45 tanggapan untuk “POS Tagger Bahasa Indonesia dengan Python”

    1. Di posting tambahkan saja
      [[code language="python"]] [[/code]]
      (kurung siku-nya satu saja, ini saya jadikan dua karena kalau tidak di-comment jadi hilang)
      seingat saya sudah disediakan WordPress (tdk perlu install plugin)

      1. iya pak Alhmduliilah sudah berhasil, sy nanya lagi pak, boleh ya,

        misalkan sya sudah memeperoleh hasil seperti diatas [[(‘Saya’, ‘PRP’), (‘bekerja’, ‘VB’), (‘di’, ‘IN’), (‘Bandung’, ‘NNP’)]], selanjutnya jika sy hanya ingin memanggil hasil pos tag saja misalnya:

        [‘PRP’, ‘VB’, ‘IN’, ‘NNP’], kira-kira bagaimana yah pak?? seolahnya sy masih bingung variabel mana yang dijadikan sebagai key? terimakasih

      2. for tokenTag in hasil[0]:
              token, tag = tokenTag;
              print(token+”–>”+tag);

        itu hasilnya 2 nested array lalu didalamnya tuple.

      3. Baik pak terima kasih, oh ya pak boleh saya tahu corpus yang bapak gunakan pada post tag ini, soalnya saya berniat memasukan post tag bpk di tugas sy, tapi saya membutuhkan data corpusnya sebagai pelaporannya? sebelumnya terimakasih pak dan mohon bantuannya.

    1. Code yang atas untuk menggunakan pretrained model (model yang sudah ditrain oleh saya, tinggal pake), code yang bawah kalau mau buat model sendiri.

  1. permisi mas, kalau saya mau membaca file pretrained model yang mas sediakan pakai apa ya? saya mencoba untuk memakai notepad++ tidak bisa

  2. waaah penelitian nya sama pak, bisa di jadikan literatur, bookmark dulu. hee terima kasih pak yudiwbs. kemaren buat SPOK dengan python dan NLTK, POSTAG yang di pake miliki alfan f. wicaksono. semoga kedepan trus berkembang penelitian nya pak.

      1. Udah solve pak. Untuk keempat data training itu apa bapa udh dicoba semua? Kira-kira lebih akurat yg mana dari keempat daya training tsb?

  3. Pak, saya mengikuti kode yg bapak tuliskan (kode yg paling bawah). Dengan data text milik saya sendiri. Sebelumnya saya juga pakai POSTAG milik Fam Rashel, tapi saya lgsg clone dari repositori mereka dan menjalankan file shell (./tag.sh) sesuai dengan tutorial yg mereka berikan di github. Saya bandingkan dgn cara yg bapak lakukan ini (python + nltk), hasil tagging-nya banyak yg berbeda. Kira2 itu kenapa ya pak?

  4. Cara yang paling gampang ikuti posting ini lalu jadikan dataset anda jadi input. Jadi deh berlabel. Tinggal ada perbaiki saja label yang salah.

    1. maksudnya konversi dari apa ke mana? Kalau dari corpus pos tag yg saya gunakan di contoh ini, buat saja script kecil untuk mengkonversi.

  5. Maaf Pak, itu isi file (all_indo_man_tag_corpus_model.crf.tagger) apa bisa di edit ? kalau bisa menggunakan software apa ?? mohon jawabannya ya pak, ini terkait dengan skripsi saya. terimakasih

  6. Mohon maaf Pak, ini saya eror “NameError: name ‘pycrfsuite’ is not defined”
    saya cari solusi tidak ketemu-ketemu. Mohon informasinya

      1. Saya juga memiliki masalah yang sama pak. name ‘pycrfsuite’ is not defined .
        Padahal sudah install python-crfsuite. gimana ya ?

  7. Saya juga memiliki masalah seperti itu. Mohon bantuannya Pak termakasih.

  8. Selamat siang pak Yudi. terima asih atas artikelnya. sudah saya gunakan CRFTagger diatas untuk tesis saya. Pak Yudi, saya mohon info tentang keterangan kelas kata yang digunakan di dalamnya. Ada NNP, FW, CD, NEG. Mungkin ada informasi lengkapnya pak. ? terima kasih

  9. Pak Yudi, saya melakukan pos tagging pada sebuah kalimat, yg di dalamnya terdapat kata hoax muncul 4-5 kali. Hasil pos tagging pada kata hoax, tersebut, beberapa memasukkannya dalam ‘FW’, tetapi ada juga yang memasukkannya dalam ‘NN’. mengapa bisa demikian ya pak ?
    from nltk.tag import CRFTagger

    ct = CRFTagger()
    ct.set_model_file(‘data/all_indo_man_tag_corpus_model.crf.tagger’)

    hasil = ct.tag_sents([[‘simak’, ‘berita’, ‘berikut’, ‘ini’, ‘sejarah’, ‘mencatat’, ‘bahwa’, ‘hoax’, ‘bukan’, ‘hal’, ‘baru’, ‘berita’, ‘hoax’, ‘beragam’, ‘baik’, ‘dalam’, ‘dunia’, ‘sains’, ‘dunia’, ‘militer’, ‘bahkan’, ‘dalam’, ‘urusan’, ‘agama’, ‘sekalipun’, ‘mulai’, ‘dari’, ‘hoax’, ‘yang’, ‘berakibat’, ‘serius’, ‘hingga’, ‘hoax’, ‘sepele’, ‘yang’, ‘sekadar’, ‘memancing’, ’emosi’, ‘para’, ‘pembaca’, ‘perkembangan’, ‘teknologi’, ‘memudahkan’, ‘manusia’, ‘mengakses’, ‘informasi’, ‘apapun’, ‘namun’, ‘dibalik’, ‘kemudahan’, ‘tersebut’, ‘informasi’, ‘palsu’, ‘atau’, ‘hoax’, ‘bermunculan’, ‘dan’, ‘menimbulkan’, ‘perpecahan’, ‘hoax’, ‘merusak’, ‘hubungan’, ‘baik’, ‘antar’, ‘masyarakat’, ‘di’, ‘desa’, ‘a’, ‘seorang’, ‘pria’, ‘diamuk’, ‘massa’, ‘karena’, ‘dituduh’, ‘sebagai’, ‘penculik’, ‘anak’, ‘saat’, ‘itu’, ‘dia’, ‘berniat’, ‘untuk’, ‘menjenguk’, ‘cucunya’, ‘yang’, ‘baru’, ‘lahir’, ‘dirinya’, ‘kebingungan’, ‘mencari’, ‘rumah’, ‘anaknya’, ‘warga’, ‘yang’, ‘melihatnya’, ‘langsung’, ‘curiga’, ‘dan’, ‘menuduhnya’, ‘sebagai’, ‘pelaku’, ‘penculikan’, ‘anak’, ‘tuduhan’, ‘tersebut’, ‘didasarkan’, ‘pada’, ‘berita’, ‘hoax’, ‘yang’, ‘beredar’, ‘kala’, ‘itu’, ‘tanpa’, ‘berusaha’, ‘mencari’, ‘info’, ‘lebih’, ‘lanjut’, ‘para’, ‘warga’, ‘lantas’, ‘mengeroyok’, ‘pria’, ‘tersebut’, ‘keluarga’, ‘korban’, ‘tidak’, ‘terima’, ‘dan’, ‘kerusuhan’, ‘berlanjut’, ‘sumber’, ‘diakses’, ‘februari’, ‘jika’, ‘dikaitkan’, ‘dengan’, ‘nilai’, ‘pancasila’, ‘isi’, ‘berita’, ‘tersebut’, ‘bertentangan’, ‘dengan’, ‘nilai’, ‘pancasila’, ‘terutama’, ‘nilai’]])
    hasil
    [[(‘simak’, ‘NN’),
    (‘berita’, ‘NN’),
    (‘berikut’, ‘NN’),
    (‘ini’, ‘PR’),
    (‘sejarah’, ‘NN’),
    (‘mencatat’, ‘VB’),
    (‘bahwa’, ‘SC’),
    (‘hoax’, ‘FW’),
    (‘bukan’, ‘NEG’),
    (‘hal’, ‘NN’),
    (‘baru’, ‘JJ’),
    (‘berita’, ‘NN’),
    (‘hoax’, ‘NN’),

    1. masuk ke spam commentnya gara2 dump kata 🙂 Masalah hasil tag ya tergantung data trainingnya. Jangan-jangan data trainingnya nggak ada kata “hoax”

  10. Terima kasih atas informasi yang baik.
    Dalam tokenisasi, “kereta api” terbagi menjadi “kereta” dan “api” meskipun diperlakukan sebagai satu kata yang berarti kereta api.
    Bagaimana Anda menangani karakteristik bahasa dari kata kompleks ini di Indonesia?

Tinggalkan komentar