577 lines
34 KiB
Plaintext
577 lines
34 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# ടെക്സ്റ്റ് വർഗ്ഗീകരണ പ്രവർത്തി\n",
|
||
"\n",
|
||
"നാം പറഞ്ഞതുപോലെ, നാം **AG_NEWS** ഡാറ്റാസെറ്റിനെ അടിസ്ഥാനമാക്കി ലളിതമായ ടെക്സ്റ്റ് വർഗ്ഗീകരണ പ്രവർത്തനത്തിൽ ശ്രദ്ധ കേന്ദ്രീകരിക്കും, ഇത് വാർത്താ തലക്കെട്ടുകൾ നാല് വിഭാഗങ്ങളിൽ ഒന്നായി വർഗ്ഗീകരിക്കുകയാണ്: ലോകം, കായികം, ബിസിനസ്സ്, സയൻസ്/ടെക്.\n",
|
||
"\n",
|
||
"## ഡാറ്റാസെറ്റ്\n",
|
||
"\n",
|
||
"ഈ ഡാറ്റാസെറ്റ് [`torchtext`](https://github.com/pytorch/text) മോഡ്യൂളിൽ ഉൾപ്പെടുത്തിയിട്ടുള്ളതാണ്, അതിനാൽ നാം എളുപ്പത്തിൽ അതിലേക്ക് പ്രവേശിക്കാം.\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` ഉം ലേബൽ (ക്ലാസിന്റെ സംഖ്യ)യും ടെക്സ്റ്റും യോജിപ്പായി നൽകുന്ന ശേഖരങ്ങളാണ്, ഉദാഹരണത്തിന്:\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": [
|
||
"അപ്പോൾ, നമ്മുടെ ഡാറ്റാസെറ്റിൽ നിന്നുള്ള ആദ്യ 10 പുതിയ തലക്കെട്ടുകൾ പ്രിന്റ് ചെയ്യാം:\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": [
|
||
"## ടോക്കനൈസേഷൻ\n",
|
||
"\n",
|
||
"ഇപ്പോൾ നമുക്ക് ടെക്സ്റ്റ് **സംഖ്യകളായി** മാറ്റേണ്ടതുണ്ട്, അവ ടെൻസറുകളായി പ്രതിനിധീകരിക്കാനാകും. വാക്ക്-നിലവാരത്തിലുള്ള പ്രതിനിധാനം വേണമെങ്കിൽ, നമുക്ക് രണ്ട് കാര്യങ്ങൾ ചെയ്യണം:\n",
|
||
"* ടെക്സ്റ്റ് **ടോക്കണുകളായി** വിഭജിക്കാൻ **ടോക്കനൈസർ** ഉപയോഗിക്കുക\n",
|
||
"* ആ ടോക്കണുകളുടെ **വോകാബുലറി** നിർമ്മിക്കുക.\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": [
|
||
"വാക്ക് സമ്പത്തിനെ ഉപയോഗിച്ച്, നാം എളുപ്പത്തിൽ ടോക്കൺ ചെയ്ത സ്ട്രിംഗ് ഒരു സംഖ്യാ സമാഹാരമായി എൻകോഡ് ചെയ്യാൻ കഴിയും:\n"
|
||
]
|
||
},
|
||
{
|
||
"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": [
|
||
"## വാക്കുകളുടെ ബാഗ് ടെക്സ്റ്റ് പ്രതിനിധാനം\n",
|
||
"\n",
|
||
"വാക്കുകൾ അർത്ഥം പ്രതിനിധാനം ചെയ്യുന്നതിനാൽ, വാചകത്തിലെ ക്രമം നോക്കാതെ ചിലപ്പോൾ ഓരോ വാക്കുകളും നോക്കി ടെക്സ്റ്റിന്റെ അർത്ഥം മനസിലാക്കാൻ കഴിയും. ഉദാഹരണത്തിന്, വാർത്തകൾ വർഗ്ഗീകരിക്കുമ്പോൾ *weather*, *snow* പോലുള്ള വാക്കുകൾ *weather forecast* സൂചിപ്പിക്കാം, അതേസമയം *stocks*, *dollar* പോലുള്ള വാക്കുകൾ *financial news* എന്ന വിഭാഗത്തിലേക്ക് പെടും.\n",
|
||
"\n",
|
||
"**Bag of Words** (BoW) വെക്ടർ പ്രതിനിധാനം ഏറ്റവും സാധാരണമായി ഉപയോഗിക്കുന്ന പരമ്പരാഗത വെക്ടർ പ്രതിനിധാനമാണ്. ഓരോ വാക്കും ഒരു വെക്ടർ ഇൻഡക്സുമായി ബന്ധിപ്പിച്ചിരിക്കുന്നു, വെക്ടർ ഘടകം ഒരു നൽകിയ ഡോക്യുമെന്റിൽ ആ വാക്കിന്റെ ആവർത്തനങ്ങളുടെ എണ്ണം ഉൾക്കൊള്ളുന്നു.\n",
|
||
"\n",
|
||
" \n",
|
||
"\n",
|
||
"> **Note**: BoW-നെ ടെക്സ്റ്റിലെ ഓരോ വാക്കിനും ഉള്ള ഒന്ന്-ഹോട്ട്-എൻകോഡഡ് വെക്ടറുകളുടെ മൊത്തം കൂട്ടമായി കാണാം.\n",
|
||
"\n",
|
||
"താഴെ Scikit Learn പൈതൺ ലൈബ്രറി ഉപയോഗിച്ച് വാക്കുകളുടെ ബാഗ് പ്രതിനിധാനം എങ്ങനെ സൃഷ്ടിക്കാമെന്ന് ഒരു ഉദാഹരണം കൊടുത്തിരിക്കുന്നു:\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 ഡാറ്റാസെറ്റിന്റെ വെക്ടർ പ്രതിനിധാനത്തിൽ നിന്ന് ബാഗ്-ഓഫ്-വേർഡ്സ് വെക്ടർ കണക്കാക്കാൻ, നാം താഴെ കൊടുത്തിരിക്കുന്ന ഫംഗ്ഷൻ ഉപയോഗിക്കാം:\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": [
|
||
"> **കുറിപ്പ്:** ഇവിടെ നാം ഡിഫോൾട്ട് വാക്ക് സമാഹാരത്തിന്റെ വലിപ്പം നിർദ്ദേശിക്കാൻ ഗ്ലോബൽ `vocab_size` വേരിയബിൾ ഉപയോഗിക്കുന്നു. സാധാരണയായി വാക്ക് സമാഹാരത്തിന്റെ വലിപ്പം വളരെ വലുതായിരിക്കും, അതിനാൽ വാക്ക് സമാഹാരത്തിന്റെ വലിപ്പം ഏറ്റവും സാധാരണമായ വാക്കുകളിലേക്കു പരിമിതപ്പെടുത്താം. `vocab_size` മൂല്യം കുറച്ച് താഴെ കൊടുത്തിരിക്കുന്ന കോഡ് പ്രവർത്തിപ്പിച്ച് നോക്കൂ, അത് കൃത്യതയെ എങ്ങനെ ബാധിക്കുന്നുവെന്ന് കാണൂ. ചില കൃത്യത കുറവ് പ്രതീക്ഷിക്കാം, പക്ഷേ പ്രകടനത്തിൽ വലിയ വ്യത്യാസമുണ്ടാകില്ല.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## BoW ക്ലാസിഫയർ പരിശീലനം\n",
|
||
"\n",
|
||
"നമ്മൾ ടെക്സ്റ്റിന്റെ Bag-of-Words പ്രതിനിധാനം എങ്ങനെ നിർമ്മിക്കാമെന്ന് പഠിച്ചപ്പോൾ, അതിന്റെ മുകളിൽ ഒരു ക്ലാസിഫയർ പരിശീലിപ്പിക്കാം. ആദ്യം, പരിശീലനത്തിനായി നമ്മുടെ ഡാറ്റാസെറ്റ് എല്ലാ സ്ഥാനവിവര വക്ടർ പ്രതിനിധാനങ്ങളും bag-of-words പ്രതിനിധാനങ്ങളായി മാറ്റേണ്ടതുണ്ട്. ഇത് സാധാരണ torch `DataLoader`-ലേക്ക് `collate_fn` പാരാമീറ്ററായി `bowify` ഫംഗ്ഷൻ നൽകിക്കൊണ്ട് സാധ്യമാക്കാം:\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": [
|
||
"ഇപ്പോൾ ഒരു ലീനിയർ ലെയർ അടങ്ങിയ ഒരു ലളിതമായ ക്ലാസിഫയർ ന്യൂറൽ നെറ്റ്വർക്ക് നിർവചിക്കാം. ഇൻപുട്ട് വെക്ടറിന്റെ വലുപ്പം `vocab_size`-നോട് തുല്യമാണ്, ഔട്ട്പുട്ട് വലുപ്പം ക്ലാസുകളുടെ എണ്ണം (4) അനുസരിച്ചാണ്. നാം ക്ലാസിഫിക്കേഷൻ ടാസ്ക് പരിഹരിക്കുന്നതിനാൽ, അവസാന ആക്ടിവേഷൻ ഫംഗ്ഷൻ `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 ട്രെയിനിംഗ് ലൂപ്പ് നിർവചിക്കും. നമ്മുടെ ഡാറ്റാസെറ്റ് വളരെ വലുതായതിനാൽ, പഠനത്തിനായി നാം ഒരു epoch മാത്രമേ ട്രെയിൻ ചെയ്യൂ, ചിലപ്പോൾ ഒരു epoch-ലും കുറവായി (epoch_size പാരാമീറ്റർ ഉപയോഗിച്ച് ട്രെയിനിംഗ് പരിധി നിശ്ചയിക്കാം). ട്രെയിനിംഗിനിടെ സമാഹരിച്ച accuracy-യും നാം റിപ്പോർട്ട് ചെയ്യും; റിപ്പോർട്ട് ചെയ്യാനുള്ള ആവൃത്തി report_freq പാരാമീറ്റർ ഉപയോഗിച്ച് നിശ്ചയിക്കാം.\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": [
|
||
"## ബൈഗ്രാമുകൾ, ട്രൈഗ്രാമുകൾ, എൻ-ഗ്രാമുകൾ\n",
|
||
"\n",
|
||
"ഒരു ബാഗ് ഓഫ് വേഡ്സ് സമീപനത്തിന്റെ ഒരു പരിമിതിയാണ് ചില വാക്കുകൾ മൾട്ടി വേഡ് എക്സ്പ്രഷനുകളുടെ ഭാഗമായിരിക്കുക എന്നത്. ഉദാഹരണത്തിന്, 'hot dog' എന്ന വാക്കിന് 'hot' ഉം 'dog' ഉം എന്ന വാക്കുകളുടെ വ്യത്യസ്തമായ അർത്ഥമുണ്ട്. 'hot' ഉം 'dog' ഉം എല്ലായ്പ്പോഴും ഒരേ വെക്ടറുകൾ ഉപയോഗിച്ച് പ്രതിനിധീകരിച്ചാൽ, അത് നമ്മുടെ മോഡലിനെ ആശയക്കുഴപ്പത്തിലാക്കാം.\n",
|
||
"\n",
|
||
"ഇതിന് പരിഹാരമായി, **N-ഗ്രാം പ്രതിനിധാനങ്ങൾ** ഡോക്യുമെന്റ് ക്ലാസിഫിക്കേഷനിൽ ഉപയോഗിക്കാറുണ്ട്, ഇവിടെ ഓരോ വാക്കിന്റെയും, ബൈ-വേഡിന്റെയും, ട്രൈ-വേഡിന്റെയും ആവൃത്തി ക്ലാസിഫയർ പരിശീലനത്തിന് ഉപകാരപ്രദമായ ഫീച്ചറാണ്. ഉദാഹരണത്തിന്, ബൈഗ്രാം പ്രതിനിധാനത്തിൽ, നാം വാക്കുകളുടെ യോജിപ്പുകൾ എല്ലാം വാക്കുകളുടെ ശബ്ദകോശത്തിൽ ചേർക്കും, ഒറിജിനൽ വാക്കുകൾക്കൊപ്പം.\n",
|
||
"\n",
|
||
"താഴെ Scikit Learn ഉപയോഗിച്ച് ബൈഗ്രാം ബാഗ് ഓഫ് വേഡ്സ് പ്രതിനിധാനം എങ്ങനെ സൃഷ്ടിക്കാമെന്ന് ഒരു ഉദാഹരണം കാണിക്കുന്നു:\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 പ്രതിനിധാനം ചില ഡൈമെൻഷണാലിറ്റി കുറയ്ക്കൽ സാങ്കേതികവിദ്യകളുമായി, ഉദാഹരണത്തിന് *എംബെഡിംഗുകൾ*, സംയോജിപ്പിക്കേണ്ടതുണ്ട്, ഇത് അടുത്ത യൂണിറ്റിൽ നാം ചർച്ച ചെയ്യും.\n",
|
||
"\n",
|
||
"നമ്മുടെ **AG News** ഡാറ്റാസെറ്റിൽ 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": [
|
||
"അപ്പോൾ മുകളിൽ നൽകിയ കോഡ് തന്നെ ക്ലാസിഫയർ ട്രെയിൻ ചെയ്യാൻ ഉപയോഗിക്കാം, എന്നാൽ അത് മെമ്മറി കാര്യക്ഷമമല്ല. അടുത്ത യൂണിറ്റിൽ, നാം എംബെഡിംഗുകൾ ഉപയോഗിച്ച് ബിഗ്രാം ക്ലാസിഫയർ ട്രെയിൻ ചെയ്യും.\n",
|
||
"\n",
|
||
"> **Note:** നിഗ്രാമുകൾ ടെക്സ്റ്റിൽ നിശ്ചിത തവണകളിൽ കൂടുതൽ സംഭവിക്കുന്നവ മാത്രമേ നിങ്ങൾ വയ്ക്കാൻ കഴിയൂ. ഇതിലൂടെ അപൂർവമായ ബിഗ്രാമുകൾ ഒഴിവാക്കപ്പെടുകയും, ഡൈമെൻഷണാലിറ്റി ഗണ്യമായി കുറയുകയും ചെയ്യും. ഇത് ചെയ്യാൻ, `min_freq` പാരാമീറ്റർ ഉയർന്ന മൂല്യത്തിൽ സജ്ജമാക്കി, വാക്കുകളുടെ വാക്ക്സഭയുടെ നീളം എങ്ങനെ മാറുന്നു എന്ന് ശ്രദ്ധിക്കുക.\n"
|
||
]
|
||
},
|
||
{
|
||
"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 ന്റെ ഒരു വ്യത്യാസമാണ്, ഇവിടെ ഒരു വാക്ക് ഒരു ഡോക്യുമെന്റിൽ ഉണ്ടെന്നത് സൂചിപ്പിക്കുന്ന 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}$ എന്നത് $j$ ഡോക്യുമെന്റിൽ $i$ വാക്ക് എത്ര തവണ സംഭവിച്ചുവെന്ന്, അതായത് മുമ്പ് കണ്ട 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 പ്രതിനിധാനങ്ങൾ വ്യത്യസ്ത വാക്കുകൾക്ക് ആവൃത്തി ഭാരമൊരുക്കിയിരുന്നാലും അവ അർത്ഥം അല്ലെങ്കിൽ ക്രമം പ്രതിനിധാനം ചെയ്യാൻ കഴിയുന്നില്ല. പ്രശസ്ത ഭാഷാശാസ്ത്രജ്ഞൻ J. R. Firth 1935-ൽ പറഞ്ഞതുപോലെ, \"ഒരു വാക്കിന്റെ പൂർണ്ണ അർത്ഥം എപ്പോഴും സാന്ദർഭികമാണ്, സാന്ദർഭം ഒഴികെയുള്ള അർത്ഥ പഠനം ഗൗരവത്തോടെ സ്വീകരിക്കാനാകില്ല.\" ഈ കോഴ്സിൽ പിന്നീട് നാം ഭാഷാ മോഡലിംഗിലൂടെ ടെക്സ്റ്റിൽ നിന്നുള്ള സാന്ദർഭിക വിവരങ്ങൾ എങ്ങനെ പിടിച്ചെടുക്കാമെന്ന് പഠിക്കും.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**അസൂയാ**: \nഈ രേഖ AI വിവർത്തന സേവനം [Co-op Translator](https://github.com/Azure/co-op-translator) ഉപയോഗിച്ച് വിവർത്തനം ചെയ്തതാണ്. നാം കൃത്യതയ്ക്ക് ശ്രമിച്ചിട്ടുണ്ടെങ്കിലും, സ്വയം പ്രവർത്തിക്കുന്ന വിവർത്തനങ്ങളിൽ പിശകുകൾ അല്ലെങ്കിൽ തെറ്റുകൾ ഉണ്ടാകാമെന്ന് ദയവായി ശ്രദ്ധിക്കുക. അതിന്റെ മാതൃഭാഷയിലുള്ള യഥാർത്ഥ രേഖ അധികാരപരമായ ഉറവിടമായി കണക്കാക്കണം. നിർണായക വിവരങ്ങൾക്ക്, പ്രൊഫഷണൽ മനുഷ്യ വിവർത്തനം ശുപാർശ ചെയ്യപ്പെടുന്നു. ഈ വിവർത്തനത്തിന്റെ ഉപയോഗത്തിൽ നിന്നുണ്ടാകുന്ന ഏതെങ്കിലും തെറ്റിദ്ധാരണകൾക്കോ തെറ്റായ വ്യാഖ്യാനങ്ങൾക്കോ ഞങ്ങൾ ഉത്തരവാദികളല്ല.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\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-11-26T01:35:56+00:00",
|
||
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationPyTorch.ipynb",
|
||
"language_code": "ml"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
} |