Text Augmentation#

This tutorial is available as an IPython notebook at Malaya/example/augmentation.

[1]:
import os

os.environ['CUDA_VISIBLE_DEVICES'] = ''
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
[2]:
%%time

import malaya
/home/husein/dev/malaya/malaya/tokenizer.py:202: FutureWarning: Possible nested set at position 3361
  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))
/home/husein/dev/malaya/malaya/tokenizer.py:202: FutureWarning: Possible nested set at position 3879
  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))
CPU times: user 3.07 s, sys: 3.45 s, total: 6.52 s
Wall time: 2.05 s

Why augmentation#

Let say you have a very limited labelled corpus, and you want to add more, but labelling is very costly.

So, text augmentation! We provided few augmentation interfaces in Malaya.

Load Synonym#

Use dictionary of synonym to replace words with it synonyms. Synonym data from Malaya-Dataset/90k-synonym.

def synonym(
    string: str,
    threshold: float = 0.5,
    top_n = 5,
    **kwargs
):
    """
    augmenting a string using synonym, https://github.com/huseinzol05/Malaya-Dataset#90k-synonym

    Parameters
    ----------
    string: str
        this string input assumed been properly tokenized and cleaned.
    threshold: float, optional (default=0.5)
        random selection for a word.
    top_n: int, (default=5)
        number of nearest neighbors returned. Length of returned result should as top_n.

    Returns
    -------
    result: List[str]
    """
[3]:
string = 'saya suka makan ayam dan ikan'
text = 'Perdana Menteri berkata, beliau perlu memperoleh maklumat terperinci berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang tindakan lanjut. Bagaimanapun, beliau yakin masalah itu dapat diselesaikan dan pentadbiran kerajaan boleh berfungsi dengan baik.'
[4]:
tokenizer = malaya.preprocessing.Tokenizer()
[5]:
malaya.augmentation.synonym(' '.join(tokenizer.tokenize(string)))
[5]:
['saya disukai suruh ayam dan ikan',
 'saya menerima suruh ternakan dan ikan',
 'saya menerima menyuruh ternakan dan ikan',
 'saya meraba suruh ternakan dan ikan',
 'saya meraba makan ternakan dan ikan']
[6]:
malaya.augmentation.synonym(' '.join(tokenizer.tokenize(text)))
[6]:
['Utama Menteri membaca , beliau memerlukan memperoleh Maklumat terperinci berhubung hal berkenaan dulu jajahan dapat mengambil sebarang tindakan lanjut . Bagaimanapun , beliau yakin kesusahan itu dapat diselesaikan dan pemberian ranah boleh berkesan dengan cikgu .',
 'Utama Menteri membaca , beliau mengakibatkan beruntung Maklumat terperinci berhubung tajuk berkenaan sebelumnya jajahan dapat mengambil sebarang tindakan lanjut . masih , beliau yakin masalah itu dapat diselesaikan dan pemberian kekaisaran boleh bergeser dengan cikgu .',
 'Primer gajah membaca , beliau membawa bernasib Baik maklumat terperinci menghayati tajuk berkenaan sebelumnya kerajaan dapat mengambil sebarang tindakan lama . masih , beliau yakin masalah itu dapatkan diselesaikan dan konsesi negara boleh gores dengan pendidik .',
 'Utama menteri membaca , beliau berakhir bernasib Baik maklumat terperinci menghasut tujuannya berkenaan sebelumnya pentadbiran berupaya lukai sebarang sijil jauh . masih , beliau aman masalah itu dapatkan diselesaikan dan penyerahan keadaan mampu takuk dengan pendidikan .',
 'Perdana menteri membaca , beliau berakhir bernasib Baik maklumat terperinci menghasut tujuannya berkenaan sebelumnya strategi berupaya mencemarkan sebarang tindakan jauh . masih , beliau aman masalah itu dapatkan diselesaikan dan penyerahan keadaan mahir gores dengan perintah .']

Load Wordvector#

dictionary of synonym is quite hard to populate, required some domain experts to help us. So we can use wordvector to find nearest words.

def wordvector(
    string: str,
    wordvector,
    threshold: float = 0.5,
    top_n: int = 5,
    soft: bool = False,
):
    """
    augmenting a string using wordvector.

    Parameters
    ----------
    string: str
    wordvector: object
        wordvector interface object.
    threshold: float, optional (default=0.5)
        random selection for a word.
    soft: bool, optional (default=False)
        if True, a word not in the dictionary will be replaced with nearest jarowrinkler ratio.
        if False, it will throw an exception if a word not in the dictionary.
    top_n: int, (default=5)
        number of nearest neighbors returned. Length of returned result should as top_n.

    Returns
    -------
    result: List[str]
    """
