AI-For-Beginners/translations/ml/lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb

647 lines
41 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ടെക്സ്റ്റ് വർഗ്ഗീകരണ പ്രവർത്തി\n",
"\n",
"ഈ മോഡ്യൂളിൽ, നാം ഒരു ലളിതമായ ടെക്സ്റ്റ് വർഗ്ഗീകരണ പ്രവർത്തനത്തോടെ തുടങ്ങും, ഇത് **[AG_NEWS](http://www.di.unipi.it/~gulli/AG_corpus_of_news_articles.html)** ഡാറ്റാസെറ്റിനെ അടിസ്ഥാനമാക്കിയുള്ളതാണ്: നാം വാർത്താ തലക്കെട്ടുകൾ 4 വിഭാഗങ്ങളിൽ ഒന്നായി വർഗ്ഗീകരിക്കും: ലോകം, കായികം, ബിസിനസ്സ്, സയൻസ്/ടെക്.\n",
"\n",
"## ഡാറ്റാസെറ്റ്\n",
"\n",
"ഡാറ്റാസെറ്റ് ലോഡ് ചെയ്യാൻ, നാം **[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'] എന്നതും ഉപയോഗിച്ച് ഡാറ്റാസെറ്റിന്റെ പരിശീലനവും പരിശോധനാ ഭാഗങ്ങളും ആക്‌സസ് ചെയ്യാൻ കഴിയും:\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": [
"നമ്മുടെ ഡാറ്റാസെറ്റിൽ നിന്നുള്ള ആദ്യ 10 പുതിയ തലക്കെട്ടുകൾ പ്രിന്റ് ചെയ്യാം:\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",
"ഇപ്പോൾ ടെക്സ്റ്റ് **സംഖ്യകളായി** മാറ്റേണ്ടതുണ്ട്, അവ ടെൻസറുകളായി പ്രതിനിധീകരിക്കാനാകും. വാക്ക്-നിലവാര പ്രതിനിധാനം വേണമെങ്കിൽ, രണ്ട് കാര്യങ്ങൾ ചെയ്യണം:\n",
"\n",
"* ടെക്സ്റ്റ് **ടോക്കണുകളായി** വിഭജിക്കാൻ **ടോക്കണൈസർ** ഉപയോഗിക്കുക.\n",
"* ആ ടോക്കണുകളുടെ **വോകാബുലറി** നിർമ്മിക്കുക.\n",
"\n",
"### വോകാബുലറി വലുപ്പം പരിമിതപ്പെടുത്തൽ\n",
"\n",
"AG News ഡാറ്റാസെറ്റ് ഉദാഹരണത്തിൽ, വോകാബുലറി വലുപ്പം വളരെ വലുതാണ്, 100k-ലധികം വാക്കുകൾ. സാധാരണയായി, ടെക്സ്റ്റിൽ അപൂർവമായി വരുന്ന വാക്കുകൾ ആവശ്യമില്ല — ചില വാചകങ്ങളിൽ മാത്രമേ അവ ഉണ്ടാകൂ, മോഡൽ അവയിൽ നിന്ന് പഠിക്കില്ല. അതിനാൽ, വോകാബുലറി വലുപ്പം ചെറിയ ഒരു സംഖ്യയിലേക്ക് പരിമിതപ്പെടുത്തുന്നത് ബുദ്ധിമുട്ടില്ല, vectorizer കൺസ്ട്രക്ടറിലേക്ക് ഒരു argument നൽകിക്കൊണ്ട്:\n",
"\n",
"ഈ രണ്ട് ഘട്ടങ്ങളും **TextVectorization** ലെയർ ഉപയോഗിച്ച് കൈകാര്യം ചെയ്യാം. vectorizer ഒബ്ജക്റ്റ് സൃഷ്ടിച്ച്, ശേഷം `adapt` മെത്തഡ് വിളിച്ച് എല്ലാ ടെക്സ്റ്റും പരിശോധിച്ച് വോകാബുലറി നിർമ്മിക്കാം:\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": [
"## വാക്കുകളുടെ ബാഗ് ടെക്സ്റ്റ് പ്രതിനിധാനം\n",
"\n",
"വാക്കുകൾ അർത്ഥം പ്രതിനിധാനം ചെയ്യുന്നതിനാൽ, വാചകത്തിലെ വാക്കുകളുടെ ക്രമം നോക്കാതെ വെറും ഓരോ വാക്കുകളും നോക്കി ഒരു ടെക്സ്റ്റിന്റെ അർത്ഥം കണ്ടെത്താൻ സാധിക്കാറുണ്ട്. ഉദാഹരണത്തിന്, വാർത്തകൾ വർഗ്ഗീകരിക്കുമ്പോൾ *weather* (കാലാവസ്ഥ) എന്നതും *snow* (മഞ്ഞ്) എന്നതും *weather forecast* (കാലാവസ്ഥ പ്രവചനം) സൂചിപ്പിക്കാനിടയുള്ളവയാണ്, അതേസമയം *stocks* (സ്റ്റോക്കുകൾ) എന്നും *dollar* (ഡോളർ) എന്നും വരുന്ന വാക്കുകൾ *financial news* (സാമ്പത്തിക വാർത്തകൾ) എന്ന വിഭാഗത്തിലേക്ക് പോകും.\n",
"\n",
"**Bag-of-words** (BoW) വെക്ടർ പ്രതിനിധാനം ഏറ്റവും എളുപ്പത്തിൽ മനസ്സിലാക്കാവുന്ന പരമ്പരാഗത വെക്ടർ പ്രതിനിധാനമാണ്. ഓരോ വാക്കിനും ഒരു വെക്ടർ ഇൻഡക്സ് ബന്ധിപ്പിച്ചിരിക്കുന്നു, ഒരു വെക്ടർ ഘടകം ഒരു നൽകിയ ഡോക്യുമെന്റിൽ ഓരോ വാക്കിന്റെയും ആവർത്തനങ്ങളുടെ എണ്ണം ഉൾക്കൊള്ളുന്നു.\n",
"\n",
"![Image showing how a bag of words vector representation is represented in memory.](../../../../../translated_images/ml/bag-of-words-example.606fc1738f1d7ba9.webp) \n",
"\n",
"> **Note**: BoW-നെ ടെക്സ്റ്റിലെ ഓരോ വാക്കിനും ഉള്ള ഒന്ന്-ഹോട്ട്-എൻകോഡഡ് വെക്ടറുകളുടെ മൊത്തം കൂട്ടമായി കാണാം.\n",
"\n",
"താഴെ Scikit Learn പൈതൺ ലൈബ്രറി ഉപയോഗിച്ച് ബാഗ്-ഓഫ്-വേർഡ്സ് പ്രതിനിധാനം എങ്ങനെ സൃഷ്ടിക്കാമെന്ന് ഒരു ഉദാഹരണം കൊടുത്തിരിക്കുന്നു:\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": [
"മുകളിൽ നാം നിർവചിച്ച കേരാസ് വെക്ടറൈസർ ഉപയോഗിച്ച് ഓരോ വാക്കിന്റെ നമ്പറിനെയും വൺ-ഹോട്ട് എൻകോഡിങ്ങിലേക്ക് മാറ്റി ആ വെക്ടറുകൾ എല്ലാം കൂട്ടിച്ചേർക്കാം:\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": [
"> **Note**: മുമ്പത്തെ ഉദാഹരണത്തേക്കാൾ ഫലം വ്യത്യസ്തമാണെന്ന് നിങ്ങൾക്ക് അത്ഭുതമാകാം. കാരണം, Keras ഉദാഹരണത്തിൽ വെക്ടറിന്റെ നീളം വാക്കുകളുടെ വാക്ക്‌സഭയുടെ വലുപ്പത്തോട് പൊരുത്തപ്പെടുന്നു, അത് മുഴുവൻ AG News ഡാറ്റാസെറ്റിൽ നിന്നാണ് നിർമ്മിച്ചത്, എന്നാൽ Scikit Learn ഉദാഹരണത്തിൽ നാം സാമ്പിൾ ടെക്സ്റ്റിൽ നിന്നാണ് വാക്ക്‌സഭ സൃഷ്ടിച്ചത്.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## BoW ക്ലാസിഫയർ പരിശീലനം\n",
"\n",
"നമ്മൾ ടെക്സ്റ്റിന്റെ ബാഗ്-ഓഫ്-വേർഡ്സ് പ്രതിനിധാനം എങ്ങനെ നിർമ്മിക്കാമെന്ന് പഠിച്ചപ്പോൾ, അതുപയോഗിക്കുന്ന ഒരു ക്ലാസിഫയർ പരിശീലിപ്പിക്കാം. ആദ്യം, നമ്മുടെ ഡാറ്റാസെറ്റ് ബാഗ്-ഓഫ്-വേർഡ്സ് പ്രതിനിധാനമായി മാറ്റേണ്ടതുണ്ട്. ഇത് `map` ഫംഗ്ഷൻ ഉപയോഗിച്ച് താഴെ കാണുന്ന രീതിയിൽ സാധ്യമാക്കാം:\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": [
"ഇപ്പോൾ ഒരു ലീനിയർ ലെയർ അടങ്ങിയ ഒരു ലളിതമായ ക്ലാസിഫയർ ന്യൂറൽ നെറ്റ്‌വർക്ക് നിർവചിക്കാം. ഇൻപുട്ട് വലുപ്പം `vocab_size` ആണ്, ഔട്ട്പുട്ട് വലുപ്പം ക്ലാസുകളുടെ എണ്ണം (4) അനുസരിക്കുന്നു. നാം ഒരു ക്ലാസിഫിക്കേഷൻ ടാസ്‌ക് പരിഹരിക്കുന്നതിനാൽ, അവസാന ആക്ടിവേഷൻ ഫംഗ്ഷൻ **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": [
"നമുക്ക് 4 ക്ലാസുകൾ ഉള്ളതിനാൽ, 80% മുകളിൽ ഉള്ള കൃത്യത നല്ല ഫലം ആണ്.\n",
"\n",
"## ഒരു നെറ്റ്‌വർക്കായി ക്ലാസിഫയർ പരിശീലിപ്പിക്കൽ\n",
"\n",
"വെക്ടറൈസർ ഒരു Keras ലെയർ ആയതിനാൽ, അതിനെ ഉൾക്കൊള്ളുന്ന ഒരു നെറ്റ്‌വർക്ക് നിർവചിച്ച്, അതിനെ end-to-end ആയി പരിശീലിപ്പിക്കാം. ഇതിലൂടെ `map` ഉപയോഗിച്ച് ഡാറ്റാസെറ്റ് വെക്ടറൈസ് ചെയ്യേണ്ടതില്ല, നാം നേരിട്ട് ഒറിജിനൽ ഡാറ്റാസെറ്റ് നെറ്റ്‌വർക്കിന്റെ ഇൻപുട്ടിലേക്ക് നൽകാം.\n",
"\n",
"> **Note**: നമുക്ക് ഡാറ്റാസെറ്റിൽ നിന്ന് ഫീൽഡുകൾ (ഉദാഹരണത്തിന് `title`, `description`, `label`) ഡിക്ഷണറികളിൽ നിന്ന് ട്യൂപ്പിളുകളിലേക്ക് മാറ്റാൻ map പ്രയോഗിക്കേണ്ടി വരും. എന്നാൽ, ഡിസ്‌കിൽ നിന്ന് ഡാറ്റ ലോഡ് ചെയ്യുമ്പോൾ, ആവശ്യമായ ഘടനയുള്ള ഡാറ്റാസെറ്റ് ആദ്യം തന്നെ നിർമ്മിക്കാം.\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": [
"## ബിഗ്രാമുകൾ, ട്രൈഗ്രാമുകൾ, എൻ-ഗ്രാമുകൾ\n",
"\n",
"ബാഗ്-ഓഫ്-വേർഡ്സ് സമീപനത്തിന്റെ ഒരു പരിമിതിയാണ് ചില വാക്കുകൾ ബഹുവാക്ക് വ്യഞ്ജനങ്ങളുടെ ഭാഗമായിരിക്കുക. ഉദാഹരണത്തിന്, 'ഹോട്ട് ഡോഗ്' എന്ന വാക്കിന് 'ഹോട്ട്' എന്നും 'ഡോഗ്' എന്നും വേറിട്ട അർത്ഥമുണ്ട്. 'ഹോട്ട്' എന്നും 'ഡോഗ്' എന്നും വാക്കുകൾ എല്ലായ്പ്പോഴും ഒരേ വെക്ടറുകൾ ഉപയോഗിച്ച് പ്രതിനിധീകരിച്ചാൽ, നമ്മുടെ മോഡൽ ആശയക്കുഴപ്പം അനുഭവിക്കാം.\n",
"\n",
"ഇതിന് പരിഹാരമായി, **എൻ-ഗ്രാം പ്രതിനിധാനങ്ങൾ** ഡോക്യുമെന്റ് ക്ലാസിഫിക്കേഷനിലെ രീതികളിൽ സാധാരണയായി ഉപയോഗിക്കുന്നു, ഇവിടെ ഓരോ വാക്കിന്റെയും, ബൈ-വേർഡിന്റെയും, ട്രൈ-വേർഡിന്റെയും ആവൃത്തി ക്ലാസിഫയർ പരിശീലനത്തിന് ഉപകാരപ്രദമായ ഫീച്ചറാണ്. ഉദാഹരണത്തിന്, ബിഗ്രാം പ്രതിനിധാനങ്ങളിൽ, നാം യഥാർത്ഥ വാക്കുകൾക്കൊപ്പം എല്ലാ വാക്കു ജോഡികളും വാക്ക് സമാഹാരത്തിൽ ചേർക്കും.\n",
"\n",
"താഴെ Scikit Learn ഉപയോഗിച്ച് ബിഗ്രാം ബാഗ് ഓഫ് വേഡ് പ്രതിനിധാനം എങ്ങനെ സൃഷ്ടിക്കാമെന്ന് ഒരു ഉദാഹരണം കാണിക്കുന്നു:\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-ഗ്രാം സമീപനത്തിന്റെ പ്രധാന ദോഷം വാക്കുകളുടെ വലുപ്പം അതിവേഗം വളരാൻ തുടങ്ങുന്നതാണ്. പ്രായോഗികമായി, n-ഗ്രാം പ്രതിനിധാനം *എംബെഡ്ഡിംഗ്സ്* പോലുള്ള ഒരു ഡൈമെൻഷണാലിറ്റി കുറയ്ക്കൽ സാങ്കേതികവിദ്യയുമായി സംയോജിപ്പിക്കേണ്ടതുണ്ട്, ഇത് അടുത്ത യൂണിറ്റിൽ നാം ചർച്ച ചെയ്യും.\n",
"\n",
"നമ്മുടെ **AG News** ഡാറ്റാസെറ്റിൽ n-ഗ്രാം പ്രതിനിധാനം ഉപയോഗിക്കാൻ, `TextVectorization` കൺസ്ട്രക്ടറിലേക്ക് `ngrams` പാരാമീറ്റർ നൽകേണ്ടതാണ്. ബിഗ്രാം വാക്കുകളുടെ എണ്ണം **വളരെ കൂടുതലാണ്**, നമ്മുടെ കേസിൽ ഇത് 1.3 മില്യൺ ടോക്കണുകൾക്കുമപ്പുറം ആണ്! അതിനാൽ ബിഗ്രാം ടോക്കണുകളും ഒരു യുക്തിപരമായ പരിധിയിൽ പരിമിതപ്പെടുത്തുന്നത് ബുദ്ധിമുട്ടില്ല.\n",
"\n",
"മുകളിൽ നൽകിയ കോഡ് ഉപയോഗിച്ച് ക്ലാസിഫയർ പരിശീലിപ്പിക്കാമെങ്കിലും, അത് മെമ്മറി കാര്യക്ഷമമല്ല. അടുത്ത യൂണിറ്റിൽ, നാം എംബെഡ്ഡിംഗ്സ് ഉപയോഗിച്ച് ബിഗ്രാം ക്ലാസിഫയർ പരിശീലിപ്പിക്കും. അതുവരെ, ഈ നോട്ട്‌ബുക്കിൽ ബിഗ്രാം ക്ലാസിഫയർ പരിശീലനത്തിൽ പരീക്ഷണം നടത്തുകയും ഉയർന്ന കൃത്യത നേടാൻ കഴിയുമോ എന്ന് നോക്കുകയും ചെയ്യാം.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## സ്വയം ബോഡ് വെക്ടറുകൾ കണക്കാക്കൽ\n",
"\n",
"മുകളിൽ നൽകിയ ഉദാഹരണത്തിൽ, ഓരോ വാക്കിന്റെയും വൺ-ഹോട്ട് എൻകോഡിങ്ങുകൾ കൂട്ടിച്ചേർത്ത് ബോഡ് വെക്ടറുകൾ കൈയോടെ കണക്കാക്കിയിരുന്നു. എന്നാൽ, TensorFlow-ന്റെ ഏറ്റവും പുതിയ പതിപ്പ്, വക്ടറൈസർ കൺസ്ട്രക്ടറിലേക്ക് `output_mode='count'` പാരാമീറ്റർ നൽകുന്നതിലൂടെ ബോഡ് വെക്ടറുകൾ സ്വയം കണക്കാക്കാൻ അനുവദിക്കുന്നു. ഇത് നമ്മുടെ മോഡൽ നിർവചിക്കുകയും പരിശീലിപ്പിക്കുകയും ചെയ്യുന്നത് വളരെ എളുപ്പമാക്കുന്നു:\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** എന്നത് **ടെർമ് ഫ്രീക്വൻസി - ഇൻവേഴ്സ് ഡോക്യുമെന്റ് ഫ്രീക്വൻസി** എന്നർത്ഥം വരുന്ന ഒരു രീതിയാണ്. ഇത് ബാഗ്-ഓഫ്-വേർഡ്സിന്റെ ഒരു വ്യത്യാസമാണ്, ഇവിടെ ഒരു ഡോക്യുമെന്റിൽ ഒരു വാക്ക് ഉണ്ടെന്നത് സൂചിപ്പിക്കുന്ന 0/1 ബൈനറി മൂല്യത്തിന് പകരം, കോർപ്പസിൽ വാക്കിന്റെ ആവർത്തനത്തിന്റെ അടിസ്ഥാനത്തിൽ ഒരു ഫ്ലോട്ടിംഗ്-പോയിന്റ് മൂല്യം ഉപയോഗിക്കുന്നു.\n",
"\n",
"കൂടുതൽ ഔപചാരികമായി, ഒരു ഡോക്യുമെന്റ് $j$-ൽ വാക്ക് $i$-യുടെ ഭാരം $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": 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` ലെയർ `output_mode='tf-idf'` പാരാമീറ്റർ നൽകുന്നതിലൂടെ സ്വയം TF-IDF ഫ്രീക്വൻസികൾ കണക്കാക്കാൻ കഴിയും. TF-IDF ഉപയോഗിക്കുന്നത് കൃത്യത വർദ്ധിപ്പിക്കുന്നുണ്ടോ എന്ന് പരിശോധിക്കാൻ മുകളിൽ ഉപയോഗിച്ച കോഡ് വീണ്ടും ആവർത്തിക്കാം:\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 പ്രതിനിധാനങ്ങൾ വ്യത്യസ്ത വാക്കുകൾക്ക് ആവൃത്തി ഭാരങ്ങൾ നൽകുന്നുവെങ്കിലും, അവ അർത്ഥം അല്ലെങ്കിൽ ക്രമം പ്രതിനിധാനം ചെയ്യാൻ കഴിയുന്നില്ല. പ്രശസ്ത ഭാഷാശാസ്ത്രജ്ഞൻ 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": "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-11-26T01:40:32+00:00",
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
"language_code": "ml"
}
},
"nbformat": 4,
"nbformat_minor": 4
}