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

647 lines
39 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"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": [
"हाम्रो डाटासेटबाट पहिलो १० नयाँ शीर्षकहरू प्रिन्ट गरौं:\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 डेटासेटको उदाहरणमा, शब्दकोशको आकार धेरै ठूलो छ, १k भन्दा बढी शब्दहरू। सामान्यतया, हामीलाई पाठमा कम उपस्थित हुने शब्दहरूको आवश्यकता हुँदैन — केवल केही वाक्यहरूमा मात्र ती शब्दहरू हुनेछन्, र मोडेलले तीबाट सिक्ने छैन। त्यसैले, शब्दकोशको आकारलाई सानो संख्यामा सीमित गर्नु उपयुक्त हुन्छ, जसका लागि भेक्टराइजर कन्स्ट्रक्टरमा एउटा आर्गुमेन्ट पास गर्न सकिन्छ:\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": [
"## शब्दहरूको झोला (Bag-of-words) पाठ प्रतिनिधित्व\n",
"\n",
"किनभने शब्दहरूले अर्थ व्यक्त गर्छन्, कहिलेकाहीं हामी वाक्यको क्रमको पर्वाह नगरी व्यक्तिगत शब्दहरू हेरेर पाठको अर्थ पत्ता लगाउन सक्छौं। उदाहरणका लागि, समाचार वर्गीकरण गर्दा, *मौसम* र *हिउँ* जस्ता शब्दहरूले *मौसम पूर्वानुमान* संकेत गर्न सक्छन्, जबकि *स्टक* र *डलर* जस्ता शब्दहरूले *आर्थिक समाचार* तर्फ गणना गर्न सक्छन्।\n",
"\n",
"**शब्दहरूको झोला** (BoW) भेक्टर प्रतिनिधित्व परम्परागत भेक्टर प्रतिनिधित्वहरू मध्ये सबैभन्दा सरल र बुझ्न सजिलो हो। प्रत्येक शब्दलाई भेक्टरको सूचकसँग जोडिन्छ, र भेक्टरको तत्वले कुनै पनि दस्तावेजमा प्रत्येक शब्दको उपस्थितिको संख्या समावेश गर्दछ।\n",
"\n",
"![शब्दहरूको झोला भेक्टर प्रतिनिधित्व मेमोरीमा कसरी प्रतिनिधित्व गरिन्छ भन्ने देखाउने चित्र।](../../../../../translated_images/ne/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": [
"हामीले माथि परिभाषित गरेको Keras vectorizer पनि प्रयोग गर्न सक्छौं, प्रत्येक शब्द संख्या एक-हट एन्कोडिङमा परिवर्तन गरेर ती सबै भेक्टरहरूलाई जोड्न:\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": [
"चूँकि हामीसँग ४ वटा वर्गहरू छन्, ८०% भन्दा माथिको शुद्धता राम्रो नतिजा हो।\n",
"\n",
"## एक नेटवर्कको रूपमा वर्गीकरणकर्ता प्रशिक्षण गर्ने\n",
"\n",
"किनभने भेक्टराइजर पनि Keras लेयर हो, हामी यसलाई समावेश गर्ने नेटवर्क परिभाषित गर्न सक्छौं र यसलाई अन्त-देखि-अन्तसम्म प्रशिक्षण गर्न सक्छौं। यसरी हामीले `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",
"तल स्काइ-किट लर्न प्रयोग गरेर बाइग्राम ब्याग-अफ-वर्ड्स प्रतिनिधित्व कसरी निर्माण गर्ने भन्ने उदाहरण छ:\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 प्रतिनिधित्व प्रयोग गर्न, हामीले `TextVectorization` कन्स्ट्रक्टरमा `ngrams` प्यारामिटर पास गर्नुपर्छ। बिग्राम शब्दकोशको लम्बाइ **धेरै ठूलो** हुन्छ, हाम्रो केसमा यो १.३ मिलियनभन्दा बढी टोकनहरू हुन्छ! त्यसैले, बिग्राम टोकनहरूलाई पनि कुनै उपयुक्त सीमामा सीमित गर्नु उचित हुन्छ।\n",
"\n",
"हामीले माथिको जस्तै कोड प्रयोग गरेर क्लासिफायरलाई प्रशिक्षण दिन सक्थ्यौं, तर यो धेरै मेमोरी-अक्षम हुने थियो। अर्को इकाईमा, हामी embeddings प्रयोग गरेर बिग्राम क्लासिफायरलाई प्रशिक्षण दिनेछौं। यसैबीच, तपाईं यस नोटबुकमा बिग्राम क्लासिफायर प्रशिक्षणसँग प्रयोग गर्न सक्नुहुन्छ र उच्च सटीकता प्राप्त गर्न सकिन्छ कि भनेर हेर्न सक्नुहुन्छ।\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## BoW भेक्टरहरू स्वचालित रूपमा गणना गर्ने\n",
"\n",
"माथिको उदाहरणमा, हामीले व्यक्तिगत शब्दहरूको वन-हट इनकोडिङहरूलाई जोडेर BoW भेक्टरहरू हातले गणना गरेका थियौं। तर, TensorFlow को पछिल्लो संस्करणले `output_mode='count` प्यारामिटरलाई भेक्टराइजर कन्स्ट्रक्टरमा पास गरेर BoW भेक्टरहरू स्वचालित रूपमा गणना गर्न अनुमति दिन्छ। यसले हाम्रो मोडेल परिभाषित गर्न र प्रशिक्षण गर्न निकै सजिलो बनाउँछ:\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training vectorizer\n",
"938/938 [==============================] - 7s 7ms/step - loss: 0.5929 - acc: 0.8486 - val_loss: 0.4168 - val_acc: 0.8772\n"
]
},
{
"data": {
"text/plain": [
"<keras.callbacks.History at 0x20c725217c0>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model = keras.models.Sequential([\n",
" keras.layers.experimental.preprocessing.TextVectorization(max_tokens=vocab_size,output_mode='count'),\n",
" keras.layers.Dense(4,input_shape=(vocab_size,), activation='softmax')\n",
"])\n",
"print(\"Training vectorizer\")\n",
"model.layers[0].adapt(ds_train.take(500).map(extract_text))\n",
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## टर्म फ्रिक्वेन्सी - इनभर्स डकुमेन्ट फ्रिक्वेन्सी (TF-IDF)\n",
"\n",
"BoW प्रतिनिधित्वमा, शब्दको उपस्थितिलाई एउटै प्रविधि प्रयोग गरेर तौल दिइन्छ, चाहे शब्द जे भए पनि। तर, यो स्पष्ट छ कि *a* र *in* जस्ता बारम्बार प्रयोग हुने शब्दहरू वर्गीकरणका लागि विशेष शब्दहरू भन्दा कम महत्त्वपूर्ण हुन्छन्। धेरैजसो NLP कार्यहरूमा केही शब्दहरू अरूभन्दा बढी सान्दर्भिक हुन्छन्।\n",
"\n",
"**TF-IDF** को अर्थ **टर्म फ्रिक्वेन्सी - इनभर्स डकुमेन्ट फ्रिक्वेन्सी** हो। यो 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": 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 प्रतिनिधित्वहरूले विभिन्न शब्दहरूलाई आवृत्ति तौल प्रदान गर्छन्, तिनीहरूले अर्थ वा क्रमलाई प्रतिनिधित्व गर्न सक्दैनन्। प्रसिद्ध भाषाविद् जे. आर. फर्थले १९३५ मा भनेका थिए, \"शब्दको पूर्ण अर्थ सधैं सन्दर्भात्मक हुन्छ, र सन्दर्भबाहेकको अर्थको कुनै पनि अध्ययनलाई गम्भीरतापूर्वक लिन सकिँदैन।\" हामी पाठबाट सन्दर्भात्मक जानकारी कसरी समात्ने भन्ने कुरा यस पाठ्यक्रममा पछि भाषा मोडलिङ प्रयोग गरेर सिक्नेछौं।\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-28T09:55:06+00:00",
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
"language_code": "ne"
}
},
"nbformat": 4,
"nbformat_minor": 4
}