[7]:
vocab_wiki, embedded_wiki = malaya.wordvector.load(model = 'wikipedia')
word_vector_wiki = malaya.wordvector.WordVector(embedded_wiki, vocab_wiki)
Load pretrained wordvector into `malaya.wordvector.WordVector` class will disable eager execution.
2022-09-15 22:13:34.223920: 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-09-15 22:13:34.228059: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected
2022-09-15 22:13:34.228078: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: husein-MS-7D31
2022-09-15 22:13:34.228082: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: husein-MS-7D31
2022-09-15 22:13:34.228135: 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-09-15 22:13:34.228151: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:204] kernel reported version is: 470.141.3
[8]:
malaya.augmentation.wordvector(
    ' '.join(tokenizer.tokenize(string)), word_vector_wiki, soft = True
)
2022-09-15 22:13:34.248494: W tensorflow/core/framework/cpu_allocator_impl.cc:80] Allocation of 781670400 exceeds 10% of free system memory.
2022-09-15 22:13:34.461367: W tensorflow/core/framework/cpu_allocator_impl.cc:80] Allocation of 781670400 exceeds 10% of free system memory.
2022-09-15 22:13:34.466641: W tensorflow/core/framework/cpu_allocator_impl.cc:80] Allocation of 781670400 exceeds 10% of free system memory.
2022-09-15 22:13:34.561037: W tensorflow/core/framework/cpu_allocator_impl.cc:80] Allocation of 781670400 exceeds 10% of free system memory.
[8]:
['saya suka makan ayam dan ikan',
 'kamu gemar makan ayam dan ikan',
 'anda pandai makan ayam dan ikan',
 'kami senang makan ayam dan ikan',
 'aku ingin makan ayam dan ikan']
[9]:
malaya.augmentation.wordvector(
    ' '.join(tokenizer.tokenize(text)), word_vector_wiki, soft = True
)
2022-09-15 22:13:34.686946: W tensorflow/core/framework/cpu_allocator_impl.cc:80] Allocation of 781670400 exceeds 10% of free system memory.
[9]:
['Perdana Menteri berkata , beliau perlu memperoleh maklumat terperinci berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang tindakan lanjut . Bagaimanapun , beliau yakin masalah itu dapat diselesaikan dan pentadbiran kerajaan boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , beliau harus mendapatkan maklumat mendalam berhubung persoalan berkaitan selepas pemerintah boleh mengambil sebarang dakwaan terperinci . Bagaimanapun , dia yakin masalah tersebut boleh dibuktikan dan pentadbiran kerajaan dapat berfungsi setelah sempurna .',
 'Perdana Menteri berkata , beliau mesti memperolehi maklumat menyeluruh berhubung prosedur tertentu setelah perlembagaan harus mengambil sebarang kesalahan lanjutan . Bagaimanapun , baginda yakin masalah ini harus dilaksanakan dan pentadbiran kerajaan harus berfungsi apabila kuat .',
 'Perdana Menteri berkata , beliau terpaksa meraih maklumat efektif berhubung artikel tersebut ketika kesultanan perlu mengambil sebarang perbuatan ringkas . Bagaimanapun , mereka yakin masalah itulah perlu dikesan dan pentadbiran kerajaan perlu berfungsi selepas hebat .',
 'Perdana Menteri berkata , beliau dapat menerima maklumat konsisten berhubung kontroversi berlainan sejak pemerintahan mampu mengambil sebarang gerakan positif . Bagaimanapun , saya yakin masalah inilah mampu diperhatikan dan pentadbiran kerajaan akan berfungsi menerusi kukuh .']

Load Transformer#

Problem with wordvector, it just replaced a word for near synonym without understood the whole sentence context, so, Transformer comes to the rescue!

def transformer(
    string: str,
    model,
    threshold: float = 0.5,
    top_p: float = 0.9,
    top_k: int = 100,
    temperature: float = 1.0,
    top_n: int = 5,
):

    """
    augmenting a string using transformer + nucleus sampling / top-k sampling.

    Parameters
    ----------
    string: str
    model: object
        transformer interface object. Right now only supported BERT, ALBERT and ELECTRA.
    threshold: float, optional (default=0.5)
        random selection for a word.
    top_p: float, optional (default=0.8)
        cumulative sum of probabilities to sample a word.
        If top_n bigger than 0, the model will use nucleus sampling, else top-k sampling.
    top_k: int, optional (default=100)
        k for top-k sampling.
    temperature: float, optional (default=0.8)
        logits * temperature.
    top_n: int, (default=5)
        number of nearest neighbors returned. Length of returned result should as top_n.

    Returns
    -------
    result: List[str]
    """
[10]:
malaya.transformer.available_transformer()
[10]:
Size (MB) Description
bert 425.6 Google BERT BASE parameters
tiny-bert 57.4 Google BERT TINY parameters
albert 48.6 Google ALBERT BASE parameters
tiny-albert 22.4 Google ALBERT TINY parameters
xlnet 446.6 Google XLNET BASE parameters
alxlnet 46.8 Malaya ALXLNET BASE parameters
electra 443 Google ELECTRA BASE parameters
small-electra 55 Google ELECTRA SMALL parameters
[11]:
electra = malaya.transformer.load(model = 'electra')
WARNING:tensorflow:From /home/husein/.local/lib/python3.8/site-packages/tensorflow/python/util/dispatch.py:206: multinomial (from tensorflow.python.ops.random_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.random.categorical` instead.
INFO:tensorflow:Restoring parameters from /home/husein/Malaya/electra-model/base/electra-base/model.ckpt
[12]:
bert = malaya.transformer.load(model = 'bert')
INFO:tensorflow:Restoring parameters from /home/husein/Malaya/bert-model/base/bert-base-v3/model.ckpt
[20]:
albert = malaya.transformer.load(model = 'albert')
INFO:tensorflow:Restoring parameters from /home/husein/Malaya/albert-model/base/albert-base/model.ckpt
[13]:
malaya.augmentation.transformer(' '.join(tokenizer.tokenize(string)), electra)
2022-09-15 22:13:59.015441: W tensorflow/core/grappler/costs/op_level_cost_estimator.cc:689] Error in PredictCost() for the op: op: "Softmax" attr { key: "T" value { type: DT_FLOAT } } inputs { dtype: DT_FLOAT shape { unknown_rank: true } } device { type: "CPU" vendor: "GenuineIntel" model: "103" frequency: 2112 num_cores: 20 environment { key: "cpu_instruction_set" value: "AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2" } environment { key: "eigen" value: "3.3.90" } l1_cache_size: 49152 l2_cache_size: 1310720 l3_cache_size: 26214400 memory_size: 268435456 } outputs { dtype: DT_FLOAT shape { unknown_rank: true } }
[13]:
['Lebih suka untuk ayam goreng ikan',
 'Lebih suka mie ayam dengan ikan',
 'Aku suka mie ayam dan ikan',
 'aku suka daging ayam dan ikan',
 'aku suka bubur ayam ama ikan']
[17]:
malaya.augmentation.transformer(' '.join(tokenizer.tokenize(string)), bert)
[17]:
['saya suka potongan kacang dan ikan',
 'saya gabisa mie ikan / ikan',
 'saya suka sup ikan / ikan',
 'saya kenyang ada ikan siang ikan',
 'saya pandai masak ikan + ikan']
[21]:
malaya.augmentation.transformer(' '.join(tokenizer.tokenize(string)), albert)
2022-09-15 22:14:49.069337: W tensorflow/core/grappler/costs/op_level_cost_estimator.cc:689] Error in PredictCost() for the op: op: "Softmax" attr { key: "T" value { type: DT_FLOAT } } inputs { dtype: DT_FLOAT shape { unknown_rank: true } } device { type: "CPU" vendor: "GenuineIntel" model: "103" frequency: 2112 num_cores: 20 environment { key: "cpu_instruction_set" value: "AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2" } environment { key: "eigen" value: "3.3.90" } l1_cache_size: 49152 l2_cache_size: 1310720 l3_cache_size: 26214400 memory_size: 268435456 } outputs { dtype: DT_FLOAT shape { unknown_rank: true } }
[21]:
['saya suka kari ayam dan rendang',
 'saya suka makan pisang dan sate',
 'saya suka kulit kepala dan lemang',
 'saya suka masakan jengkol dan ikan',
 'saya suka makan telur dan ikan']
[18]:
malaya.augmentation.transformer(' '.join(tokenizer.tokenize(text)), electra)
[18]:
['Perdana Menteri berkata , kerajaan perlu mengemukakan butiran terperinci berhubung isu ini supaya kerajaan tidak melakukan sebarang tindakan lanjut . Bagaimanapun , beliau yakin masalah itu dapat diselesaikan sekiranya memastikan hanya boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , kerajaan perlu mempunyai maklumat terperinci berhubung isu itu supaya kerajaan boleh mengambil sebarang tindakan lanjut . Bagaimanapun , beliau yakin masalah berkenaan dapat diselesaikan dan percaya itu boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , kerajaan perlu beri kajian terperinci berhubung isu ini supaya kerajaan negeri membuat semula tindakan lanjut . Bagaimanapun , beliau yakin masalah itu dapat diatasi dan kemudiannya kerajaan boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , kerajaan perlu mempunyai maklumat terperinci berhubung isu itu supaya kerajaan dapat memberi beberapa tindakan lanjut . Bagaimanapun , beliau yakin masalah rakyat dapat diselesaikan selagi tetap negeri boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , beliau perlu mengumpul maklumat terperinci berhubung isu tersebut sehingga kerajaan akan melaksanakan sebarang tindakan lanjut . Bagaimanapun , beliau yakin isu ini dapat diatasi kerana bantuan masih boleh berfungsi dengan baik .']
[19]:
malaya.augmentation.transformer(' '.join(tokenizer.tokenize(text)), electra)
[19]:
['Perdana Menteri berkata , beliau perlu mempunyai perhatian lanjut berhubung isu berkenaan supaya kerajaan tidak memberi kira tindakan segera . Bagaimanapun , beliau berharap masalah itu dapat diselesaikan jika pentadbiran kerajaan boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , beliau perlu mengemukakan maklumat secukupnya berhubung perkara itu supaya beliau tidak mengambil segala tindakan lanjut . Bagaimanapun , beliau berharap masalah itu boleh diselesaikan dan pentadbiran kerajaan boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , beliau perlu mempunyai maklumat lanjut berhubung isu ini supaya tidak dapat menghadapi sebarang tindakan lanjut . Bagaimanapun , beliau berharap masalah itu boleh diselesaikan apabila pentadbiran kerajaan boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , beliau perlu mengemukakan maklumat terperinci mengenai perkara itu supaya mereka tempatan memberi serius tindakan selanjutnya . Bagaimanapun , beliau yakin masalah itu dapat diselesaikan sehingga pentadbiran kerajaan boleh berfungsi dengan baik .',
 'Perdana Menteri berkata , beliau perlu mendapatkan perhatian terperinci berhubung isu sebenar supaya tidak untuk mengambil satu tindakan sewajarnya . Bagaimanapun , beliau berharap masalah itu dapat diselesaikan selagi pentadbiran kerajaan boleh berfungsi dengan baik .']
[22]:
malaya.augmentation.transformer(' '.join(tokenizer.tokenize(text)), albert)
[22]:
['Perdana Menteri berkata, pihaknya sedang memberikan penjelasan lanjut berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang penjelasan lanjut. Bagaimanapun, beliau berharap isu itu boleh diselesaikan dan perancangan tidak boleh diselesaikan dengan baik.',
 'Perdana Menteri berkata, kerajaan akan memberikan penjelasan lanjut berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang penjelasan terperinci. Bagaimanapun, beliau berharap masalah itu boleh diselesaikan dan perancangan kerajaan boleh berjalan dengan baik.',
 'Perdana Menteri berkata, beliau akan mempunyai penjelasan lanjut berhubung masalah berkenaan sebelum kerajaan dapat mengambil sebarang penjelasan sewajarnya. Bagaimanapun, beliau berharap masalah itu akan diselesaikan dan semua kerajaan boleh berfungsi dengan baik.',
 'Perdana Menteri berkata, kerajaan akan mendapat penjelasan lanjut berhubung masalah berkenaan sebelum kerajaan dapat mengambil sebarang penjelasan lanjut. Bagaimanapun, beliau yakin masalah itu akan diselesaikan dan semua ini boleh berfungsi dengan baik.',
 'Perdana Menteri berkata, pihaknya akan memberikan penjelasan lanjut berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang tindakan serius. Bagaimanapun, beliau berharap perkara itu boleh diselesaikan dan semua beliau boleh pulih dengan baik.']