647 lines
43 KiB
Plaintext
647 lines
43 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# စာသားအမျိုးအစားသတ်မှတ်ခြင်း အလုပ်\n",
|
|
"\n",
|
|
"ဒီအခန်းမှာတော့ **[AG_NEWS](http://www.di.unipi.it/~gulli/AG_corpus_of_news_articles.html)** dataset ကိုအခြေခံပြီး ရိုးရှင်းတဲ့ စာသားအမျိုးအစားသတ်မှတ်ခြင်း အလုပ်ကို စတင်လုပ်ဆောင်ပါမယ်။ ဤအလုပ်မှာ သတင်းခေါင်းစဉ်များကို အမျိုးအစား ၄ မျိုးဖြစ်တဲ့ World, Sports, Business, Sci/Tech တို့ထဲက တစ်ခုအဖြစ် သတ်မှတ်ပေးပါမယ်။\n",
|
|
"\n",
|
|
"## Dataset အကြောင်း\n",
|
|
"\n",
|
|
"Dataset ကို load လုပ်ဖို့အတွက် **[TensorFlow Datasets](https://www.tensorflow.org/datasets)** API ကို အသုံးပြုပါမယ်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import tensorflow as tf\n",
|
|
"from tensorflow import keras\n",
|
|
"import tensorflow_datasets as tfds\n",
|
|
"\n",
|
|
"# In this tutorial, we will be training a lot of models. In order to use GPU memory cautiously,\n",
|
|
"# we will set tensorflow option to grow GPU memory allocation when required.\n",
|
|
"physical_devices = tf.config.list_physical_devices('GPU') \n",
|
|
"if len(physical_devices)>0:\n",
|
|
" tf.config.experimental.set_memory_growth(physical_devices[0], True)\n",
|
|
"\n",
|
|
"dataset = tfds.load('ag_news_subset')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"အခုကျွန်တော်တို့ `dataset['train']` နဲ့ `dataset['test']` ကိုအသုံးပြုပြီး training portion နဲ့ test portion ကို dataset မှာ access လုပ်နိုင်ပါပြီ:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Length of train dataset = 120000\n",
|
|
"Length of test dataset = 7600\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"ds_train = dataset['train']\n",
|
|
"ds_test = dataset['test']\n",
|
|
"\n",
|
|
"print(f\"Length of train dataset = {len(ds_train)}\")\n",
|
|
"print(f\"Length of test dataset = {len(ds_test)}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"အချက်အလက်စုစည်းမှုမှ ပထမဆုံး ၁၀ ခုသော သတင်းခေါင်းစဉ်အသစ်များကို ပုံနှိပ်ကြမယ်:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"3 (Sci/Tech) -> b'AMD Debuts Dual-Core Opteron Processor' b'AMD #39;s new dual-core Opteron chip is designed mainly for corporate computing applications, including databases, Web services, and financial transactions.'\n",
|
|
"1 (Sports) -> b\"Wood's Suspension Upheld (Reuters)\" b'Reuters - Major League Baseball\\\\Monday announced a decision on the appeal filed by Chicago Cubs\\\\pitcher Kerry Wood regarding a suspension stemming from an\\\\incident earlier this season.'\n",
|
|
"2 (Business) -> b'Bush reform may have blue states seeing red' b'President Bush #39;s quot;revenue-neutral quot; tax reform needs losers to balance its winners, and people claiming the federal deduction for state and local taxes may be in administration planners #39; sights, news reports say.'\n",
|
|
"3 (Sci/Tech) -> b\"'Halt science decline in schools'\" b'Britain will run out of leading scientists unless science education is improved, says Professor Colin Pillinger.'\n",
|
|
"1 (Sports) -> b'Gerrard leaves practice' b'London, England (Sports Network) - England midfielder Steven Gerrard injured his groin late in Thursday #39;s training session, but is hopeful he will be ready for Saturday #39;s World Cup qualifier against Austria.'\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"classes = ['World', 'Sports', 'Business', 'Sci/Tech']\n",
|
|
"\n",
|
|
"for i,x in zip(range(5),ds_train):\n",
|
|
" print(f\"{x['label']} ({classes[x['label']]}) -> {x['title']} {x['description']}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## စာသားကို ဂဏန်းအဖြစ်ပြောင်းခြင်း\n",
|
|
"\n",
|
|
"အခုတော့ စာသားတွေကို **ဂဏန်း** အဖြစ်ပြောင်းပြီး tensor အနေနဲ့ ကိုယ်စားပြုနိုင်အောင် ပြုလုပ်ရပါမယ်။ စကားလုံးအဆင့်ကိုယ်စားပြုမှုလိုချင်ရင် အောက်ပါအချက်နှစ်ခုကို ပြုလုပ်ရပါမယ်-\n",
|
|
"\n",
|
|
"* **tokenizer** ကိုသုံးပြီး စာသားကို **tokens** အဖြစ်ခွဲခြားပါ။\n",
|
|
"* အဲ့ဒီ tokens တွေကို **vocabulary** တစ်ခုတည်ဆောက်ပါ။\n",
|
|
"\n",
|
|
"### Vocabulary အရွယ်အစားကို ကန့်သတ်ခြင်း\n",
|
|
"\n",
|
|
"AG News dataset ဥပမာမှာတော့ vocabulary size က အတော်လေးကြီးပါတယ်၊ စကားလုံး 100,000 ကျော်ပါဝင်ပါတယ်။ အထူးသဖြင့် စာသားမှာ ရှားရှားပါးပါးပေါ်လာတဲ့ စကားလုံးတွေကို မလိုအပ်ပါဘူး — အဲ့ဒီစကားလုံးတွေဟာ စာကြောင်းအနည်းငယ်မှာပဲ ပါဝင်ပြီး၊ model က အဲ့ဒီစကားလုံးတွေကနေ သင်ယူနိုင်မှာ မဟုတ်ပါဘူး။ ဒါကြောင့် vocabulary size ကို သေးငယ်တဲ့အရေအတွက်တစ်ခုအထိ ကန့်သတ်ဖို့ make sense ဖြစ်ပါတယ်၊ အဲ့ဒီအတွက် vectorizer constructor ကို argument ဖြတ်ပေးရပါမယ်။\n",
|
|
"\n",
|
|
"အဲ့ဒီအဆင့်နှစ်ခုကို **TextVectorization** layer ကိုသုံးပြီး လုပ်ဆောင်နိုင်ပါတယ်။ အရင်ဆုံး vectorizer object ကို instantiate လုပ်ပြီး၊ `adapt` method ကို ခေါ်သုံးကာ စာသားအားလုံးကို ဖြတ်သွားပြီး vocabulary တစ်ခုတည်ဆောက်ပါ။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"vocab_size = 50000\n",
|
|
"vectorizer = keras.layers.experimental.preprocessing.TextVectorization(max_tokens=vocab_size)\n",
|
|
"vectorizer.adapt(ds_train.take(500).map(lambda x: x['title']+' '+x['description']))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"> **မှတ်ချက်** ကျွန်တော်တို့သည် စာလုံးစုစည်းမှုတစ်ခုကို တည်ဆောက်ရန် အချက်အလက်စုစည်းမှု၏ အစိတ်အပိုင်းတစ်ခုကိုသာ အသုံးပြုနေပါသည်။ ဒါကို လုပ်ခြင်းဖြင့် အကောင်အထည်ဖော်မှုအချိန်ကို မြန်ဆန်စေပြီး သင့်ကို စောင့်နေစရာမလိုအောင် လုပ်ဆောင်ပါသည်။ သို့သော် အချက်အလက်စုစည်းမှု၏ စာလုံးအချို့သည် စာလုံးစုစည်းမှုထဲတွင် မပါဝင်နိုင်ဘဲ လေ့ကျင့်မှုအတွင်း မျက်မမြင်ဖြစ်နိုင်သည်ဆိုသော အန္တရာယ်ကို ကျွန်တော်တို့ ခံယူထားပါသည်။ ထို့ကြောင့် `adapt` လုပ်ဆောင်မှုအတွင်း စာလုံးစုစည်းမှုအရွယ်အစားအားလုံးကို အသုံးပြုပြီး အချက်အလက်စုစည်းမှုအားလုံးကို ဖြတ်သန်းခြင်းဖြင့် နောက်ဆုံးရလဒ်တိကျမှုကို တိုးမြှင့်နိုင်မည်ဖြစ်သော်လည်း အလွန်အမင်း မတိုးတက်နိုင်ပါ။\n",
|
|
"\n",
|
|
"အခု ကျွန်တော်တို့ စာလုံးစုစည်းမှုကို တကယ်ရောက်ရှိနိုင်ပါပြီ:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"['', '[UNK]', 'the', 'to', 'a', 'in', 'of', 'and', 'on', 'for']\n",
|
|
"Length of vocabulary: 5335\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"vocab = vectorizer.get_vocabulary()\n",
|
|
"vocab_size = len(vocab)\n",
|
|
"print(vocab[:10])\n",
|
|
"print(f\"Length of vocabulary: {vocab_size}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ဗက်တိုရာဇာကို အသုံးပြု၍ မည်သည့်စာသားကိုမဆို အလွယ်တကူ နံပါတ်များအဖြစ် ကုဒ်ပြုလုပ်နိုင်ပါသည်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<tf.Tensor: shape=(7,), dtype=int64, numpy=array([ 112, 3695, 3, 304, 11, 1041, 1], dtype=int64)>"
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"vectorizer('I love to play with my words')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## စကားလုံးအထုပ် (Bag-of-words) စာသားကိုယ်စားပြုမှု\n",
|
|
"\n",
|
|
"စကားလုံးများသည် အဓိပ္ပါယ်ကို ကိုယ်စားပြုနိုင်သောကြောင့်၊ တစ်ခါတစ်ရံ စာသားတစ်ခု၏ အဓိပ္ပါယ်ကို စာကြောင်းအတွင်း စကားလုံးများ၏ အစီအစဉ်ကို မကြည့်ဘဲ၊ တစ်ခုချင်းစီ စကားလုံးများကိုသာ ကြည့်ခြင်းဖြင့် သိနိုင်ပါသည်။ ဥပမာအားဖြင့် သတင်းများကို အမျိုးအစားခွဲခြားရာတွင် *ရာသီဥတု* နှင့် *နှင်း* ကဲ့သို့သော စကားလုံးများသည် *ရာသီဥတုခန့်မှန်းချက်* ကို ဖော်ပြနိုင်ပြီး၊ *အหุ้น* နှင့် *ဒေါ်လာ* ကဲ့သို့သော စကားလုံးများသည် *ဘဏ္ဍာရေးသတင်း* ကို ဖော်ပြနိုင်ပါသည်။\n",
|
|
"\n",
|
|
"**စကားလုံးအထုပ်** (BoW) ဗက်တာကိုယ်စားပြုမှုသည် နားလည်ရန် အလွယ်ဆုံးသော ရိုးရာဗက်တာကိုယ်စားပြုမှုဖြစ်သည်။ စကားလုံးတစ်ခုချင်းစီကို ဗက်တာအညွှန်းနှင့် ချိတ်ဆက်ထားပြီး၊ ဗက်တာအခန်းကဏ္ဍတစ်ခုတွင် သတ်မှတ်ထားသော စာရွက်စာတမ်းအတွင်း စကားလုံးတစ်ခုချင်းစီ၏ ဖြစ်ပေါ်မှုအရေအတွက်ကို ပါဝင်ထားသည်။\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"> **Note**: BoW ကို စာသားအတွင်း စကားလုံးတစ်ခုချင်းစီအတွက် တစ်ခုချင်းစီ *one-hot-encoded* ဗက်တာများ၏ စုစုပေါင်းအဖြစ်လည်း စဉ်းစားနိုင်ပါသည်။\n",
|
|
"\n",
|
|
"အောက်တွင် Scikit Learn python library ကို အသုံးပြု၍ စကားလုံးအထုပ်ကိုယ်စားပြုမှုကို ဖန်တီးပုံ၏ ဥပမာကို ဖော်ပြထားပါသည်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"array([[1, 1, 0, 2, 0, 0, 0, 0, 0]], dtype=int64)"
|
|
]
|
|
},
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from sklearn.feature_extraction.text import CountVectorizer\n",
|
|
"sc_vectorizer = CountVectorizer()\n",
|
|
"corpus = [\n",
|
|
" 'I like hot dogs.',\n",
|
|
" 'The dog ran fast.',\n",
|
|
" 'Its hot outside.',\n",
|
|
" ]\n",
|
|
"sc_vectorizer.fit_transform(corpus)\n",
|
|
"sc_vectorizer.transform(['My dog likes hot dogs on a hot day.']).toarray()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ကျွန်ုပ်တို့အပေါ်တွင်သတ်မှတ်ထားသော Keras vectorizer ကိုလည်းအသုံးပြုနိုင်ပြီး၊ စကားလုံးနံပါတ်တစ်ခုချင်းစီကို one-hot encoding အဖြစ်ပြောင်းလဲပြီး၊ အဲဒီ vector တွေကိုလုံးလုံးပေါင်းထည့်နိုင်ပါသည်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"array([0., 5., 0., ..., 0., 0., 0.], dtype=float32)"
|
|
]
|
|
},
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def to_bow(text):\n",
|
|
" return tf.reduce_sum(tf.one_hot(vectorizer(text),vocab_size),axis=0)\n",
|
|
"\n",
|
|
"to_bow('My dog likes hot dogs on a hot day.').numpy()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"> **မှတ်ချက်**: အရင်ဥပမာနဲ့ရလဒ်ကွာခြားနေတယ်ဆိုတာကို သင်အံ့ဩနိုင်ပါတယ်။ အကြောင်းက Keras ဥပမာမှာ vector ရဲ့အရှည်ဟာ vocabulary size နဲ့ကိုက်ညီပြီး၊ အဲဒီ vocabulary ကို AG News dataset အပြည့်အစုံကနေတည်ဆောက်ထားတာဖြစ်ပါတယ်။ ဒါပေမယ့် Scikit Learn ဥပမာမှာတော့ vocabulary ကို sample text ကနေ ချက်ချင်းတည်ဆောက်ထားတာဖြစ်ပါတယ်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## BoW ခွဲခြားစနစ်ကို လေ့ကျင့်ခြင်း\n",
|
|
"\n",
|
|
"အခုတော့ ကျွန်တော်တို့ စာသားကို bag-of-words ကိုယ်စားပြုမှုအဖြစ် တည်ဆောက်နည်းကို သင်ယူပြီးဖြစ်သောကြောင့်၊ ဒါကို အသုံးပြုတဲ့ ခွဲခြားစနစ်တစ်ခုကို လေ့ကျင့်ကြမယ်။ ပထမဦးစွာ ကျွန်တော်တို့ရဲ့ ဒေတာစုစည်းမှုကို bag-of-words ကိုယ်စားပြုမှုအဖြစ် ပြောင်းလဲဖို့ လိုအပ်ပါတယ်။ ဒါကို `map` function ကို အောက်ပါနည်းလမ်းဖြင့် အသုံးပြုခြင်းဖြင့် ပြုလုပ်နိုင်ပါတယ် - \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"batch_size = 128\n",
|
|
"\n",
|
|
"ds_train_bow = ds_train.map(lambda x: (to_bow(x['title']+x['description']),x['label'])).batch(batch_size)\n",
|
|
"ds_test_bow = ds_test.map(lambda x: (to_bow(x['title']+x['description']),x['label'])).batch(batch_size)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"အခုတော့ linear layer တစ်ခုပါဝင်တဲ့ ရိုးရှင်းတဲ့ classifier neural network ကို သတ်မှတ်ကြမယ်။ Input size က `vocab_size` ဖြစ်ပြီး၊ output size က class အရေအတွက် (၄) ကို ကိုယ်စားပြုပါတယ်။ Classification task ကို ဖြေရှင်းနေတာဖြစ်လို့၊ နောက်ဆုံး activation function က **softmax** ဖြစ်ပါတယ်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"938/938 [==============================] - 66s 70ms/step - loss: 0.6144 - acc: 0.8427 - val_loss: 0.4416 - val_acc: 0.8697\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<keras.callbacks.History at 0x20c70a947f0>"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"model = keras.models.Sequential([\n",
|
|
" keras.layers.Dense(4,activation='softmax',input_shape=(vocab_size,))\n",
|
|
"])\n",
|
|
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
|
|
"model.fit(ds_train_bow,validation_data=ds_test_bow)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ကျွန်တော်တို့မှာ အတန်း ၄ ခုရှိတဲ့အတွက် ၈၀% အထက်ရှိတဲ့ တိကျမှုဟာ ရလဒ်ကောင်းတစ်ခုဖြစ်ပါတယ်။\n",
|
|
"\n",
|
|
"## တစ်ခုတည်းသော network အဖြစ် classifier ကို လေ့ကျင့်ခြင်း\n",
|
|
"\n",
|
|
"Vectorizer ကလည်း Keras layer တစ်ခုဖြစ်တဲ့အတွက်၊ network တစ်ခုအဖြစ် သတ်မှတ်ပြီး၊ အဆုံးအထိ လေ့ကျင့်နိုင်ပါတယ်။ ဒီနည်းလမ်းနဲ့ dataset ကို `map` အသုံးပြုပြီး vectorize လုပ်စရာမလိုတော့ပါဘူး၊ network ရဲ့ input ကို အစစ်အမှန် dataset ကိုပဲ ဖြတ်သွားနိုင်ပါတယ်။\n",
|
|
"\n",
|
|
"> **Note**: Dataset ကို dictionary (ဥပမာ `title`, `description` နဲ့ `label`) ကနေ tuple အဖြစ် ပြောင်းဖို့ map တွေကို အသုံးပြုရဦးမှာဖြစ်ပါတယ်။ သို့သော် disk ကနေ data ကို load လုပ်တဲ့အခါမှာတော့ လိုအပ်တဲ့ ဖွဲ့စည်းမှုနဲ့ dataset ကို အစဉ်အတိုင်း တည်ဆောက်နိုင်ပါတယ်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Model: \"model\"\n",
|
|
"_________________________________________________________________\n",
|
|
" Layer (type) Output Shape Param # \n",
|
|
"=================================================================\n",
|
|
" input_1 (InputLayer) [(None, 1)] 0 \n",
|
|
" \n",
|
|
" text_vectorization (TextVec (None, None) 0 \n",
|
|
" torization) \n",
|
|
" \n",
|
|
" tf.one_hot (TFOpLambda) (None, None, 5335) 0 \n",
|
|
" \n",
|
|
" tf.math.reduce_sum (TFOpLam (None, 5335) 0 \n",
|
|
" bda) \n",
|
|
" \n",
|
|
" dense_2 (Dense) (None, 4) 21344 \n",
|
|
" \n",
|
|
"=================================================================\n",
|
|
"Total params: 21,344\n",
|
|
"Trainable params: 21,344\n",
|
|
"Non-trainable params: 0\n",
|
|
"_________________________________________________________________\n",
|
|
"938/938 [==============================] - 73s 77ms/step - loss: 0.6057 - acc: 0.8414 - val_loss: 0.4202 - val_acc: 0.8736\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<keras.callbacks.History at 0x20c721521f0>"
|
|
]
|
|
},
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def extract_text(x):\n",
|
|
" return x['title']+' '+x['description']\n",
|
|
"\n",
|
|
"def tupelize(x):\n",
|
|
" return (extract_text(x),x['label'])\n",
|
|
"\n",
|
|
"inp = keras.Input(shape=(1,),dtype=tf.string)\n",
|
|
"x = vectorizer(inp)\n",
|
|
"x = tf.reduce_sum(tf.one_hot(x,vocab_size),axis=1)\n",
|
|
"out = keras.layers.Dense(4,activation='softmax')(x)\n",
|
|
"model = keras.models.Model(inp,out)\n",
|
|
"model.summary()\n",
|
|
"\n",
|
|
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
|
|
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Bigrams, trigrams နှင့် n-grams\n",
|
|
"\n",
|
|
"Bag-of-words နည်းလမ်း၏ အားနည်းချက်တစ်ခုမှာ စကားလုံးတစ်ချို့သည် စကားလုံးများပေါင်းစပ်မှုဖြစ်ပြီး၊ ဥပမာအားဖြင့် 'hot dog' ဆိုသော စကားလုံးသည် 'hot' နှင့် 'dog' ဆိုသော စကားလုံးများ၏ အခြားအကြောင်းအရာများတွင် အဓိပ္ပါယ်ကွဲပြားမှုရှိသည်။ 'hot' နှင့် 'dog' စကားလုံးများကို အမြဲတမ်းတူညီသော vectors ဖြင့် ကိုယ်စားပြုပါက၊ ၎င်းသည် မော်ဒယ်ကို ရှုပ်ထွေးစေနိုင်သည်။\n",
|
|
"\n",
|
|
"ဤပြဿနာကို ဖြေရှင်းရန်၊ **n-gram ကိုယ်စားပြုမှုများ** ကို အချို့သော စာရွက်စာတမ်းများကို အမျိုးအစားခွဲခြားရာတွင် အသုံးပြုလေ့ရှိပြီး၊ စကားလုံးတစ်လုံး၊ စကားလုံးနှစ်လုံး (bi-word) သို့မဟုတ် စကားလုံးသုံးလုံး (tri-word) တစ်ခုချင်းစီ၏ frequency သည် classifier များကို လေ့ကျင့်ရန် အသုံးဝင်သော feature ဖြစ်သည်။ ဥပမာအားဖြင့် bigram ကိုယ်စားပြုမှုတွင်၊ မူရင်းစကားလုံးများအပြင် စကားလုံးအတွဲများအားလုံးကို vocabulary ထဲသို့ ထည့်သွင်းပါမည်။\n",
|
|
"\n",
|
|
"အောက်တွင် Scikit Learn ကို အသုံးပြု၍ bigram bag of word ကိုယ်စားပြုမှုကို ဖန်တီးနည်း၏ ဥပမာကို ဖော်ပြထားသည်-\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Vocabulary:\n",
|
|
" {'i': 7, 'like': 11, 'hot': 4, 'dogs': 2, 'i like': 8, 'like hot': 12, 'hot dogs': 5, 'the': 16, 'dog': 0, 'ran': 14, 'fast': 3, 'the dog': 17, 'dog ran': 1, 'ran fast': 15, 'its': 9, 'outside': 13, 'its hot': 10, 'hot outside': 6}\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"array([[1, 0, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],\n",
|
|
" dtype=int64)"
|
|
]
|
|
},
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"bigram_vectorizer = CountVectorizer(ngram_range=(1, 2), token_pattern=r'\\b\\w+\\b', min_df=1)\n",
|
|
"corpus = [\n",
|
|
" 'I like hot dogs.',\n",
|
|
" 'The dog ran fast.',\n",
|
|
" 'Its hot outside.',\n",
|
|
" ]\n",
|
|
"bigram_vectorizer.fit_transform(corpus)\n",
|
|
"print(\"Vocabulary:\\n\",bigram_vectorizer.vocabulary_)\n",
|
|
"bigram_vectorizer.transform(['My dog likes hot dogs on a hot day.']).toarray()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"n-gram နည်းလမ်းရဲ့ အဓိကအားနည်းချက်က vocabulary အရွယ်အစားက အလွန်မြန်မြန်ဆန်ဆန် ကြီးထွားလာတတ်တာပဲ ဖြစ်ပါတယ်။ အကောင်အထည်ဖော်ရာမှာတော့ n-gram ကို အသုံးပြုတဲ့အခါ dimensionality reduction နည်းလမ်းတစ်ခုဖြစ်တဲ့ *embeddings* နဲ့ပေါင်းစပ်ဖို့ လိုအပ်ပါတယ်၊ ဒီအကြောင်းကို နောက်အခန်းမှာ ဆွေးနွေးပါမယ်။\n",
|
|
"\n",
|
|
"**AG News** dataset မှာ n-gram ကို အသုံးပြုဖို့ `ngrams` parameter ကို `TextVectorization` constructor ထဲမှာ ဖြတ်သွင်းရပါမယ်။ bigram vocabulary ရဲ့ အရှည်က **အလွန်ကြီးမား**ပြီး၊ ကျွန်တော်တို့ရဲ့ အခြေအနေမှာတော့ 1.3 million tokens ထက်ပိုပါတယ်! ဒါကြောင့် bigram tokens ကိုလည်း သင့်တော်တဲ့ အရေအတွက်တစ်ခုနဲ့ ကန့်သတ်ဖို့ make sense ဖြစ်ပါတယ်။\n",
|
|
"\n",
|
|
"classifier ကို training လုပ်ဖို့ အပေါ်မှာ အသုံးပြုခဲ့တဲ့ code ကိုပဲ အသုံးပြုနိုင်ပါတယ်၊ ဒါပေမယ့် memory ကို အလွန်မထိရောက်စွာ အသုံးပြုမိနိုင်ပါဘူး။ နောက်အခန်းမှာတော့ embeddings ကို အသုံးပြုပြီး bigram classifier ကို training လုပ်ပါမယ်။ အခုအချိန်မှာတော့ ဒီ notebook ထဲမှာ bigram classifier training ကို စမ်းသပ်ပြီး အတိအကျမှု (accuracy) ပိုမြင့်တင်နိုင်မလား စမ်းကြည့်နိုင်ပါတယ်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## BoW ဗက်တာများကို အလိုအလျောက်တွက်ချက်ခြင်း\n",
|
|
"\n",
|
|
"အထက်ပါ ဥပမာတွင် BoW ဗက်တာများကို တစ်ခုချင်းစီသော စကားလုံးများ၏ one-hot encodings များကို ပေါင်းပြီး လက်ဖြင့်တွက်ချက်ခဲ့ပါသည်။ သို့သော် TensorFlow ၏ နောက်ဆုံးဗားရှင်းတွင် `output_mode='count` parameter ကို vectorizer constructor သို့ ဖြတ်သွားခြင်းဖြင့် BoW ဗက်တာများကို အလိုအလျောက်တွက်ချက်နိုင်ပါသည်။ ဤနည်းလမ်းသည် မော်ဒယ်ကို သတ်မှတ်ခြင်းနှင့် လေ့ကျင့်ခြင်းကို အလွန်လွယ်ကူစေပါသည်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Training vectorizer\n",
|
|
"938/938 [==============================] - 7s 7ms/step - loss: 0.5929 - acc: 0.8486 - val_loss: 0.4168 - val_acc: 0.8772\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<keras.callbacks.History at 0x20c725217c0>"
|
|
]
|
|
},
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"model = keras.models.Sequential([\n",
|
|
" keras.layers.experimental.preprocessing.TextVectorization(max_tokens=vocab_size,output_mode='count'),\n",
|
|
" keras.layers.Dense(4,input_shape=(vocab_size,), activation='softmax')\n",
|
|
"])\n",
|
|
"print(\"Training vectorizer\")\n",
|
|
"model.layers[0].adapt(ds_train.take(500).map(extract_text))\n",
|
|
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
|
|
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## စကားလုံးအကြိမ်ရေ - စာရွက်စာတမ်းအကြိမ်ရေကို ဆန့်ကျင်သော အကြိမ်ရေ (TF-IDF)\n",
|
|
"\n",
|
|
"BoW ကိုယ်စားပြုမှုတွင် စကားလုံးများ၏ ဖြစ်ပေါ်မှုကို စကားလုံး၏ အမျိုးအစားမရွေးဘဲ တူညီသောနည်းလမ်းဖြင့် အလေးပေးသည်။ သို့သော် *a* နှင့် *in* ကဲ့သို့ မကြာခဏ တွေ့ရသော စကားလုံးများသည် အထူးသီးသန့် စကားလုံးများထက် အမျိုးအစားခွဲခြားမှုအတွက် အရေးပါမှုနည်းပါးသည်ဟု သိသာသည်။ NLP အလုပ်များအများစုတွင် စကားလုံးတချို့သည် အခြားစကားလုံးများထက် ပိုမိုသက်ဆိုင်မှုရှိသည်။\n",
|
|
"\n",
|
|
"**TF-IDF** သည် **term frequency - inverse document frequency** ကို ဆိုလိုသည်။ ၎င်းသည် bag-of-words ၏ အမျိုးအစားတစ်ခုဖြစ်ပြီး စကားလုံးတစ်ခုသည် စာရွက်စာတမ်းတွင် ပါဝင်မှုကို binary 0/1 တန်ဖိုးဖြင့် ဖော်ပြခြင်းမဟုတ်ဘဲ စကားလုံး၏ corpus တွင် ဖြစ်ပေါ်မှုအကြိမ်ရေနှင့် ဆက်စပ်သော floating-point တန်ဖိုးကို အသုံးပြုသည်။\n",
|
|
"\n",
|
|
"ပိုမိုတိကျစွာဆိုရမည်ဆိုလျှင် စကားလုံး $i$ ၏ စာရွက်စာတမ်း $j$ တွင် အလေးပေးမှု $w_{ij}$ ကို အောက်ပါအတိုင်း သတ်မှတ်သည်။\n",
|
|
"$$\n",
|
|
"w_{ij} = tf_{ij}\\times\\log({N\\over df_i})\n",
|
|
"$$\n",
|
|
"အဲဒီမှာ\n",
|
|
"* $tf_{ij}$ သည် $i$ ကို $j$ တွင် တွေ့ရသော အကြိမ်ရေဖြစ်သည်၊ ဒါဟာ ကျွန်တော်တို့ အရင်က တွေ့ခဲ့တဲ့ BoW တန်ဖိုးဖြစ်သည်\n",
|
|
"* $N$ သည် စုစုပေါင်း စာရွက်စာတမ်းအရေအတွက်ဖြစ်သည်\n",
|
|
"* $df_i$ သည် စကားလုံး $i$ ကို စုစုပေါင်း စာရွက်စာတမ်းများတွင် ပါဝင်သော စာရွက်စာတမ်းအရေအတွက်ဖြစ်သည်\n",
|
|
"\n",
|
|
"TF-IDF တန်ဖိုး $w_{ij}$ သည် စကားလုံးတစ်ခုသည် စာရွက်စာတမ်းတွင် ပါဝင်သော အကြိမ်ရေအတိုင်း တိုးမြှင့်ပြီး corpus တွင် စကားလုံးပါဝင်သော စာရွက်စာတမ်းအရေအတွက်ကို အလေးပေးမှုဖြင့် လျှော့ချသည်။ ၎င်းသည် စကားလုံးတစ်ချို့သည် အခြားစကားလုံးများထက် မကြာခဏ တွေ့ရသည်ဆိုသော အချက်ကို ပြင်ဆင်ရန် အထောက်အကူပြုသည်။ ဥပမာအားဖြင့် စကားလုံးတစ်ခုသည် စုစုပေါင်း စာရွက်စာတမ်းများ *အားလုံး* တွင် ပါဝင်လျှင် $df_i=N$ ဖြစ်ပြီး $w_{ij}=0$ ဖြစ်သည်။ ထို့ကြောင့် စကားလုံးများကို လုံးဝ မထည့်သွင်းစဉ်းစားတော့ပါ။\n",
|
|
"\n",
|
|
"Scikit Learn ကို အသုံးပြု၍ TF-IDF vectorization ကို လွယ်ကူစွာ ဖန်တီးနိုင်သည်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"array([[0.43381609, 0. , 0.43381609, 0. , 0.65985664,\n",
|
|
" 0.43381609, 0. , 0. , 0. , 0. ,\n",
|
|
" 0. , 0. , 0. , 0. , 0. ,\n",
|
|
" 0. ]])"
|
|
]
|
|
},
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
|
"vectorizer = TfidfVectorizer(ngram_range=(1,2))\n",
|
|
"vectorizer.fit_transform(corpus)\n",
|
|
"vectorizer.transform(['My dog likes hot dogs on a hot day.']).toarray()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Keras တွင် `TextVectorization` layer သည် `output_mode='tf-idf'` parameter ကို ဖြတ်သွားခြင်းဖြင့် TF-IDF frequency များကို အလိုအလျောက်တွက်ချက်နိုင်သည်။ TF-IDF ကို အသုံးပြုခြင်းက တိကျမှုကို တိုးမြှင့်ပေးနိုင်မည်လားဆိုတာကို ကြည့်ရန် အထက်တွင် အသုံးပြုခဲ့သော code ကို ထပ်မံလုပ်ဆောင်ကြည့်ပါ။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Training vectorizer\n",
|
|
"938/938 [==============================] - 12s 12ms/step - loss: 0.4197 - acc: 0.8662 - val_loss: 0.3432 - val_acc: 0.8849\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<keras.callbacks.History at 0x20c729dfd30>"
|
|
]
|
|
},
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"model = keras.models.Sequential([\n",
|
|
" keras.layers.experimental.preprocessing.TextVectorization(max_tokens=vocab_size,output_mode='tf-idf'),\n",
|
|
" keras.layers.Dense(4,input_shape=(vocab_size,), activation='softmax')\n",
|
|
"])\n",
|
|
"print(\"Training vectorizer\")\n",
|
|
"model.layers[0].adapt(ds_train.take(500).map(extract_text))\n",
|
|
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
|
|
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## အနှစ်ချုပ်\n",
|
|
"\n",
|
|
"TF-IDF ကိုယ်စားပြုမှုများသည် စကားလုံးများအတွက် ကြိမ်နှုန်းအလေးချိန်များကို ပေးနိုင်သော်လည်း အဓိပ္ပါယ် သို့မဟုတ် အစီအစဉ်ကို ကိုယ်စားပြုနိုင်ခြင်း မရှိပါ။ 1935 ခုနှစ်တွင် နာမည်ကြီး ဘာသာဗေဒပညာရှင် J. R. Firth က ပြောခဲ့သလို၊ \"စကားလုံးတစ်လုံး၏ အပြည့်အစုံသော အဓိပ္ပါယ်သည် အမြဲတမ်း အခြေအနေအရသာသာ ရှိနိုင်ပြီး အခြေအနေမှ ကွဲလွဲသော အဓိပ္ပါယ်ကို လေ့လာခြင်းသည် အလေးထားစဉ်းစားရန် မဖြစ်နိုင်ပါ။\" ကျွန်ုပ်တို့သည် သင်တန်း၏ နောက်ပိုင်းတွင် ဘာသာစကား မော်ဒယ်တစ်ခုကို အသုံးပြု၍ စာသားမှ အခြေအနေဆိုင်ရာ အချက်အလက်များကို ဖမ်းယူနည်းကို လေ့လာသွားပါမည်။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**အကြောင်းကြားချက်**: \nဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေပါသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှု ဝန်ဆောင်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"interpreter": {
|
|
"hash": "0cb620c6d4b9f7a635928804c26cf22403d89d98d79684e4529119355ee6d5a5"
|
|
},
|
|
"kernel_info": {
|
|
"name": "conda-env-py37_tensorflow-py"
|
|
},
|
|
"kernelspec": {
|
|
"display_name": "py37_tensorflow",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.8.12"
|
|
},
|
|
"nteract": {
|
|
"version": "nteract-front-end@1.0.0"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "19b43951d55b377a76209c24c1f017e4",
|
|
"translation_date": "2025-08-30T10:45:25+00:00",
|
|
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
|
|
"language_code": "my"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |