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

647 lines
26 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Úkol klasifikace textu\n",
"\n",
"V tomto modulu začneme jednoduchým úkolem klasifikace textu na základě datasetu **[AG_NEWS](http://www.di.unipi.it/~gulli/AG_corpus_of_news_articles.html)**: budeme klasifikovat nadpisy zpráv do jedné ze 4 kategorií: Svět, Sport, Byznys a Věda/Technika.\n",
"\n",
"## Dataset\n",
"\n",
"Pro načtení datasetu 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": [
"Nyní můžeme přistupovat k trénovací a testovací části datové sady pomocí `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": [
"Pojďme vytisknout prvních 10 nových titulků z našeho datového souboru:\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": [
"## Vektorizace textu\n",
"\n",
"Nyní potřebujeme převést text na **čísla**, která mohou být reprezentována jako tensory. Pokud chceme reprezentaci na úrovni slov, musíme udělat dvě věci:\n",
"\n",
"* Použít **tokenizér** k rozdělení textu na **tokeny**.\n",
"* Vytvořit **slovník** těchto tokenů.\n",
"\n",
"### Omezení velikosti slovníku\n",
"\n",
"V příkladu s datasetem AG News je velikost slovníku poměrně velká, více než 100 tisíc slov. Obecně řečeno, nepotřebujeme slova, která se v textu vyskytují jen zřídka — pouze několik vět je bude obsahovat a model se z nich nic nenaučí. Proto má smysl omezit velikost slovníku na menší počet tím, že předáme argument konstruktoru vektorizéru:\n",
"\n",
"Oba tyto kroky lze zvládnout pomocí vrstvy **TextVectorization**. Pojďme vytvořit objekt vektorizéru a poté zavolat metodu `adapt`, která projde veškerý text a vytvoří 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žíváme pouze podmnožinu celého datasetu k vytvoření slovníku. Děláme to proto, abychom zrychlili dobu zpracování a nemuseli jste dlouho čekat. Tím však podstupujeme riziko, že některá slova z celého datasetu nebudou zahrnuta do slovníku a budou během trénování ignorována. Použití celé velikosti slovníku a zpracování celého datasetu během `adapt` by mělo zvýšit konečnou přesnost, ale ne výrazně.\n",
"\n",
"Nyní můžeme přistoupit 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": [
"Pomocí vektorizéru můžeme snadno zakódovat jakýkoli text do sady čí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": [
"## Reprezentace textu pomocí Bag-of-words\n",
"\n",
"Protože slova nesou význam, někdy můžeme pochopit smysl textu jen tím, že se podíváme na jednotlivá slova, bez ohledu na jejich pořadí ve větě. Například při klasifikaci zpráv slova jako *počasí* a *sníh* pravděpodobně naznačují *předpověď počasí*, zatímco slova jako *akcie* a *dolar* by spíše ukazovala na *finanční zprávy*.\n",
"\n",
"Reprezentace vektoru **Bag-of-words** (BoW) je nejjednodušší tradiční vektorová reprezentace na pochopení. Každé slovo je spojeno s indexem vektoru a prvek vektoru obsahuje počet výskytů každého slova v daném dokumentu.\n",
"\n",
"![Obrázek ukazující, jak je reprezentace Bag-of-words uložena v paměti.](../../../../../translated_images/cs/bag-of-words-example.606fc1738f1d7ba9.webp) \n",
"\n",
"> **Note**: Na BoW můžete také nahlížet jako na součet všech one-hot-encoded vektorů pro jednotlivá slova v textu.\n",
"\n",
"Níže je uveden příklad, jak vytvořit reprezentaci Bag-of-words pomocí python knihovny 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": [
"Můžeme také použít Keras vektorizér, který jsme definovali výše, převést každé číslo slova na one-hot kódování a všechny tyto vektory sečíst:\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 překvapit, že výsledek se liší od předchozího příkladu. Důvodem je, že v příkladu s Kerasem délka vektoru odpovídá velikosti slovníku, který byl vytvořen z celého datasetu AG News, zatímco v příkladu se Scikit Learn jsme slovník vytvořili z ukázkového textu za běhu.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Trénování klasifikátoru BoW\n",
"\n",
"Nyní, když jsme se naučili, jak vytvořit reprezentaci textu pomocí \"bag-of-words\" (BoW), pojďme natrénovat klasifikátor, který ji využívá. Nejprve musíme převést náš dataset na reprezentaci \"bag-of-words\". Toho lze dosáhnout použitím funkce `map` následujícím způsobem:\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": [
"Nyní definujme jednoduchou klasifikační neuronovou síť, která obsahuje jednu lineární vrstvu. Velikost vstupu je `vocab_size` a velikost výstupu odpovídá počtu tříd (4). Protože řešíme klasifikační úlohu, konečná aktivační funkce 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": [
"Vzhledem k tomu, že máme 4 třídy, přesnost nad 80 % je dobrý výsledek.\n",
"\n",
"## Trénování klasifikátoru jako jedné sítě\n",
"\n",
"Protože je vektorizér také vrstvou Keras, můžeme definovat síť, která ho zahrnuje, a trénovat ji od začátku do konce. Tímto způsobem není potřeba vektorizovat dataset pomocí `map`, stačí předat původní dataset jako vstup do sítě.\n",
"\n",
"> **Note**: Stále bychom museli aplikovat mapy na náš dataset, abychom převedli pole ze slovníků (jako `title`, `description` a `label`) na dvojice. Nicméně při načítání dat z disku můžeme dataset rovnou vytvořit ve požadované struktuře.\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 omezení přístupu bag-of-words je, že některá slova jsou součástí víceslovných výrazů. Například slovo „hot dog“ má úplně jiný význam než slova „hot“ a „dog“ v jiných kontextech. Pokud bychom slova „hot“ a „dog“ vždy reprezentovali stejnými vektory, mohlo by to náš model zmást.\n",
"\n",
"Abychom tento problém vyřešili, často se v metodách klasifikace dokumentů používají **reprezentace n-gramů**, kde je frekvence každého slova, dvojice slov nebo trojice slov užitečnou vlastností pro trénování klasifikátorů. Například v bigramových reprezentacích přidáme do slovníku všechny dvojice slov, kromě původních slov.\n",
"\n",
"Níže je uveden příklad, jak vytvořit bigramovou reprezentaci bag-of-words pomocí 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": [
"Hlavní nevýhodou přístupu n-gramů je, že velikost slovníku začíná růst extrémně rychle. V praxi je potřeba kombinovat reprezentaci n-gramů s technikou redukce dimenzionality, jako jsou *embeddingy*, o kterých budeme diskutovat v další jednotce.\n",
"\n",
"Abychom použili reprezentaci n-gramů v našem datasetu **AG News**, musíme předat parametr `ngrams` do našeho konstruktoru `TextVectorization`. Délka slovníku bigramů je **výrazně větší**, v našem případě je to více než 1,3 milionu tokenů! Proto má smysl omezit počet bigramových tokenů na nějaké rozumné číslo.\n",
"\n",
"Mohli bychom použít stejný kód jako výše k trénování klasifikátoru, ale bylo by to velmi neefektivní z hlediska paměti. V další jednotce budeme trénovat klasifikátor bigramů pomocí embeddingů. Mezitím můžete experimentovat s trénováním klasifikátoru bigramů v tomto notebooku a zjistit, zda dokážete dosáhnout vyšší přesnosti.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Automatický výpočet BoW vektorů\n",
"\n",
"V předchozím příkladu jsme BoW vektory počítali ručně sčítáním jednohotových kódování jednotlivých slov. Nicméně nejnovější verze TensorFlow nám umožňuje vypočítat BoW vektory automaticky pomocí předání parametru `output_mode='count` konstruktoru vektorizéru. To výrazně usnadňuje definování a trénování našeho modelu:\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": [
"## Frekvence termínů - inverzní frekvence dokumentů (TF-IDF)\n",
"\n",
"V reprezentaci BoW jsou výskyty slov váženy stejnou technikou bez ohledu na samotné slovo. Je však zřejmé, že častá slova jako *a* a *v* jsou pro klasifikaci mnohem méně důležitá než specializované termíny. Ve většině úloh NLP jsou některá slova relevantnější než jiná.\n",
"\n",
"**TF-IDF** znamená **frekvence termínů - inverzní frekvence dokumentů**. Jedná se o variaci na bag-of-words, kde místo binární hodnoty 0/1, která označuje výskyt slova v dokumentu, je použita hodnota s plovoucí desetinnou čárkou, která souvisí s frekvencí výskytu slova v korpusu.\n",
"\n",
"Formálněji je váha $w_{ij}$ slova $i$ v dokumentu $j$ definována jako:\n",
"$$\n",
"w_{ij} = tf_{ij}\\times\\log({N\\over df_i})\n",
"$$\n",
"kde\n",
"* $tf_{ij}$ je počet výskytů $i$ v $j$, tj. hodnota BoW, kterou jsme viděli dříve\n",
"* $N$ je počet dokumentů v kolekci\n",
"* $df_i$ je počet dokumentů obsahujících slovo $i$ v celé kolekci\n",
"\n",
"Hodnota TF-IDF $w_{ij}$ roste úměrně s počtem výskytů slova v dokumentu a je korigována počtem dokumentů v korpusu, které slovo obsahují, což pomáhá zohlednit skutečnost, že některá slova se objevují častěji než jiná. Například pokud se slovo objeví *v každém* dokumentu v kolekci, pak $df_i=N$ a $w_{ij}=0$, a tyto termíny by byly zcela ignorovány.\n",
"\n",
"TF-IDF vektorizaci textu můžete snadno vytvořit pomocí 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čítat TF-IDF frekvence pomocí předání parametru `output_mode='tf-idf'`. Pojďme zopakovat kód, který jsme použili výše, abychom zjistili, zda použití TF-IDF zvyšuje přesnost:\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ávěr\n",
"\n",
"I když reprezentace TF-IDF poskytují váhové frekvence různým slovům, nejsou schopny reprezentovat význam nebo pořadí. Jak slavný lingvista J. R. Firth řekl v roce 1935: „Úplný význam slova je vždy kontextový a žádná studie významu bez kontextu nemůže být brána vážně.“ Později v kurzu se naučíme, jak zachytit kontextové informace z textu pomocí jazykového modelování.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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-29T16:46:53+00:00",
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
"language_code": "cs"
}
},
"nbformat": 4,
"nbformat_minor": 4
}