Kesalahan Tatabahasa with Tagging
Contents
Kesalahan Tatabahasa with Tagging#
This tutorial is available as an IPython notebook at Malaya/example/tatabahasa-tagging.
This module only trained on standard language structure, so it is not save to use it for local language structure.
This interface deprecated, use HuggingFace interface instead.
[1]:
import os
os.environ['CUDA_VISIBLE_DEVICES'] = ''
[2]:
import logging
logging.basicConfig(level=logging.INFO)
[3]:
import malaya
from pprint import pprint
Model#
Common Seq2Seq model, P(yt | X, yt-1), one step decoder will generate yt
, and this required encoder output and output from last step decoder, yt-1
.
So we improve the model to general tags also, P(yt, zt | X, yt-1, zt-1), one step decoder will generate yt
and zt
, and this required encoder output and outputs from last step decoder, yt-1
and zt-1
.
We named this model as TransformerTag
.
There is no paper produced for this model, feel free to write a paper about it, check out our implementation at https://github.com/huseinzol05/malaya/tree/master/session/tatabahasa
[4]:
import warnings
warnings.filterwarnings('default')
List available Transformer models#
[5]:
malaya.tatabahasa.available_transformer()
/home/husein/dev/malaya/malaya/tatabahasa.py:156: DeprecationWarning: `malaya.tatabahasa.available_transformer` is deprecated, use `malaya.tatabahasa.available_huggingface` instead
warnings.warn(
INFO:malaya.tatabahasa:tested on 5k generated dataset at https://f000.backblazeb2.com/file/malay-dataset/tatabahasa/test-set-tatabahasa.pkl
[5]:
Size (MB) | Quantized Size (MB) | Sequence Accuracy | Sequence Tagging Accuracy | |
---|---|---|---|---|
small | 397.0 | 100.0 | 0.860198 | 0.963267 |
base | 875.0 | 220.0 | 0.938972 | 0.977407 |
Supported kesalahan tatabahasa#
For full description, check out https://tatabahasabm.tripod.com/tata/salahtata.htm
[6]:
malaya.tatabahasa.describe_tagging()
[6]:
class | Description | salah | betul | |
---|---|---|---|---|
0 | 0 | PAD | ||
1 | 1 | kesambungan subwords | ||
2 | 2 | tiada kesalahan | ||
3 | 3 | kesalahan frasa nama, Perkara yang diterangkan... | Cili sos | sos cili |
4 | 4 | kesalahan kata jamak | mereka-mereka | mereka |
5 | 5 | kesalahan kata penguat | sangat tinggi sekali | sangat tinggi |
6 | 6 | kata adjektif dan imbuhan "ter" tanpa penguat. | Sani mendapat markah yang tertinggi sekali. | Sani mendapat markah yang tertinggi. |
7 | 7 | kesalahan kata hubung | Sally sedang membaca bila saya tiba di rumahnya. | Sally sedang membaca apabila saya tiba di ruma... |
8 | 8 | kesalahan kata bilangan | Beribu peniaga tidak membayar cukai pendapatan. | Beribu-ribu peniaga tidak membayar cukai penda... |
9 | 9 | kesalahan kata sendi | Umar telah berpindah daripada sekolah ini bula... | Umar telah berpindah dari sekolah ini bulan lalu. |
10 | 10 | kesalahan penjodoh bilangan | Setiap orang pelajar | Setiap pelajar. |
11 | 11 | kesalahan kata ganti diri | Pencuri itu telah ditangkap. Beliau dibawa ke ... | Pencuri itu telah ditangkap. Dia dibawa ke bal... |
12 | 12 | kesalahan ayat pasif | Cerpen itu telah dikarang oleh saya. | Cerpen itu telah saya karang. |
13 | 13 | kesalahan kata tanya | Kamu berasal dari manakah ? | Kamu berasal dari mana ? |
14 | 14 | kesalahan tanda baca | Kamu berasal dari manakah . | Kamu berasal dari mana ? |
15 | 15 | kesalahan kata kerja tak transitif | Dia kata kepada saya | Dia berkata kepada saya |
16 | 16 | kesalahan kata kerja transitif | Dia suka baca buku | Dia suka membaca buku |
17 | 17 | penggunaan kata yang tidak tepat | Tembuk Besar negeri Cina dibina oleh Shih Huan... | Tembok Besar negeri Cina dibina oleh Shih Huan... |
Right now we only able to predict up to 15 different kesalahan tatabahasa, hopefully in the future we can scale this up.
Load Transformer Tag model#
def transformer(model: str = 'base', quantized: bool = False, **kwargs):
"""
Load Malaya transformer encoder-decoder + tagging model to correct a `kesalahan tatabahasa` text.
Parameters
----------
model: str, optional (default='base')
Check available models at `malaya.tatabahasa.available_transformer()`.
quantized: bool, optional (default=False)
if True, will load 8-bit quantized model.
Quantized model not necessary faster, totally depends on the machine.
Returns
-------
result: malaya.model.tf.Tatabahasa class
"""
[7]:
model = malaya.tatabahasa.transformer(model = 'base')
/home/husein/dev/malaya/malaya/tatabahasa.py:191: DeprecationWarning: `malaya.tatabahasa.transformer` is deprecated, use `malaya.tatabahasa.huggingface` instead
warnings.warn(
2022-11-16 22:23:39.470583: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2022-11-16 22:23:39.496105: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected
2022-11-16 22:23:39.496128: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: husein-MS-7D31
2022-11-16 22:23:39.496131: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: husein-MS-7D31
2022-11-16 22:23:39.496218: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:200] libcuda reported version is: Not found: was unable to find libcuda.so DSO loaded into this program
2022-11-16 22:23:39.496241: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:204] kernel reported version is: 470.141.3
/home/husein/dev/malaya/malaya/tokenizer.py:208: FutureWarning: Possible nested set at position 2253
self.tok = re.compile(r'({})'.format('|'.join(pipeline)))
/home/husein/dev/malaya/malaya/tokenizer.py:208: FutureWarning: Possible nested set at position 2771
self.tok = re.compile(r'({})'.format('|'.join(pipeline)))
Load Quantized model#
To load 8-bit quantized model, simply pass quantized = True
, default is False
.
We can expect slightly accuracy drop from quantized model, and not necessary faster than normal 32-bit float model, totally depends on machine.
[2]:
quantized_model = malaya.tatabahasa.transformer(model = 'base', quantized = True)
Predict using greedy decoder#
def greedy_decoder(self, strings: List[str]):
"""
Fix kesalahan tatatabahasa.
Parameters
----------
strings : List[str]
Returns
-------
result: List[str]
"""
For TransformerTag model, right now only supported greedy_decoder
method.
Randomly picked string in bahasa melayu wikipedia.
[7]:
# https://ms.wikipedia.org/wiki/Bola_sepak
string = 'Pada amnya, hanya penjaga gol sahaja yang dibenarkan menyentuh bola dengan tangan di dalam kawasan golnya'
[8]:
model.greedy_decoder([string])
[8]:
[[('Pada', 2),
('amnya', 2),
(',', 2),
('hanya', 2),
('penjaga', 2),
('gol', 2),
('sahaja', 2),
('yang', 2),
('dibenarkan', 2),
('menyentuh', 2),
('bola', 2),
('dengan', 2),
('tangan', 2),
('di', 2),
('dalam', 2),
('kawasan', 2),
('golnya', 2)]]
Now assumed we have kesalahan frasa nama, from penjaga gol
become gol penjaga
.
[9]:
# https://ms.wikipedia.org/wiki/Bola_sepak
string = 'Pada amnya, hanya gol penjaga sahaja yang dibenarkan menyentuh bola dengan tangan di dalam kawasan golnya'
[10]:
model.greedy_decoder([string])
[10]:
[[('Pada', 2),
('amnya', 2),
(',', 2),
('hanya', 2),
('penjaga', 3),
('gol', 3),
('sahaja', 2),
('yang', 2),
('dibenarkan', 2),
('menyentuh', 2),
('bola', 2),
('dengan', 2),
('tangan', 2),
('di', 2),
('dalam', 2),
('kawasan', 2),
('golnya', 2)]]
[11]:
string = 'Sani mendapat markah yang tertinggi sekali.'
string1 = 'Hassan ialah peserta yang termuda sekali dalam pertandingan itu.'
model.greedy_decoder([string, string1])
[11]:
[[('Sani', 2),
('mendapat', 2),
('markah', 2),
('yang', 2),
('tertinggi', 6),
('.', 2)],
[('Hassan', 2),
('ialah', 2),
('peserta', 2),
('yang', 2),
('termuda', 6),
('dalam', 2),
('pertandingan', 2),
('itu', 2),
('.', 2)]]
[12]:
string = 'Dia kata kepada saya.'
model.greedy_decoder([string])
[12]:
[[('Dia', 2), ('berkata', 15), ('kepada', 2), ('saya', 2), ('.', 2)]]
[13]:
import pickle
with open('tests/dataset-tatabahasa.pkl', 'rb') as fopen:
test_set = pickle.load(fopen)
len(test_set)
[13]:
100
[14]:
def get_xy(row):
x, y, tag = [], [], []
for i in range(len(row[0])):
t = [row[0][i][0]]
y.extend(t)
t = [row[1][i][0]]
x.extend(t)
tag.extend([row[1][i][1]] * len(t))
return ' '.join(x), ' '.join(y), tag
[15]:
x, y, t = get_xy(test_set[0])
x, y, t
[15]:
('Dirk Jan Klaas " Klaas-Jan " Huntelaar ( lahir 12 Ogos 1983 ) merupakan pemain bola sepak Belanda yang bermain seperti posisi penyerang !',
'Dirk Jan Klaas " Klaas-Jan " Huntelaar ( lahir 12 Ogos 1983 ) merupakan pemain bola sepak Belanda yang bermain di posisi penyerang .',
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, 14])
[16]:
model.greedy_decoder([x])
[16]:
[[('Dirk', 2),
('Jan', 2),
('Klaas', 2),
('"', 2),
('Klaas-Jan', 2),
('"', 2),
('Huntelaar', 2),
('(', 2),
('lahir', 2),
('12', 2),
('Ogos', 2),
('1983', 2),
(')', 2),
('merupakan', 2),
('pemain', 2),
('bola', 2),
('sepak', 2),
('Belanda', 2),
('yang', 2),
('bermain', 2),
('di', 9),
('posisi', 2),
('penyerang', 2),
('.', 14)]]
[17]:
quantized_model.greedy_decoder([x])
[17]:
[[('Dirk', 2),
('Jan', 2),
('Klaas', 2),
('"', 2),
('Klaas-Jan', 2),
('"', 2),
('Huntelaar', 2),
('(', 2),
('lahir', 2),
('12', 2),
('Ogos', 2),
('1983', 2),
(')', 2),
('merupakan', 2),
('pemain', 2),
('bola', 2),
('sepak', 2),
('Belanda', 2),
('yang', 2),
('bermain', 2),
('di', 9),
('posisi', 2),
('penyerang', 2),
('.', 14)]]
[18]:
x, y, t = get_xy(test_set[-1])
x, y, t
[18]:
('Pada tahun 2002 , kedua-dua gol beliau menduduki tempat ke-6 dalam 100 Greatest Sporting Moments oleh saluran Channel 4 UK .',
'Pada tahun 2002 , kedua-dua gol ini menduduki tempat ke-6 dalam 100 Greatest Sporting Moments oleh saluran Channel 4 UK .',
[2, 2, 2, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
[19]:
model.greedy_decoder([x])
[19]:
[[('Pada', 2),
('tahun', 2),
('2002', 2),
(',', 2),
('kedua-dua', 2),
('gol', 2),
('beliau', 2),
('menduduki', 2),
('tempat', 2),
('ke-6', 2),
('dalam', 2),
('100', 2),
('Greatest', 2),
('Sporting', 2),
('Moments', 2),
('oleh', 2),
('saluran', 2),
('Channel', 2),
('4', 2),
('UK', 2),
('.', 2)]]
[20]:
x, y, t = get_xy(test_set[-2])
x, y, t
[20]:
('Gol inilah yang bergelar Goal of the Century dengan undian Internet 2000 sejak FIFA .',
'Gol inilah yang bergelar Goal of the Century di undian Internet 2000 oleh FIFA .',
[2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 2])
[21]:
model.greedy_decoder([x])
[21]:
[[('Gol', 2),
('inilah', 2),
('yang', 2),
('bergelar', 2),
('Goal', 2),
('of', 2),
('the', 2),
('Century', 2),
('dengan', 2),
('undian', 2),
('Internet', 2),
('2000', 2),
('sejak', 2),
('FIFA', 2),
('.', 2)]]
[22]:
x, y, t = get_xy(test_set[-3])
x, y, t
[22]:
('Beliau mengambil bola dalam kawasan kepul diri lalu pusing dan luru lebih separuh padang sambil menyentuh bola 11 kali , memintas lima pemain England : ( Glenn Hoddle , Peter Reid , Kenny Sansom , Terry Butcher , dan Terry Fenwick ) serta penjaga gawang Peter Shilton .',
'Beliau mengambil bola di kawasan pasukan diri lalu berpusing-pusing dan meluru lebih separuh padang sambil menyentuh bola 11 kali , memintas lima pemain England : ( Glenn Hoddle , Peter Reid , Kenny Sansom , Terry Butcher , dan Terry Fenwick ) serta penjaga gawang Peter Shilton .',
[2,
2,
2,
9,
2,
10,
2,
2,
15,
2,
15,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2])
[23]:
model.greedy_decoder([x])
[23]:
[[('Beliau', 2),
('mengambil', 2),
('bola', 2),
('dari', 9),
('kawasan', 2),
('kaki', 10),
('diri', 2),
('lalu', 2),
('berpusing', 15),
('dan', 2),
('meluru', 15),
('lebih', 2),
('separuh', 2),
('padang', 2),
('sambil', 2),
('menyentuh', 2),
('bola', 2),
('11', 2),
('kali', 2),
(',', 2),
('memintas', 2),
('lima', 2),
('pemain', 2),
('England', 2),
(':', 2),
('(', 2),
('Glenn', 2),
('Hoddle', 2),
(',', 2),
('Peter', 2),
('Reid', 2),
(',', 2),
('Kenny', 2),
('Sansom', 2),
(',', 2),
('Terry', 2),
('Butcher', 2),
(',', 2),
('dan', 2),
('Terry', 2),
('Fenwick', 2),
(')', 2),
('serta', 2),
('penjaga', 2),
('gawang', 2),
('Peter', 2),
('Shilton', 2),
('.', 2)]]
[24]:
quantized_model.greedy_decoder([x])
[24]:
[[('Beliau', 2),
('mengambil', 2),
('bola', 2),
('dari', 9),
('kawasan', 2),
('kaki', 10),
('diri', 2),
('lalu', 2),
('berpusing', 15),
('dan', 2),
('meluru', 15),
('lebih', 2),
('separuh', 2),
('padang', 2),
('sambil', 2),
('menyentuh', 2),
('bola', 2),
('11', 2),
('kali', 2),
(',', 2),
('memintas', 2),
('lima', 2),
('pemain', 2),
('England', 2),
(':', 2),
('(', 2),
('Glenn', 2),
('Hoddle', 2),
(',', 2),
('Peter', 2),
('Reid', 2),
(',', 2),
('Kenny', 2),
('Sansom', 2),
(',', 2),
('Terry', 2),
('Butcher', 2),
(',', 2),
('dan', 2),
('Terry', 2),
('Fenwick', 2),
(')', 2),
('serta', 2),
('penjaga', 2),
('gawang', 2),
('Peter', 2),
('Shilton', 2),
('.', 2)]]
More examples#
I just copy pasted from https://ms.wikipedia.org/wiki/Kesalahan_biasa_tatabahasa_Melayu
[26]:
string = 'Tidak ada apa yang mereka risaukan waktu itu.'
model.greedy_decoder([string])
[26]:
[[('Tidak', 2),
('ada', 2),
('apa', 2),
('yang', 2),
('mereka', 2),
('risaukan', 2),
('waktu', 2),
('itu', 2),
('.', 2)]]
[27]:
string = 'Ayahnya setuju walaupun melanggar syarat yang dia sendiri menetapkan.'
model.greedy_decoder([string])
[27]:
[[('Ayahnya', 2),
('setuju', 2),
('dan', 7),
('melanggar', 2),
('syarat', 2),
('yang', 2),
('dia', 2),
('sendiri', 2),
('menetapkan', 2),
('.', 2)]]
[28]:
string = 'Semuanya dia kenal.'
model.greedy_decoder([string])
[28]:
[[('Semuanya', 2), ('dia', 2), ('terkenal', 15), ('.', 2)]]
[29]:
string = 'Dia menjawab seperti disuruh-suruh oleh kuasa yang dia tidak tahu dari mana puncanya.'
model.greedy_decoder([string])
[29]:
[[('Dia', 2),
('menjawab', 2),
('seperti', 2),
('disuruh-suruh', 2),
('oleh', 2),
('kuasa', 2),
('yang', 2),
('dia', 2),
('tidak', 2),
('tahu', 2),
('dari', 2),
('mana', 2),
('puncanya', 2),
('.', 2)]]
[30]:
string = 'Bola ini ditendang oleh saya.'
model.greedy_decoder([string])
[30]:
[[('Bola', 2),
('ini', 2),
('ditendang', 2),
('oleh', 2),
('saya', 2),
('.', 2)]]
[31]:
string = 'Makanan ini kamu telah makan?'
model.greedy_decoder([string])
[31]:
[[('Makanan', 2),
('ini', 2),
('kamu', 2),
('telah', 2),
('makan', 2),
('.', 14)]]
[32]:
string = 'Segala perubahan yang berlaku kita akan menghadapi sama-sama.'
model.greedy_decoder([string])
[32]:
[[('Segala', 2),
('perubahan', 2),
('yang', 2),
('berlaku', 2),
('kita', 2),
('akan', 2),
('menghadapi', 2),
('sama-sama', 2),
('.', 2)]]
[33]:
string = 'Kakak saya sedang memasak gulai nangka. Dia menyenduk seketul nangka gulai dan menyuruh saya merasanya.'
model.greedy_decoder([string])
[33]:
[[('Kakak', 2),
('saya', 2),
('sedang', 2),
('memasak', 2),
('gulai', 2),
('nangka', 2),
('.', 2),
('Dia', 2),
('menyenduk', 2),
('seketul', 2),
('gulai', 3),
('nangka', 3),
('dan', 2),
('menyuruh', 2),
('saya', 2),
('merasanya', 2),
('.', 2)]]
[34]:
string = 'Sally sedang membaca bila saya tiba di rumahnya.'
model.greedy_decoder([string])
[34]:
[[('Sally', 2),
('sedang', 2),
('membaca', 2),
('bila', 2),
('dia', 11),
('tiba', 2),
('di', 2),
('rumahnya', 2),
('.', 2)]]
[35]:
string = 'Badannya besar kecuali kakinya kecil.'
model.greedy_decoder([string])
[35]:
[[('Badannya', 2),
('besar', 2),
('dan', 7),
('kakinya', 2),
('kecil', 2),
('.', 2)]]
[36]:
string = 'Beribu peniaga tidak membayar cukai pendapatan.'
model.greedy_decoder([string])
[36]:
[[('Beribu', 2),
('peniaga', 2),
('tidak', 2),
('membayar', 2),
('cukai', 2),
('pendapatan', 2),
('.', 2)]]
[37]:
string = 'Setengah remaja suka membuang masa di pasar raya.'
model.greedy_decoder([string])
[37]:
[[('Setengah', 2),
('remaja', 2),
('suka', 2),
('membuang', 2),
('masa', 2),
('di', 2),
('pasar', 2),
('raya', 2),
('.', 2)]]
[38]:
string = 'Umar telah berpindah daripada sekolah ini bulan lalu.'
model.greedy_decoder([string])
[38]:
[[('Umar', 2),
('telah', 2),
('berpindah', 2),
('daripada', 2),
('sekolah', 2),
('ini', 2),
('bulan', 2),
('lalu', 2),
('.', 2)]]
[39]:
string = 'Para-para peserta sedang berbaris.'
model.greedy_decoder([string])
[39]:
[[('Para', 4), ('peserta', 2), ('sedang', 2), ('berbaris', 2), ('.', 2)]]
[ ]: