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

647 lines
26 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Textklassificeringsuppgift\n",
"\n",
"I den här modulen börjar vi med en enkel textklassificeringsuppgift baserad på **[AG_NEWS](http://www.di.unipi.it/~gulli/AG_corpus_of_news_articles.html)**-datasetet: vi kommer att klassificera nyhetsrubriker i en av fyra kategorier: Världen, Sport, Ekonomi och Vetenskap/Teknik.\n",
"\n",
"## Datasetet\n",
"\n",
"För att ladda datasetet kommer vi att använda **[TensorFlow Datasets](https://www.tensorflow.org/datasets)**-API:et.\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": [
"Vi kan nu komma åt tränings- och testdelarna av datasetet genom att använda `dataset['train']` och `dataset['test']` respektive:\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": [
"Låt oss skriva ut de första 10 nya rubrikerna från vår dataset:\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": [
"## Textvektorisering\n",
"\n",
"Nu behöver vi konvertera text till **siffror** som kan representeras som tensorer. Om vi vill ha representation på ordnivå behöver vi göra två saker:\n",
"\n",
"* Använda en **tokenizer** för att dela upp texten i **tokens**.\n",
"* Bygga ett **ordförråd** av dessa tokens.\n",
"\n",
"### Begränsa storleken på ordförrådet\n",
"\n",
"I exemplet med AG News-datasetet är ordförrådets storlek ganska stor, över 100 000 ord. Generellt sett behöver vi inte ord som sällan förekommer i texten — bara några få meningar kommer att innehålla dem, och modellen kommer inte att lära sig något av dem. Därför är det vettigt att begränsa ordförrådets storlek till ett mindre antal genom att skicka ett argument till vektoriseringens konstruktor:\n",
"\n",
"Båda dessa steg kan hanteras med hjälp av lagret **TextVectorization**. Låt oss instansiera vektoriseringsobjektet och sedan anropa metoden `adapt` för att gå igenom all text och bygga ett ordförråd:\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": [
"> **Observera** att vi endast använder en delmängd av hela datasetet för att bygga ett ordförråd. Vi gör detta för att snabba upp exekveringstiden och för att du inte ska behöva vänta. Dock tar vi risken att vissa ord från hela datasetet inte inkluderas i ordförrådet och ignoreras under träningen. Därför bör användning av hela ordförrådsstorleken och att köra igenom hela datasetet under `adapt` öka den slutliga noggrannheten, men inte avsevärt.\n",
"\n",
"Nu kan vi komma åt det faktiska ordförrådet:\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": [
"Med hjälp av vektoriseringen kan vi enkelt koda vilken text som helst till en uppsättning siffror:\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 textrepresentation\n",
"\n",
"Eftersom ord representerar betydelse kan vi ibland förstå innebörden av en text genom att bara titta på de enskilda orden, oavsett deras ordning i meningen. Till exempel, när vi klassificerar nyheter, är ord som *väder* och *snö* sannolikt att indikera *väderprognos*, medan ord som *aktier* och *dollar* skulle peka mot *finansiella nyheter*.\n",
"\n",
"**Bag-of-words** (BoW) vektorrepresentation är den mest lättförståeliga traditionella vektorrepresentationen. Varje ord är kopplat till ett vektorindex, och ett element i vektorn innehåller antalet förekomster av varje ord i ett givet dokument.\n",
"\n",
"![Bild som visar hur en bag-of-words vektorrepresentation representeras i minnet.](../../../../../translated_images/sv/bag-of-words-example.606fc1738f1d7ba9.webp) \n",
"\n",
"> **Note**: Du kan också tänka på BoW som en summa av alla enskilt one-hot-kodade vektorer för individuella ord i texten.\n",
"\n",
"Nedan är ett exempel på hur man genererar en bag-of-words representation med hjälp av Scikit Learn python-biblioteket:\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": [
"Vi kan också använda Keras-vektoriseraren som vi definierade ovan, konvertera varje ordnummer till en one-hot-kodning och summera alla dessa vektorer:\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": [
"> **Observera**: Du kanske blir förvånad över att resultatet skiljer sig från det tidigare exemplet. Anledningen är att i Keras-exemplet motsvarar längden på vektorn storleken på vokabulären, som byggdes från hela AG News-datasetet, medan vi i Scikit Learn-exemplet byggde vokabulären från exempeltexten direkt.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Träna BoW-klassificeraren\n",
"\n",
"Nu när vi har lärt oss att skapa bag-of-words-representationen av vår text, låt oss träna en klassificerare som använder den. Först måste vi konvertera vår dataset till en bag-of-words-representation. Detta kan göras genom att använda `map`-funktionen på följande sätt:\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": [
"Nu ska vi definiera ett enkelt klassificeringsneuronätverk som innehåller ett linjärt lager. Indatastorleken är `vocab_size`, och utmatningsstorleken motsvarar antalet klasser (4). Eftersom vi löser en klassificeringsuppgift är den slutliga aktiveringsfunktionen **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": [
"Eftersom vi har fyra klasser är en noggrannhet över 80% ett bra resultat.\n",
"\n",
"## Träna en klassificerare som ett nätverk\n",
"\n",
"Eftersom vektoriseringen också är ett Keras-lager kan vi definiera ett nätverk som inkluderar det och träna det från början till slut. På så sätt behöver vi inte vektorisera datasetet med hjälp av `map`, vi kan helt enkelt skicka det ursprungliga datasetet till nätverkets input.\n",
"\n",
"> **Note**: Vi måste fortfarande använda `map` på vårt dataset för att konvertera fält från ordböcker (såsom `title`, `description` och `label`) till tupler. Men när vi laddar data från disk kan vi bygga ett dataset med den nödvändiga strukturen direkt från början.\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": [
"## Bigrammer, trigrammer och n-gram\n",
"\n",
"En begränsning med bag-of-words-metoden är att vissa ord ingår i flerordsuttryck. Till exempel har ordet 'hot dog' en helt annan betydelse än orden 'hot' och 'dog' i andra sammanhang. Om vi alltid representerar orden 'hot' och 'dog' med samma vektorer kan det förvirra vår modell.\n",
"\n",
"För att hantera detta används ofta **n-gram-representationer** i metoder för dokumentklassificering, där frekvensen av varje ord, tvåords- eller treordsuttryck är en användbar egenskap för att träna klassificerare. I bigram-representationer, till exempel, lägger vi till alla ordpar i vokabulären, utöver de ursprungliga orden.\n",
"\n",
"Nedan är ett exempel på hur man genererar en bigram bag-of-words-representation med hjälp av 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": [
"Den största nackdelen med n-gram-metoden är att vokabulärstorleken börjar växa extremt snabbt. I praktiken behöver vi kombinera n-gram-representationen med en teknik för dimensionsreduktion, såsom *embeddings*, vilket vi kommer att diskutera i nästa enhet.\n",
"\n",
"För att använda en n-gram-representation i vårt **AG News**-dataset, behöver vi skicka `ngrams`-parametern till vår `TextVectorization`-konstruktor. Längden på ett bigram-vokabulär är **avsevärt större**, i vårt fall är det mer än 1,3 miljoner tokens! Därför är det rimligt att begränsa bigram-tokens till ett rimligt antal.\n",
"\n",
"Vi skulle kunna använda samma kod som ovan för att träna klassificeraren, men det skulle vara väldigt minnesineffektivt. I nästa enhet kommer vi att träna bigram-klassificeraren med hjälp av embeddings. Under tiden kan du experimentera med att träna bigram-klassificeraren i denna notebook och se om du kan uppnå högre noggrannhet.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Automatisk beräkning av BoW-vektorer\n",
"\n",
"I exemplet ovan beräknade vi BoW-vektorer manuellt genom att summera one-hot-enkodningarna av enskilda ord. Den senaste versionen av TensorFlow gör det dock möjligt att automatiskt beräkna BoW-vektorer genom att ange parametern `output_mode='count` till vektoriseringens konstruktor. Detta gör det betydligt enklare att definiera och träna vår modell:\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": [
"## Termfrekvens - invers dokumentfrekvens (TF-IDF)\n",
"\n",
"I BoW-representationen viktas ordens förekomster med samma teknik oavsett själva ordet. Det är dock tydligt att frekventa ord som *en* och *i* är mycket mindre viktiga för klassificering än specialiserade termer. I de flesta NLP-uppgifter är vissa ord mer relevanta än andra.\n",
"\n",
"**TF-IDF** står för **termfrekvens - invers dokumentfrekvens**. Det är en variation av bag-of-words, där man istället för ett binärt 0/1-värde som indikerar förekomsten av ett ord i ett dokument, använder ett flyttalsvärde som relaterar till frekvensen av ordets förekomst i korpusen.\n",
"\n",
"Mer formellt definieras vikten $w_{ij}$ för ett ord $i$ i dokumentet $j$ som:\n",
"$$\n",
"w_{ij} = tf_{ij}\\times\\log({N\\over df_i})\n",
"$$\n",
"där\n",
"* $tf_{ij}$ är antalet förekomster av $i$ i $j$, dvs. BoW-värdet vi har sett tidigare\n",
"* $N$ är antalet dokument i samlingen\n",
"* $df_i$ är antalet dokument som innehåller ordet $i$ i hela samlingen\n",
"\n",
"TF-IDF-värdet $w_{ij}$ ökar proportionellt med antalet gånger ett ord förekommer i ett dokument och justeras med antalet dokument i korpusen som innehåller ordet, vilket hjälper till att kompensera för att vissa ord förekommer oftare än andra. Till exempel, om ordet förekommer i *varje* dokument i samlingen, $df_i=N$, och $w_{ij}=0$, och dessa termer skulle helt ignoreras.\n",
"\n",
"Du kan enkelt skapa TF-IDF-vektorisering av text med 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": [
"I Keras kan `TextVectorization`-lagret automatiskt beräkna TF-IDF-frekvenser genom att ange parametern `output_mode='tf-idf'`. Låt oss upprepa koden vi använde ovan för att se om användning av TF-IDF ökar noggrannheten:\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": [
"## Slutsats\n",
"\n",
"Även om TF-IDF-representationer tilldelar frekvensvikter till olika ord, kan de inte representera betydelse eller ordning. Som den berömda lingvisten J. R. Firth sa år 1935: \"Den fullständiga betydelsen av ett ord är alltid kontextuell, och ingen studie av betydelse utanför kontext kan tas på allvar.\" Vi kommer senare i kursen att lära oss hur man fångar kontextuell information från text med hjälp av språkmodellering.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Ansvarsfriskrivning**: \nDetta dokument har översatts med hjälp av AI-översättningstjänsten [Co-op Translator](https://github.com/Azure/co-op-translator). Även om vi strävar efter noggrannhet, bör det noteras att automatiserade översättningar kan innehålla fel eller brister. Det ursprungliga dokumentet på dess originalspråk bör betraktas som den auktoritativa källan. För kritisk information rekommenderas professionell mänsklig översättning. Vi ansvarar inte för eventuella missförstånd eller feltolkningar som uppstår vid användning av denna översättning.\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-28T17:55:12+00:00",
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
"language_code": "sv"
}
},
"nbformat": 4,
"nbformat_minor": 4
}