647 lines
32 KiB
Plaintext
647 lines
32 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# متن کی درجہ بندی کا کام\n",
|
||
"\n",
|
||
"اس ماڈیول میں، ہم ایک سادہ متن کی درجہ بندی کے کام سے آغاز کریں گے جو **[AG_NEWS](http://www.di.unipi.it/~gulli/AG_corpus_of_news_articles.html)** ڈیٹا سیٹ پر مبنی ہے: ہم خبری سرخیوں کو چار زمروں میں تقسیم کریں گے: دنیا، کھیل، کاروبار اور سائنس/ٹیک۔\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 سے زیادہ الفاظ۔ عام طور پر، ہمیں ان الفاظ کی ضرورت نہیں ہوتی جو متن میں شاذ و نادر ہی موجود ہوں — صرف چند جملے ان میں ہوں گے، اور ماڈل ان سے کچھ نہیں سیکھے گا۔ لہذا، لغت کے سائز کو ایک چھوٹے نمبر تک محدود کرنا سمجھ میں آتا ہے، جو ویکٹرائزر کنسٹرکٹر کو ایک دلیل دے کر کیا جا سکتا ہے:\n",
|
||
"\n",
|
||
"یہ دونوں مراحل **TextVectorization** لیئر کے ذریعے انجام دیے جا سکتے ہیں۔ آئیے ویکٹرائزر آبجیکٹ کو انسٹیٹیوٹ کریں، اور پھر `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",
|
||
"چونکہ الفاظ معنی کی نمائندگی کرتے ہیں، بعض اوقات ہم کسی متن کے معنی صرف انفرادی الفاظ کو دیکھ کر سمجھ سکتے ہیں، چاہے وہ جملے میں کس ترتیب میں ہوں۔ مثال کے طور پر، خبروں کی درجہ بندی کرتے وقت، الفاظ جیسے *موسم* اور *برف* ممکنہ طور پر *موسمی پیش گوئی* کی طرف اشارہ کریں گے، جبکہ الفاظ جیسے *اسٹاکس* اور *ڈالر* *مالی خبروں* کی طرف شمار ہوں گے۔\n",
|
||
"\n",
|
||
"**الفاظ کے تھیلے** (BoW) ویکٹر کی نمائندگی سب سے آسان اور روایتی ویکٹر کی نمائندگی ہے۔ ہر لفظ کو ایک ویکٹر انڈیکس سے جوڑا جاتا ہے، اور ویکٹر عنصر کسی دیے گئے دستاویز میں ہر لفظ کے وقوعات کی تعداد کو ظاہر کرتا ہے۔\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"> **نوٹ**: آپ 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": [
|
||
"> **نوٹ**: آپ کو حیرت ہو سکتی ہے کہ نتیجہ پچھلی مثال سے مختلف ہے۔ اس کی وجہ یہ ہے کہ 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 لیئر ہے، ہم ایک ایسا نیٹ ورک ڈیفائن کر سکتے ہیں جو اسے شامل کرے، اور اسے اینڈ ٹو اینڈ تربیت دے۔ اس طریقے سے ہمیں ڈیٹا سیٹ کو `map` استعمال کرتے ہوئے ویکٹرائز کرنے کی ضرورت نہیں ہوگی، ہم نیٹ ورک کے ان پٹ پر اصل ڈیٹا سیٹ کو ہی پاس کر سکتے ہیں۔\n",
|
||
"\n",
|
||
"> **نوٹ**: ہمیں پھر بھی اپنے ڈیٹا سیٹ پر `map` لاگو کرنا ہوگا تاکہ ڈکشنریوں (جیسے `title`, `description` اور `label`) سے فیلڈز کو ٹپلز میں تبدیل کیا جا سکے۔ تاہم، جب ہم ڈسک سے ڈیٹا لوڈ کر رہے ہوں، تو ہم شروع میں ہی مطلوبہ ساخت کے ساتھ ایک ڈیٹا سیٹ بنا سکتے ہیں۔\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-gram طریقہ کار کا سب سے بڑا نقصان یہ ہے کہ الفاظ کے ذخیرے کا حجم بہت تیزی سے بڑھنے لگتا ہے۔ عملی طور پر، ہمیں n-gram نمائندگی کو ایک جہتی کمی کی تکنیک کے ساتھ جوڑنے کی ضرورت ہوتی ہے، جیسے *embeddings*، جس پر ہم اگلے یونٹ میں بات کریں گے۔\n",
|
||
"\n",
|
||
"**AG News** ڈیٹا سیٹ میں n-gram نمائندگی استعمال کرنے کے لیے، ہمیں `ngrams` پیرامیٹر کو اپنے `TextVectorization` کنسٹرکٹر میں پاس کرنا ہوگا۔ bigram ذخیرے کی لمبائی **نمایاں طور پر بڑی** ہوتی ہے، ہمارے کیس میں یہ 1.3 ملین سے زیادہ ٹوکنز ہیں! لہذا، یہ مناسب ہوگا کہ bigram ٹوکنز کو بھی کسی معقول حد تک محدود کیا جائے۔\n",
|
||
"\n",
|
||
"ہم اوپر دیے گئے کوڈ کو استعمال کر کے classifier کو ٹرین کر سکتے ہیں، لیکن یہ میموری کے لحاظ سے بہت غیر مؤثر ہوگا۔ اگلے یونٹ میں، ہم embeddings کا استعمال کرتے ہوئے bigram classifier کو ٹرین کریں گے۔ اس دوران، آپ اس نوٹ بک میں bigram classifier کی ٹریننگ کے ساتھ تجربہ کر سکتے ہیں اور دیکھ سکتے ہیں کہ آیا آپ زیادہ درستگی حاصل کر سکتے ہیں۔\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## خودکار طریقے سے BoW ویکٹرز کا حساب لگانا\n",
|
||
"\n",
|
||
"اوپر دیے گئے مثال میں، ہم نے انفرادی الفاظ کے ون-ہاٹ انکوڈنگز کو جمع کر کے BoW ویکٹرز کا حساب دستی طور پر لگایا۔ تاہم، TensorFlow کے جدید ترین ورژن میں ہمیں BoW ویکٹرز خودکار طریقے سے حساب کرنے کی سہولت ملتی ہے، صرف `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** کا مطلب ہے **اصطلاح کی فریکوئنسی - معکوس دستاویز فریکوئنسی**۔ یہ bag-of-words کی ایک قسم ہے، جہاں کسی دستاویز میں کسی لفظ کی موجودگی کو ظاہر کرنے کے لیے بائنری 0/1 ویلیو کے بجائے ایک فلوٹنگ پوائنٹ ویلیو استعمال کی جاتی ہے، جو کارپس میں لفظ کی موجودگی کی فریکوئنسی سے متعلق ہوتی ہے۔\n",
|
||
"\n",
|
||
"زیادہ رسمی طور پر، کسی لفظ $i$ کا وزن $w_{ij}$ کسی دستاویز $j$ میں یوں بیان کیا جاتا ہے:\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": [
|
||
"کیرس میں، `TextVectorization` لیئر خودکار طور پر TF-IDF فریکوئنسیز کا حساب لگا سکتی ہے جب `output_mode='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 نمائندگی مختلف الفاظ کو تعدد کے وزن فراہم کرتی ہے، لیکن یہ معنی یا ترتیب کو ظاہر کرنے سے قاصر ہے۔ جیسا کہ مشہور لسانیات دان جے آر فرث نے 1935 میں کہا تھا، \"کسی لفظ کا مکمل مطلب ہمیشہ سیاق و سباق پر مبنی ہوتا ہے، اور سیاق و سباق کے بغیر معنی کا کوئی مطالعہ سنجیدگی سے نہیں لیا جا سکتا۔\" ہم اس کورس میں آگے چل کر زبان ماڈلنگ کے ذریعے متن سے سیاق و سباق کی معلومات حاصل کرنے کا طریقہ سیکھیں گے۔\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-28T04:39:21+00:00",
|
||
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
|
||
"language_code": "ur"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
} |