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

647 lines
27 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Szövegklasszifikációs feladat\n",
"\n",
"Ebben a modulban egy egyszerű szövegklasszifikációs feladattal kezdünk, amely az **[AG_NEWS](http://www.di.unipi.it/~gulli/AG_corpus_of_news_articles.html)** adathalmazon alapul: hírcímeket fogunk osztályozni 4 kategória egyikébe: Világ, Sport, Üzlet és Tudomány/Technológia.\n",
"\n",
"## Az adathalmaz\n",
"\n",
"Az adathalmaz betöltéséhez a **[TensorFlow Datasets](https://www.tensorflow.org/datasets)** API-t fogjuk használni.\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": [
"Most már hozzáférhetünk az adathalmaz képzési és tesztelési részeihez a `dataset['train']` és a `dataset['test']` használatával:\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": [
"Nyomtassuk ki az adatállományunk első 10 új címsorát:\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": [
"## Szövegvektorozás\n",
"\n",
"Most a szöveget **számokká** kell alakítanunk, amelyeket tenzorként lehet ábrázolni. Ha szószintű reprezentációt szeretnénk, két dolgot kell tennünk:\n",
"\n",
"* Használjunk egy **tokenizálót**, hogy a szöveget **tokenekre** bontsuk.\n",
"* Építsünk egy **szókincset** ezekből a tokenekből.\n",
"\n",
"### A szókincs méretének korlátozása\n",
"\n",
"Az AG News adathalmaz példájában a szókincs mérete meglehetősen nagy, több mint 100 ezer szó. Általánosságban elmondható, hogy nincs szükségünk azokra a szavakra, amelyek ritkán fordulnak elő a szövegben — csak néhány mondatban szerepelnek, és a modell nem fog tanulni belőlük. Ezért van értelme a szókincs méretét egy kisebb számra korlátozni, amit a vektorizáló konstruktorának egy argumentumával adhatunk meg:\n",
"\n",
"Mindkét lépést a **TextVectorization** réteg segítségével kezelhetjük. Hozzuk létre a vektorizáló objektumot, majd hívjuk meg az `adapt` metódust, hogy végigmenjünk az összes szövegen és felépítsük a szókincset:\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": [
"> **Megjegyzés**: Csak az egész adatállomány egy részét használjuk a szókincs felépítéséhez. Ezt azért tesszük, hogy felgyorsítsuk a végrehajtási időt, és ne kelljen sokat várnod. Ugyanakkor vállaljuk annak kockázatát, hogy az egész adatállományból néhány szó nem kerül be a szókincsbe, és így figyelmen kívül marad az edzés során. Ezért az egész szókincs méretének használata és az adatállomány teljes átfutása az `adapt` során növelhetné a végső pontosságot, de nem jelentős mértékben.\n",
"\n",
"Most már hozzáférhetünk a tényleges szókincshez:\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": [
"A vektorizáló segítségével könnyedén kódolhatunk bármilyen szöveget számok halmazává:\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": [
"## Szövegábrázolás szótásképzés módszerével\n",
"\n",
"Mivel a szavak jelentést hordoznak, néha egy szöveg jelentését pusztán az egyes szavak alapján is megérthetjük, függetlenül attól, hogy milyen sorrendben szerepelnek a mondatban. Például hírek osztályozásakor a *időjárás* és *hó* szavak valószínűleg *időjárás-előrejelzésre* utalnak, míg a *részvények* és *dollár* szavak inkább *pénzügyi hírekhez* kapcsolódnak.\n",
"\n",
"A **szótásképzés** (BoW) vektori ábrázolás a legegyszerűbben érthető hagyományos vektori ábrázolás. Minden szó egy vektor indexhez van kötve, és a vektor elemei azt mutatják, hogy egy adott dokumentumban hányszor fordul elő az adott szó.\n",
"\n",
"![Kép, amely bemutatja, hogyan van ábrázolva a szótásképzés vektori reprezentációja a memóriában.](../../../../../translated_images/hu/bag-of-words-example.606fc1738f1d7ba9.webp) \n",
"\n",
"> **Megjegyzés**: A BoW-t úgy is elképzelhetjük, mint az egyes szavak egy-egy one-hot kódolt vektorának összegét a szövegben.\n",
"\n",
"Az alábbiakban egy példa látható arra, hogyan lehet szótásképzés ábrázolást létrehozni a Scikit Learn python könyvtár segítségével:\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": [
"A fentebb definiált Keras vektorizálót is használhatjuk, amely minden szószámot egy one-hot kódolássá alakít, majd ezeket a vektorokat összeadja:\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": [
"> **Megjegyzés**: Lehet, hogy meglepődsz, hogy az eredmény eltér az előző példától. Ennek az az oka, hogy a Keras példában a vektor hossza megfelel a szókincs méretének, amelyet az egész AG News adathalmazból építettünk fel, míg a Scikit Learn példában a szókincset a mintaszövegből építettük fel menet közben.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A BoW osztályozó betanítása\n",
"\n",
"Most, hogy megtanultuk, hogyan készítsük el a szövegünk bag-of-words reprezentációját, tanítsunk be egy osztályozót, amely ezt használja. Először is, az adatainkat bag-of-words reprezentációvá kell alakítanunk. Ezt a `map` függvény segítségével a következő módon érhetjük el:\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": [
"Most definiáljunk egy egyszerű osztályozó neurális hálózatot, amely egy lineáris réteget tartalmaz. A bemenet mérete `vocab_size`, a kimenet mérete pedig a kategóriák számának felel meg (4). Mivel egy osztályozási feladatot oldunk meg, a végső aktivációs függvény **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": [
"Mivel négy osztályunk van, a 80% feletti pontosság jó eredménynek számít.\n",
"\n",
"## Osztályozó tanítása egyetlen hálózatként\n",
"\n",
"Mivel a vektorizáló is egy Keras réteg, definiálhatunk egy hálózatot, amely tartalmazza azt, és végponttól végpontig taníthatjuk. Így nem szükséges a `map` használatával vektorizálni az adathalmazt, egyszerűen átadhatjuk az eredeti adathalmazt a hálózat bemenetének.\n",
"\n",
"> **Megjegyzés**: Az adathalmazunkon továbbra is alkalmaznunk kell a map-eket, hogy a mezőket (mint például `title`, `description` és `label`) szótárakból tuple-ökké alakítsuk. Azonban, ha az adatokat lemezről töltjük be, már eleve létrehozhatunk egy adathalmazt a szükséges struktúrával.\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": [
"## Bigramok, trigramok és n-gramok\n",
"\n",
"A bag-of-words megközelítés egyik korlátja, hogy bizonyos szavak több szóból álló kifejezések részei lehetnek. Például a \"hot dog\" kifejezés teljesen más jelentéssel bír, mint a \"hot\" és \"dog\" szavak külön-külön más kontextusokban. Ha a \"hot\" és \"dog\" szavakat mindig ugyanazokkal a vektorokkal ábrázoljuk, az összezavarhatja a modellünket.\n",
"\n",
"Ennek kezelésére gyakran használnak **n-gram reprezentációkat** dokumentumosztályozási módszerekben, ahol az egyes szavak, kétszavas vagy háromszavas kifejezések gyakorisága hasznos jellemző a klasszifikátorok tanításához. Például bigram reprezentációk esetén az eredeti szavak mellett az összes szópárt is hozzáadjuk a szókincshez.\n",
"\n",
"Az alábbiakban egy példa látható arra, hogyan lehet bigram bag-of-words reprezentációt generálni a Scikit Learn segítségével:\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": [
"Az n-gram megközelítés fő hátránya, hogy a szókincs mérete rendkívül gyorsan növekedni kezd. A gyakorlatban szükséges az n-gram reprezentációt egy dimenziócsökkentési technikával, például *beágyazásokkal* kombinálni, amelyről a következő egységben fogunk beszélni.\n",
"\n",
"Ahhoz, hogy n-gram reprezentációt használjunk az **AG News** adathalmazunkban, meg kell adnunk az `ngrams` paramétert a `TextVectorization` konstruktorunknak. Egy bigram szókincs hossza **jelentősen nagyobb**, esetünkben több mint 1,3 millió token! Ezért érdemes a bigram tokeneket is ésszerű számra korlátozni.\n",
"\n",
"Ugyanazt a kódot használhatnánk, mint fentebb a klasszifikátor betanításához, azonban ez nagyon memóriaigényes lenne. A következő egységben bigram klasszifikátort fogunk tanítani beágyazások segítségével. Addig is kísérletezhetsz a bigram klasszifikátor betanításával ebben a notebookban, és megnézheted, hogy el tudsz-e érni magasabb pontosságot.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## BoW vektorok automatikus kiszámítása\n",
"\n",
"A fenti példában kézzel számoltuk ki a BoW vektorokat az egyes szavak egyhot kódolásának összegzésével. Azonban a TensorFlow legújabb verziója lehetővé teszi, hogy automatikusan kiszámítsuk a BoW vektorokat, ha az `output_mode='count` paramétert átadjuk a vektorizáló konstruktorának. Ez jelentősen megkönnyíti a modellünk definiálását és tanítását:\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": [
"## Term frekvencia - fordított dokumentum frekvencia (TF-IDF)\n",
"\n",
"A BoW reprezentációban a szavak előfordulásait ugyanazzal a technikával súlyozzák, függetlenül magától a szótól. Azonban egyértelmű, hogy a gyakori szavak, mint például *a* és *in*, sokkal kevésbé fontosak az osztályozás szempontjából, mint a speciális kifejezések. A legtöbb NLP feladatban egyes szavak relevánsabbak, mint mások.\n",
"\n",
"A **TF-IDF** a **term frekvencia - fordított dokumentum frekvencia** rövidítése. Ez a bag-of-words egy változata, ahol egy szó megjelenését egy dokumentumban nem bináris 0/1 értékkel jelölik, hanem egy lebegőpontos értékkel, amely a szó előfordulási gyakoriságával van összefüggésben a korpuszban.\n",
"\n",
"Formálisabban, egy $i$ szó $j$ dokumentumban vett súlya $w_{ij}$ így definiálható:\n",
"$$\n",
"w_{ij} = tf_{ij}\\times\\log({N\\over df_i})\n",
"$$\n",
"ahol\n",
"* $tf_{ij}$ az $i$ szó előfordulásainak száma $j$-ben, azaz a korábban látott BoW érték\n",
"* $N$ a gyűjteményben lévő dokumentumok száma\n",
"* $df_i$ azon dokumentumok száma, amelyek tartalmazzák az $i$ szót az egész gyűjteményben\n",
"\n",
"A TF-IDF érték $w_{ij}$ arányosan növekszik azzal, hogy egy szó hányszor jelenik meg egy dokumentumban, és csökken azoknak a dokumentumoknak a számával, amelyek tartalmazzák a szót a korpuszban. Ez segít korrigálni azt a tényt, hogy egyes szavak gyakrabban fordulnak elő, mint mások. Például, ha egy szó *minden* dokumentumban megjelenik a gyűjteményben, akkor $df_i=N$, és $w_{ij}=0$, így ezek a kifejezések teljesen figyelmen kívül maradnak.\n",
"\n",
"A Scikit Learn segítségével könnyedén létrehozhat TF-IDF vektorizációt szövegből:\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": [
"A Kerasban a `TextVectorization` réteg automatikusan kiszámíthatja a TF-IDF gyakoriságokat az `output_mode='tf-idf'` paraméter átadásával. Ismételjük meg a fent használt kódot, hogy megnézzük, növeli-e a pontosságot a TF-IDF használata:\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": [
"## Következtetés\n",
"\n",
"Bár a TF-IDF reprezentációk frekvenciasúlyokat rendelnek különböző szavakhoz, nem képesek jelentést vagy sorrendet ábrázolni. Ahogy a híres nyelvész, J. R. Firth 1935-ben mondta: \"Egy szó teljes jelentése mindig kontextuális, és a jelentés kontextustól független tanulmányozása nem vehető komolyan.\" A kurzus későbbi részében megtanuljuk, hogyan lehet nyelvi modellezéssel megragadni a szöveg kontextuális információit.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Felelősség kizárása**: \nEz a dokumentum az AI fordítási szolgáltatás [Co-op Translator](https://github.com/Azure/co-op-translator) segítségével lett lefordítva. Bár törekszünk a pontosságra, kérjük, vegye figyelembe, hogy az automatikus fordítások hibákat vagy pontatlanságokat tartalmazhatnak. Az eredeti dokumentum az eredeti nyelvén tekintendő hiteles forrásnak. Kritikus információk esetén javasolt professzionális emberi fordítást igénybe venni. Nem vállalunk felelősséget semmilyen félreértésért vagy téves értelmezésért, amely a fordítás használatából eredhet.\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:45:51+00:00",
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
"language_code": "hu"
}
},
"nbformat": 4,
"nbformat_minor": 4
}