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

647 lines
26 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Úloha klasifikácie textu\n",
"\n",
"V tomto module začneme jednoduchou úlohou klasifikácie textu založenou na dátovej sade **[AG_NEWS](http://www.di.unipi.it/~gulli/AG_corpus_of_news_articles.html)**: budeme klasifikovať nadpisy správ do jednej zo 4 kategórií: Svet, Šport, Biznis a Veda/Technológie.\n",
"\n",
"## Dátová sada\n",
"\n",
"Na načítanie dátovej sady použijeme API **[TensorFlow Datasets](https://www.tensorflow.org/datasets)**.\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": [
"Teraz môžeme pristupovať k tréningovej a testovacej časti dátovej sady pomocou `dataset['train']` a `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": [
"Poďme vytlačiť prvých 10 nových titulkov z nášho datasetu:\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": [
"## Vektorizácia textu\n",
"\n",
"Teraz musíme previesť text na **čísla**, ktoré môžu byť reprezentované ako tenzory. Ak chceme reprezentáciu na úrovni slov, musíme urobiť dve veci:\n",
"\n",
"* Použiť **tokenizér** na rozdelenie textu na **tokeny**.\n",
"* Vytvoriť **slovník** týchto tokenov.\n",
"\n",
"### Obmedzenie veľkosti slovníka\n",
"\n",
"V príklade s datasetom AG News je veľkosť slovníka pomerne veľká, viac ako 100 tisíc slov. Vo všeobecnosti nepotrebujeme slová, ktoré sa v texte vyskytujú zriedkavo — len niekoľko viet ich bude obsahovať, a model sa z nich nenaučí. Preto má zmysel obmedziť veľkosť slovníka na menší počet tým, že odovzdáme argument konštruktoru vektorizéra:\n",
"\n",
"Obe tieto kroky je možné zvládnuť pomocou vrstvy **TextVectorization**. Poďme vytvoriť objekt vektorizéra a potom zavolať metódu `adapt`, aby sme prešli všetok text a vytvorili slovník:\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": [
"> **Poznámka**: Používame iba podmnožinu celého datasetu na vytvorenie slovníka. Robíme to preto, aby sme urýchlili čas vykonávania a nemuseli ste dlho čakať. Avšak, týmto podstupujeme riziko, že niektoré slová z celého datasetu nebudú zahrnuté do slovníka a budú ignorované počas tréningu. Použitie celej veľkosti slovníka a prebehnutie celého datasetu počas `adapt` by malo zvýšiť konečnú presnosť, ale nie výrazne.\n",
"\n",
"Teraz môžeme pristúpiť k samotnému slovníku:\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": [
"Pomocou vektorizátora môžeme ľahko zakódovať akýkoľvek text do množiny čísel:\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": [
"## Reprezentácia textu pomocou metódy Bag-of-words\n",
"\n",
"Keďže slová nesú význam, niekedy dokážeme pochopiť význam textu len na základe jednotlivých slov, bez ohľadu na ich poradie vo vete. Napríklad pri klasifikácii správ môžu slová ako *počasie* a *sneh* naznačovať *predpoveď počasia*, zatiaľ čo slová ako *akcie* a *dolár* by mohli poukazovať na *finančné správy*.\n",
"\n",
"**Bag-of-words** (BoW) je najjednoduchšia tradičná metóda reprezentácie textu pomocou vektorov. Každé slovo je priradené k indexu vektora a prvok vektora obsahuje počet výskytov daného slova v konkrétnom dokumente.\n",
"\n",
"![Obrázok znázorňujúci, ako je reprezentácia Bag-of-words uložená v pamäti.](../../../../../translated_images/sk/bag-of-words-example.606fc1738f1d7ba9.webp) \n",
"\n",
"> **Note**: Na metódu BoW sa môžete pozerať aj ako na súčet všetkých vektorov s jedným aktívnym prvkom (one-hot-encoded) pre jednotlivé slová v texte.\n",
"\n",
"Nižšie je uvedený príklad, ako vytvoriť reprezentáciu Bag-of-words pomocou knižnice Scikit Learn v jazyku Python:\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": [
"Môžeme tiež použiť Keras vektorizátor, ktorý sme definovali vyššie, previesť každé číslo slova na one-hot kódovanie a všetky tieto vektory sčítať:\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": [
"> **Poznámka**: Môže vás prekvapiť, že výsledok sa líši od predchádzajúceho príkladu. Dôvodom je, že v príklade s Kerasom dĺžka vektora zodpovedá veľkosti slovníka, ktorý bol vytvorený z celého datasetu AG News, zatiaľ čo v príklade so Scikit Learn sme slovník vytvorili na základe ukážkového textu za pochodu.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Trénovanie klasifikátora BoW\n",
"\n",
"Teraz, keď sme sa naučili, ako vytvoriť reprezentáciu textu pomocou metódy bag-of-words, poďme natrénovať klasifikátor, ktorý ju využíva. Najskôr musíme náš dataset previesť na reprezentáciu bag-of-words. To môžeme dosiahnuť použitím funkcie `map` nasledovným spôsobom:\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": [
"Teraz definujme jednoduchú klasifikačnú neurónovú sieť, ktorá obsahuje jednu lineárnu vrstvu. Veľkosť vstupu je `vocab_size` a veľkosť výstupu zodpovedá počtu tried (4). Keďže riešime klasifikačnú úlohu, konečná aktivačná funkcia je **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": [
"Keďže máme 4 triedy, presnosť nad 80 % je dobrý výsledok.\n",
"\n",
"## Trénovanie klasifikátora ako jednej siete\n",
"\n",
"Keďže vektorizér je tiež vrstva Keras, môžeme definovať sieť, ktorá ho zahŕňa, a trénovať ju od začiatku do konca. Týmto spôsobom nemusíme vektorizovať dataset pomocou `map`, stačí nám pôvodný dataset poslať na vstup siete.\n",
"\n",
"> **Poznámka**: Stále by sme museli aplikovať mapy na náš dataset, aby sme konvertovali polia zo slovníkov (ako `title`, `description` a `label`) na dvojice. Avšak pri načítavaní dát z disku môžeme hneď na začiatku vytvoriť dataset s požadovanou štruktúrou.\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": [
"## Bigramy, trigramy a n-gramy\n",
"\n",
"Jedným z obmedzení prístupu bag-of-words je, že niektoré slová sú súčasťou viacslovných výrazov. Napríklad slovo 'hot dog' má úplne iný význam ako slová 'hot' a 'dog' v iných kontextoch. Ak by sme slová 'hot' a 'dog' vždy reprezentovali rovnakými vektormi, mohlo by to zmiasť náš model.\n",
"\n",
"Na riešenie tohto problému sa často používajú **n-gramové reprezentácie** v metódach klasifikácie dokumentov, kde frekvencia každého slova, dvojslovného alebo trojslovného výrazu predstavuje užitočný prvok na trénovanie klasifikátorov. Napríklad v bigramových reprezentáciách pridáme do slovníka všetky dvojice slov, okrem pôvodných slov.\n",
"\n",
"Nižšie je uvedený príklad, ako generovať bigramovú reprezentáciu bag-of-words pomocou 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": [
"Hlavnou nevýhodou prístupu n-gramov je, že veľkosť slovníka začne rásť extrémne rýchlo. V praxi je potrebné skombinovať reprezentáciu n-gramov s technikou redukcie dimenzií, ako sú *embeddingy*, o ktorých budeme hovoriť v ďalšej jednotke.\n",
"\n",
"Aby sme mohli použiť reprezentáciu n-gramov v našej **AG News** množine údajov, musíme parameter `ngrams` odovzdať do nášho konštruktora `TextVectorization`. Dĺžka bigramového slovníka je **výrazne väčšia**, v našom prípade ide o viac ako 1,3 milióna tokenov! Preto má zmysel obmedziť aj bigramové tokeny na nejaký rozumný počet.\n",
"\n",
"Mohli by sme použiť rovnaký kód ako vyššie na trénovanie klasifikátora, avšak bolo by to veľmi neefektívne z hľadiska pamäte. V ďalšej jednotke budeme trénovať bigramový klasifikátor pomocou embeddingov. Medzitým môžete experimentovať s trénovaním bigramového klasifikátora v tomto notebooku a zistiť, či dokážete dosiahnuť vyššiu presnosť.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Automatický výpočet BoW vektorov\n",
"\n",
"V príklade vyššie sme BoW vektory počítali ručne sčítaním one-hot kódovaní jednotlivých slov. Avšak, najnovšia verzia TensorFlow nám umožňuje vypočítať BoW vektory automaticky, a to pridaním parametra `output_mode='count'` do konštruktora vektorizéra. Týmto spôsobom je definovanie a trénovanie nášho modelu výrazne jednoduchšie:\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": [
"## Frekvencia termínov - inverzná frekvencia dokumentov (TF-IDF)\n",
"\n",
"V reprezentácii BoW sa výskyty slov vážia rovnakou technikou bez ohľadu na samotné slovo. Je však zrejmé, že časté slová ako *a* a *v* sú oveľa menej dôležité pre klasifikáciu než špecializované výrazy. Pri väčšine úloh NLP sú niektoré slová relevantnejšie než iné.\n",
"\n",
"**TF-IDF** znamená **frekvencia termínov - inverzná frekvencia dokumentov**. Ide o variáciu metódy bag-of-words, kde namiesto binárnej hodnoty 0/1, ktorá označuje prítomnosť slova v dokumente, sa používa hodnota s pohyblivou desatinnou čiarkou, ktorá súvisí s frekvenciou výskytu slova v korpuse.\n",
"\n",
"Formálne je váha $w_{ij}$ slova $i$ v dokumente $j$ definovaná ako:\n",
"$$\n",
"w_{ij} = tf_{ij}\\times\\log({N\\over df_i})\n",
"$$\n",
"kde\n",
"* $tf_{ij}$ je počet výskytov $i$ v $j$, teda hodnota BoW, ktorú sme videli predtým\n",
"* $N$ je počet dokumentov v kolekcii\n",
"* $df_i$ je počet dokumentov obsahujúcich slovo $i$ v celej kolekcii\n",
"\n",
"Hodnota TF-IDF $w_{ij}$ rastie úmerne počtu výskytov slova v dokumente a je upravená počtom dokumentov v korpuse, ktoré obsahujú dané slovo, čo pomáha zohľadniť fakt, že niektoré slová sa vyskytujú častejšie než iné. Napríklad, ak sa slovo vyskytuje *v každom* dokumente kolekcie, $df_i=N$, a $w_{ij}=0$, a tieto výrazy by boli úplne ignorované.\n",
"\n",
"TF-IDF vektorizáciu textu môžete jednoducho vytvoriť pomocou Scikit Learn:\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": [
"V Keras môže vrstva `TextVectorization` automaticky vypočítať TF-IDF frekvencie pridaním parametra `output_mode='tf-idf'`. Poďme zopakovať kód, ktorý sme použili vyššie, aby sme zistili, či použitie TF-IDF zvyšuje presnosť:\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": [
"## Záver\n",
"\n",
"Aj keď reprezentácie TF-IDF poskytujú váhové hodnoty pre rôzne slová na základe ich frekvencie, nedokážu zachytiť význam alebo poradie. Ako povedal známy lingvista J. R. Firth v roku 1935: „Úplný význam slova je vždy kontextový a žiadna štúdia významu mimo kontextu nemôže byť braná vážne.“ Neskôr v kurze sa naučíme, ako zachytiť kontextové informácie z textu pomocou jazykového modelovania.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby na automatický preklad [Co-op Translator](https://github.com/Azure/co-op-translator). Hoci sa snažíme o presnosť, upozorňujeme, že automatické preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho pôvodnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre dôležité informácie odporúčame profesionálny ľudský preklad. Nezodpovedáme za akékoľvek nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\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-30T01:14:52+00:00",
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 4
}