573 lines
34 KiB
Plaintext
573 lines
34 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# စာသားအမျိုးအစားသတ်မှတ်ခြင်း အလုပ်\n",
|
||
"\n",
|
||
"ကျွန်တော်တို့ ပြောခဲ့သလို **AG_NEWS** ဒေတာစုအပေါ် အခြေခံပြီး သတင်းခေါင်းစဉ်များကို ကမ္ဘာ့သတင်း၊ အားကစား၊ စီးပွားရေးနှင့် သိပ္ပံ/နည်းပညာ စသည့် ၄ မျိုးအတွင်းမှ တစ်ခုအဖြစ် သတ်မှတ်ရန် ရိုးရှင်းသော စာသားအမျိုးအစားသတ်မှတ်ခြင်း အလုပ်ကို အာရုံစိုက်သွားပါမည်။\n",
|
||
"\n",
|
||
"## ဒေတာစု\n",
|
||
"\n",
|
||
"ဒီဒေတာစုကို [`torchtext`](https://github.com/pytorch/text) module ထဲမှာ ပါဝင်ပြီး၊ အလွယ်တကူ အသုံးပြုနိုင်ပါတယ်။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import torch\n",
|
||
"import torchtext\n",
|
||
"import os\n",
|
||
"import collections\n",
|
||
"os.makedirs('./data',exist_ok=True)\n",
|
||
"train_dataset, test_dataset = torchtext.datasets.AG_NEWS(root='./data')\n",
|
||
"classes = ['World', 'Sports', 'Business', 'Sci/Tech']"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"ဒီမှာ `train_dataset` နဲ့ `test_dataset` တွေဟာ label (အတန်းနံပါတ်) နဲ့ text တို့ကို အတွဲလိုက်ပြန်ပေးတဲ့ collection တွေကို ပါဝင်ထားပြီး၊ ဥပမာအားဖြင့်:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(3,\n",
|
||
" \"Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\\\band of ultra-cynics, are seeing green again.\")"
|
||
]
|
||
},
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"list(train_dataset)[0]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"ဒါဆိုရင်၊ ကျွန်တော်တို့ရဲ့ဒေတာစနစ်ထဲက နောက်ဆုံးထွက်ခေါင်းစဉ်အသစ် ၁၀ ခုကို ပုံနှိပ်ထုတ်ကြမယ်:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"**Sci/Tech** -> Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\band of ultra-cynics, are seeing green again.\n",
|
||
"**Sci/Tech** -> Carlyle Looks Toward Commercial Aerospace (Reuters) Reuters - Private investment firm Carlyle Group,\\which has a reputation for making well-timed and occasionally\\controversial plays in the defense industry, has quietly placed\\its bets on another part of the market.\n",
|
||
"**Sci/Tech** -> Oil and Economy Cloud Stocks' Outlook (Reuters) Reuters - Soaring crude prices plus worries\\about the economy and the outlook for earnings are expected to\\hang over the stock market next week during the depth of the\\summer doldrums.\n",
|
||
"**Sci/Tech** -> Iraq Halts Oil Exports from Main Southern Pipeline (Reuters) Reuters - Authorities have halted oil export\\flows from the main pipeline in southern Iraq after\\intelligence showed a rebel militia could strike\\infrastructure, an oil official said on Saturday.\n",
|
||
"**Sci/Tech** -> Oil prices soar to all-time record, posing new menace to US economy (AFP) AFP - Tearaway world oil prices, toppling records and straining wallets, present a new economic menace barely three months before the US presidential elections.\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"for i,x in zip(range(5),train_dataset):\n",
|
||
" print(f\"**{classes[x[0]]}** -> {x[1]}\")\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"ဒေတာစနစ်များသည် အကြောင်းအရာများဖြစ်သောကြောင့်၊ ဒေတာကို မကြိမ်များစွာ အသုံးပြုလိုပါက ဒါကို စာရင်းအဖြစ် ပြောင်းလဲရန် လိုအပ်သည်။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"train_dataset, test_dataset = torchtext.datasets.AG_NEWS(root='./data')\n",
|
||
"train_dataset = list(train_dataset)\n",
|
||
"test_dataset = list(test_dataset)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Tokenization\n",
|
||
"\n",
|
||
"အခုတော့ စာသားတွေကို **နံပါတ်တွေ** အဖြစ် ပြောင်းလဲပြီး tensors အနေနဲ့ ကိုယ်စားပြုနိုင်ဖို့ လိုအပ်ပါတယ်။ စကားလုံးအဆင့် ကိုယ်စားပြုမှု ရရှိချင်ရင် အောက်ပါ အရာနှစ်ခု လုပ်ဆောင်ရပါမယ်။\n",
|
||
"* **tokenizer** ကို အသုံးပြုပြီး စာသားကို **tokens** အဖြစ် ခွဲခြားပါ။\n",
|
||
"* အဲ့ဒီ tokens တွေကို **vocabulary** တစ်ခု တည်ဆောက်ပါ။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"['he', 'said', 'hello']"
|
||
]
|
||
},
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"tokenizer = torchtext.data.utils.get_tokenizer('basic_english')\n",
|
||
"tokenizer('He said: hello')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"counter = collections.Counter()\n",
|
||
"for (label, line) in train_dataset:\n",
|
||
" counter.update(tokenizer(line))\n",
|
||
"vocab = torchtext.vocab.vocab(counter, min_freq=1)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Vocab size if 95810\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[599, 3279, 97, 1220, 329, 225, 7368]"
|
||
]
|
||
},
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"vocab_size = len(vocab)\n",
|
||
"print(f\"Vocab size if {vocab_size}\")\n",
|
||
"\n",
|
||
"stoi = vocab.get_stoi() # dict to convert tokens to indices\n",
|
||
"\n",
|
||
"def encode(x):\n",
|
||
" return [stoi[s] for s in tokenizer(x)]\n",
|
||
"\n",
|
||
"encode('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": 7,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"array([[1, 1, 0, 2, 0, 0, 0, 0, 0]], dtype=int64)"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"from sklearn.feature_extraction.text import CountVectorizer\n",
|
||
"vectorizer = CountVectorizer()\n",
|
||
"corpus = [\n",
|
||
" 'I like hot dogs.',\n",
|
||
" 'The dog ran fast.',\n",
|
||
" 'Its hot outside.',\n",
|
||
" ]\n",
|
||
"vectorizer.fit_transform(corpus)\n",
|
||
"vectorizer.transform(['My dog likes hot dogs on a hot day.']).toarray()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"AG_NEWS ဒေတာစဉ်၏ဗက်တာကိုယ်စားပြုမှုမှ bag-of-words ဗက်တာကိုတွက်ချက်ရန်အတွက် ကျွန်ုပ်တို့အောက်ပါဖင်ခွင့်ကိုအသုံးပြုနိုင်သည်။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"tensor([2., 1., 2., ..., 0., 0., 0.])\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"vocab_size = len(vocab)\n",
|
||
"\n",
|
||
"def to_bow(text,bow_vocab_size=vocab_size):\n",
|
||
" res = torch.zeros(bow_vocab_size,dtype=torch.float32)\n",
|
||
" for i in encode(text):\n",
|
||
" if i<bow_vocab_size:\n",
|
||
" res[i] += 1\n",
|
||
" return res\n",
|
||
"\n",
|
||
"print(to_bow(train_dataset[0][1]))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## BoW ခွဲခြားမှုစနစ်ကို လေ့ကျင့်ခြင်း\n",
|
||
"\n",
|
||
"အခုတော့ ကျွန်တော်တို့ စကားလုံးအိတ် (Bag-of-Words) ကိုယ်စားပြုမှုကို တည်ဆောက်ပုံကို သင်ယူပြီးပြီဆိုတော့၊ အဲ့ဒီအပေါ်မှာ ခွဲခြားမှုစနစ်တစ်ခုကို လေ့ကျင့်ကြမယ်။ ပထမဦးဆုံး ကျွန်တော်တို့ရဲ့ dataset ကို လေ့ကျင့်ဖို့အတွက် ပြောင်းလဲဖို့လိုအပ်ပါတယ်၊ အဲ့ဒီမှာ အနေအထား vector ကိုယ်စားပြုမှုအားလုံးကို စကားလုံးအိတ်ကိုယ်စားပြုမှုအဖြစ် ပြောင်းလဲရပါမယ်။ ဒါကို `bowify` function ကို standard torch `DataLoader` ရဲ့ `collate_fn` parameter အဖြစ် ဖြတ်သွားခြင်းဖြင့် ပြုလုပ်နိုင်ပါတယ်:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 21,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from torch.utils.data import DataLoader\n",
|
||
"import numpy as np \n",
|
||
"\n",
|
||
"# this collate function gets list of batch_size tuples, and needs to \n",
|
||
"# return a pair of label-feature tensors for the whole minibatch\n",
|
||
"def bowify(b):\n",
|
||
" return (\n",
|
||
" torch.LongTensor([t[0]-1 for t in b]),\n",
|
||
" torch.stack([to_bow(t[1]) for t in b])\n",
|
||
" )\n",
|
||
"\n",
|
||
"train_loader = DataLoader(train_dataset, batch_size=16, collate_fn=bowify, shuffle=True)\n",
|
||
"test_loader = DataLoader(test_dataset, batch_size=16, collate_fn=bowify, shuffle=True)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"အခုတော့ linear layer တစ်ခုပါဝင်တဲ့ ရိုးရှင်းတဲ့ classifier neural network ကို သတ်မှတ်ကြမယ်။ input vector ရဲ့ အရွယ်အစားက `vocab_size` နဲ့ တန်းတူပြီး၊ output size က class အရေအတွက် (၄) ကို ကိုယ်စားပြုပါတယ်။ Classification task ကို ဖြေရှင်းနေတဲ့အတွက်၊ နောက်ဆုံး activation function က `LogSoftmax()` ဖြစ်ပါတယ်။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"net = torch.nn.Sequential(torch.nn.Linear(vocab_size,4),torch.nn.LogSoftmax(dim=1))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"အခုတော့ ကျွန်တော်တို့ PyTorch ပုံမှန်လေ့ကျင့်မှု loop ကို သတ်မှတ်ပါမယ်။ ကျွန်တော်တို့ရဲ့ dataset က အတော်လေးကြီးမားတဲ့အတွက်၊ သင်ကြားရေးရည်ရွယ်ချက်အတွက် epoch တစ်ခုသာလေ့ကျင့်မှာဖြစ်ပြီး၊ တစ်ခါတစ်ရံမှာတော့ epoch တစ်ခုလုံးမပြည့်လည်းဖြစ်နိုင်ပါတယ် (`epoch_size` parameter ကို သတ်မှတ်ခြင်းအားဖြင့် လေ့ကျင့်မှုကို ကန့်သတ်နိုင်ပါတယ်)။ လေ့ကျင့်မှုအတွင်း စုစုပေါင်းလေ့ကျင့်မှုတိကျမှုကိုလည်း အစီရင်ခံမှာဖြစ်ပြီး၊ အစီရင်ခံမှုရဲ့ အကြိမ်ရေကို `report_freq` parameter ကို အသုံးပြု၍ သတ်မှတ်နိုင်ပါတယ်။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def train_epoch(net,dataloader,lr=0.01,optimizer=None,loss_fn = torch.nn.NLLLoss(),epoch_size=None, report_freq=200):\n",
|
||
" optimizer = optimizer or torch.optim.Adam(net.parameters(),lr=lr)\n",
|
||
" net.train()\n",
|
||
" total_loss,acc,count,i = 0,0,0,0\n",
|
||
" for labels,features in dataloader:\n",
|
||
" optimizer.zero_grad()\n",
|
||
" out = net(features)\n",
|
||
" loss = loss_fn(out,labels) #cross_entropy(out,labels)\n",
|
||
" loss.backward()\n",
|
||
" optimizer.step()\n",
|
||
" total_loss+=loss\n",
|
||
" _,predicted = torch.max(out,1)\n",
|
||
" acc+=(predicted==labels).sum()\n",
|
||
" count+=len(labels)\n",
|
||
" i+=1\n",
|
||
" if i%report_freq==0:\n",
|
||
" print(f\"{count}: acc={acc.item()/count}\")\n",
|
||
" if epoch_size and count>epoch_size:\n",
|
||
" break\n",
|
||
" return total_loss.item()/count, acc.item()/count"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 25,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"3200: acc=0.8028125\n",
|
||
"6400: acc=0.8371875\n",
|
||
"9600: acc=0.8534375\n",
|
||
"12800: acc=0.85765625\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(0.026090790722161722, 0.8620069296375267)"
|
||
]
|
||
},
|
||
"execution_count": 25,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"train_epoch(net,train_loader,epoch_size=15000)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## BiGrams, TriGrams နှင့် N-Grams\n",
|
||
"\n",
|
||
"Bag of words နည်းလမ်း၏ အားနည်းချက်တစ်ခုမှာ စကားလုံးအချို့သည် စကားလုံးများပေါင်းစပ်မှုဖြစ်ပြီး၊ ဥပမာအားဖြင့် 'hot dog' ဆိုသောစကားလုံးသည် 'hot' နှင့် 'dog' ဆိုသောစကားလုံးများ၏ အခြားအကြောင်းအရာများတွင်ရှိသည့် အဓိပ္ပါယ်နှင့် လုံးဝကွဲပြားနေသည်။ 'hot' နှင့် 'dog' စကားလုံးများကို အမြဲတမ်းတူညီသောဗက်တာများဖြင့် ကိုယ်စားပြုပါက၊ ၎င်းသည် မော်ဒယ်ကို ရှုပ်ထွေးစေနိုင်သည်။\n",
|
||
"\n",
|
||
"ဤပြဿနာကို ဖြေရှင်းရန် **N-gram ကိုယ်စားပြုမှုများ** ကို စာရွက်စာတမ်းများကို ခွဲခြားသတ်မှတ်ရာတွင် မကြာခဏအသုံးပြုကြပြီး၊ စကားလုံးတစ်လုံး၊ စကားလုံးနှစ်လုံး (bi-word) သို့မဟုတ် စကားလုံးသုံးလုံး (tri-word) ၏ ကြိမ်နှုန်းသည် Classifier များကို လေ့ကျင့်ရန် အသုံးဝင်သော အင်္ဂါရပ်တစ်ခုဖြစ်သည်။ ဥပမာအားဖြင့် bigram ကိုယ်စားပြုမှုတွင်၊ မူလစကားလုံးများအပြင် စကားလုံးစုံအားလုံးကို Vocabulary ထဲသို့ ထည့်သွင်းပါမည်။\n",
|
||
"\n",
|
||
"အောက်တွင် Scikit Learn ကို အသုံးပြု၍ bigram bag of word ကိုယ်စားပြုမှုကို ဘယ်လိုဖန်တီးရမည်ကို ဥပမာတစ်ခုအနေဖြင့် ဖော်ပြထားသည်-\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 26,
|
||
"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": 26,
|
||
"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 နည်းလမ်း၏ အဓိကအားနည်းချက်မှာ စကားလုံးစာရင်းအရွယ်အစားက အလွန်မြန်မြန်ဆန်ဆန် တိုးလာတတ်သည်။ အကဲဖြတ်လို့ရတဲ့အခြေအနေမှာတော့ N-gram ကို *embeddings* ကဲ့သို့သော အတိုင်းအတာလျှော့ချနည်းလမ်းများနှင့် ပေါင်းစပ်အသုံးပြုရန် လိုအပ်ပါသည်။ ဒီအကြောင်းကို နောက်တစ်ခုနစ်မှာ ဆွေးနွေးသွားမည်ဖြစ်သည်။\n",
|
||
"\n",
|
||
"**AG News** dataset တွင် N-gram ကို အသုံးပြုရန်အတွက် အထူး ngram စကားလုံးစာရင်းကို တည်ဆောက်ရန် လိုအပ်ပါသည်။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 27,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Bigram vocabulary length = 1308842\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"counter = collections.Counter()\n",
|
||
"for (label, line) in train_dataset:\n",
|
||
" l = tokenizer(line)\n",
|
||
" counter.update(torchtext.data.utils.ngrams_iterator(l,ngrams=2))\n",
|
||
" \n",
|
||
"bi_vocab = torchtext.vocab.vocab(counter, min_freq=1)\n",
|
||
"\n",
|
||
"print(\"Bigram vocabulary length = \",len(bi_vocab))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"ကျွန်တော်တို့ အထက်မှာရေးထားတဲ့ ကုဒ်ကို classifier ကို သင်ကြားဖို့ အသုံးပြုနိုင်ပါတယ်၊ သို့သော် memory ကို အလွန်အကျွံ အသုံးပြုမိနိုင်ပါတယ်။ နောက်တစ်ခုမှာတော့ bigram classifier ကို embeddings အသုံးပြုပြီး သင်ကြားပါမယ်။\n",
|
||
"\n",
|
||
"> **Note:** သင့်ရဲ့ text မှာ သတ်မှတ်ထားတဲ့ အကြိမ်အရေအတွက်ထက် ပိုများတဲ့ ngrams တွေကိုသာ ထားနိုင်ပါတယ်။ ဒါက infrequent bigrams တွေကို ဖယ်ရှားပေးပြီး dimensionality ကို အလွန်လျော့ချနိုင်စေမှာ ဖြစ်ပါတယ်။ ဒီအတွက် `min_freq` parameter ကို မြင့်မားတဲ့တန်ဖိုးတစ်ခု သတ်မှတ်ပေးပြီး vocabulary ရဲ့ အရှည်ပြောင်းလဲမှုကို ကြည့်ရှုပါ။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## စကားလုံးအကြိမ်ရေနှင့် စာရွက်စာတမ်းဆိုင်ရာ အလေးချိန် (TF-IDF)\n",
|
||
"\n",
|
||
"BoW (Bag of Words) ကိုယ်စားပြုမှုတွင် စကားလုံးများ၏ ပေါ်ပေါက်မှုအားလုံးကို တန်းတူအလေးချိန်ပေးထားပြီး၊ စကားလုံးတစ်လုံးချင်းစီ၏ အရေးပါမှုကို မထည့်သွင်းစဉ်းစားထားပါ။ သို့သော်၊ *a*, *in* စသည့် မကြာခဏတွေ့ရသော စကားလုံးများသည် အထူးသီးသန့်စကားလုံးများထက် အမျိုးအစားခွဲခြားမှုတွင် အရေးပါမှုနည်းပါသည်။ အမှန်တစ်ကယ်တွင်၊ NLP လုပ်ငန်းစဉ်များအများစုတွင် စကားလုံးတစ်ချို့သည် အခြားစကားလုံးများထက် ပိုမိုသက်ဆိုင်မှုရှိပါသည်။\n",
|
||
"\n",
|
||
"**TF-IDF** သည် **term frequency–inverse document frequency** ၏ အတိုကောက်ဖြစ်သည်။ ၎င်းသည် Bag of Words ၏ အမျိုးအစားတစ်ခုဖြစ်ပြီး၊ စကားလုံးတစ်လုံး၏ စာရွက်စာတမ်းတွင် ရှိနေမှုကို ပြသသည့် 0/1 အဘိဓါန်တန်ဖိုးအစား၊ စကားလုံးပေါ်ပေါက်မှု၏ အကြိမ်ရေနှင့် ဆက်စပ်သော အလျားလိုက်တန်ဖိုးကို အသုံးပြုထားသည်။\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}$ သည် စကားလုံးတစ်လုံးသည် စာရွက်စာတမ်းတစ်ခုတွင် ပေါ်ပေါက်မှုအကြိမ်ရေနှင့် လိုက်လျောညီထွေဖြစ်ပြီး၊ စကားလုံးတစ်လုံးသည် စုစုပေါင်း စာရွက်စာတမ်းများတွင် မကြာခဏပေါ်ပေါက်မှုကို ပြင်ဆင်ပေးသည်။ ဥပမာအားဖြင့်၊ စကားလုံးတစ်လုံးသည် စုစုပေါင်း စာရွက်စာတမ်းများအားလုံးတွင် ပေါ်ပေါက်နေပါက $df_i=N$ ဖြစ်ပြီး၊ $w_{ij}=0$ ဖြစ်မည်ဖြစ်၍ ၎င်းစကားလုံးများကို လုံးဝလျစ်လျူရှုမည်ဖြစ်သည်။\n",
|
||
"\n",
|
||
"Scikit Learn ကို အသုံးပြု၍ စာသားများ၏ TF-IDF ကို အလွယ်တကူ ဖန်တီးနိုင်ပါသည်။\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 28,
|
||
"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": 28,
|
||
"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": [
|
||
"## အနှိပ်ချုပ်\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": "16af2a8bbb083ea23e5e41c7f5787656b2ce26968575d8763f2c4b17f9cd711f"
|
||
},
|
||
"kernelspec": {
|
||
"display_name": "Python 3.8.12 ('py38')",
|
||
"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"
|
||
},
|
||
"coopTranslator": {
|
||
"original_hash": "7b9040985e748e4e2d4c689892456ad7",
|
||
"translation_date": "2025-08-30T10:42:22+00:00",
|
||
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationPyTorch.ipynb",
|
||
"language_code": "my"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
} |