577 lines
21 KiB
Plaintext
577 lines
21 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Úloha klasifikace textu\n",
|
||
"\n",
|
||
"Jak jsme již zmínili, zaměříme se na jednoduchou úlohu klasifikace textu založenou na datasetu **AG_NEWS**, kde je cílem zařadit nadpisy zpráv do jedné ze 4 kategorií: Svět, Sport, Byznys a Věda/Technika.\n",
|
||
"\n",
|
||
"## Dataset\n",
|
||
"\n",
|
||
"Tento dataset je součástí modulu [`torchtext`](https://github.com/pytorch/text), takže k němu máme snadný přístup.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import torch\n",
|
||
"import torchtext\n",
|
||
"import os\n",
|
||
"import collections\n",
|
||
"os.makedirs('./data',exist_ok=True)\n",
|
||
"train_dataset, test_dataset = torchtext.datasets.AG_NEWS(root='./data')\n",
|
||
"classes = ['World', 'Sports', 'Business', 'Sci/Tech']"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Zde `train_dataset` a `test_dataset` obsahují kolekce, které vracejí dvojice štítku (číslo třídy) a textu, například:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(3,\n",
|
||
" \"Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\\\band of ultra-cynics, are seeing green again.\")"
|
||
]
|
||
},
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"list(train_dataset)[0]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Takže, pojďme vytisknout prvních 10 nových titulků z našeho datasetu:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"**Sci/Tech** -> Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\band of ultra-cynics, are seeing green again.\n",
|
||
"**Sci/Tech** -> Carlyle Looks Toward Commercial Aerospace (Reuters) Reuters - Private investment firm Carlyle Group,\\which has a reputation for making well-timed and occasionally\\controversial plays in the defense industry, has quietly placed\\its bets on another part of the market.\n",
|
||
"**Sci/Tech** -> Oil and Economy Cloud Stocks' Outlook (Reuters) Reuters - Soaring crude prices plus worries\\about the economy and the outlook for earnings are expected to\\hang over the stock market next week during the depth of the\\summer doldrums.\n",
|
||
"**Sci/Tech** -> Iraq Halts Oil Exports from Main Southern Pipeline (Reuters) Reuters - Authorities have halted oil export\\flows from the main pipeline in southern Iraq after\\intelligence showed a rebel militia could strike\\infrastructure, an oil official said on Saturday.\n",
|
||
"**Sci/Tech** -> Oil prices soar to all-time record, posing new menace to US economy (AFP) AFP - Tearaway world oil prices, toppling records and straining wallets, present a new economic menace barely three months before the US presidential elections.\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"for i,x in zip(range(5),train_dataset):\n",
|
||
" print(f\"**{classes[x[0]]}** -> {x[1]}\")\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Protože datové sady jsou iterátory, pokud chceme data použít vícekrát, musíme je převést na seznam:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"train_dataset, test_dataset = torchtext.datasets.AG_NEWS(root='./data')\n",
|
||
"train_dataset = list(train_dataset)\n",
|
||
"test_dataset = list(test_dataset)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Tokenizace\n",
|
||
"\n",
|
||
"Nyní musíme 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",
|
||
"* použít **tokenizér** k rozdělení textu na **tokeny**\n",
|
||
"* vytvořit **slovník** těchto tokenů.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"['he', 'said', 'hello']"
|
||
]
|
||
},
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"tokenizer = torchtext.data.utils.get_tokenizer('basic_english')\n",
|
||
"tokenizer('He said: hello')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"counter = collections.Counter()\n",
|
||
"for (label, line) in train_dataset:\n",
|
||
" counter.update(tokenizer(line))\n",
|
||
"vocab = torchtext.vocab.vocab(counter, min_freq=1)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Pomocí slovníku můžeme snadno zakódovat náš tokenizovaný řetězec do sady čísel:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Vocab size if 95810\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[599, 3279, 97, 1220, 329, 225, 7368]"
|
||
]
|
||
},
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"vocab_size = len(vocab)\n",
|
||
"print(f\"Vocab size if {vocab_size}\")\n",
|
||
"\n",
|
||
"stoi = vocab.get_stoi() # dict to convert tokens to indices\n",
|
||
"\n",
|
||
"def encode(x):\n",
|
||
" return [stoi[s] for s in tokenizer(x)]\n",
|
||
"\n",
|
||
"encode('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í*, *sníh* pravděpodobně naznačují *předpověď počasí*, zatímco slova jako *akcie*, *dolar* by se počítala jako *finanční zprávy*.\n",
|
||
"\n",
|
||
"**Bag of Words** (BoW) je nejčastěji používaná tradiční vektorová reprezentace. Každé slovo je spojeno s indexem vektoru, prvek vektoru obsahuje počet výskytů daného slova v konkrétním dokumentu.\n",
|
||
"\n",
|
||
" \n",
|
||
"\n",
|
||
"> **Note**: Na BoW můžete také nahlížet jako na součet všech vektorů zakódovaných metodou one-hot pro jednotlivá slova v textu.\n",
|
||
"\n",
|
||
"Níže je příklad, jak vytvořit reprezentaci Bag of Words pomocí python knihovny Scikit Learn:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"array([[1, 1, 0, 2, 0, 0, 0, 0, 0]], dtype=int64)"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"from sklearn.feature_extraction.text import CountVectorizer\n",
|
||
"vectorizer = CountVectorizer()\n",
|
||
"corpus = [\n",
|
||
" 'I like hot dogs.',\n",
|
||
" 'The dog ran fast.',\n",
|
||
" 'Its hot outside.',\n",
|
||
" ]\n",
|
||
"vectorizer.fit_transform(corpus)\n",
|
||
"vectorizer.transform(['My dog likes hot dogs on a hot day.']).toarray()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"K výpočtu vektoru bag-of-words z vektorové reprezentace našeho datasetu AG_NEWS můžeme použít následující funkci:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"tensor([2., 1., 2., ..., 0., 0., 0.])\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"vocab_size = len(vocab)\n",
|
||
"\n",
|
||
"def to_bow(text,bow_vocab_size=vocab_size):\n",
|
||
" res = torch.zeros(bow_vocab_size,dtype=torch.float32)\n",
|
||
" for i in encode(text):\n",
|
||
" if i<bow_vocab_size:\n",
|
||
" res[i] += 1\n",
|
||
" return res\n",
|
||
"\n",
|
||
"print(to_bow(train_dataset[0][1]))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"> **Poznámka:** Zde používáme globální proměnnou `vocab_size` k určení výchozí velikosti slovníku. Protože velikost slovníku je často poměrně velká, můžeme omezit jeho velikost na nejčastější slova. Zkuste snížit hodnotu `vocab_size` a spustit níže uvedený kód, abyste viděli, jak to ovlivní přesnost. Měli byste očekávat určitý pokles přesnosti, ale ne dramatický, výměnou za vyšší výkon.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Trénování klasifikátoru BoW\n",
|
||
"\n",
|
||
"Nyní, když jsme se naučili, jak vytvořit reprezentaci Bag-of-Words pro náš text, pojďme na ní natrénovat klasifikátor. Nejprve musíme převést náš dataset pro trénování tak, aby všechny poziční vektorové reprezentace byly převedeny na reprezentaci bag-of-words. Toho lze dosáhnout předáním funkce `bowify` jako parametru `collate_fn` do standardního torch `DataLoader`:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 21,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from torch.utils.data import DataLoader\n",
|
||
"import numpy as np \n",
|
||
"\n",
|
||
"# this collate function gets list of batch_size tuples, and needs to \n",
|
||
"# return a pair of label-feature tensors for the whole minibatch\n",
|
||
"def bowify(b):\n",
|
||
" return (\n",
|
||
" torch.LongTensor([t[0]-1 for t in b]),\n",
|
||
" torch.stack([to_bow(t[1]) for t in b])\n",
|
||
" )\n",
|
||
"\n",
|
||
"train_loader = DataLoader(train_dataset, batch_size=16, collate_fn=bowify, shuffle=True)\n",
|
||
"test_loader = DataLoader(test_dataset, batch_size=16, collate_fn=bowify, shuffle=True)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Nyní definujme jednoduchou klasifikační neuronovou síť, která obsahuje jednu lineární vrstvu. Velikost vstupního vektoru se rovná `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 `LogSoftmax()`.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"net = torch.nn.Sequential(torch.nn.Linear(vocab_size,4),torch.nn.LogSoftmax(dim=1))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Nyní definujeme standardní trénovací smyčku PyTorch. Protože náš dataset je poměrně velký, pro účely výuky budeme trénovat pouze jednu epochu, a někdy dokonce méně než jednu epochu (parametr `epoch_size` nám umožňuje omezit trénování). Během trénování také budeme hlásit kumulovanou přesnost trénování; frekvence hlášení je určena pomocí parametru `report_freq`.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def train_epoch(net,dataloader,lr=0.01,optimizer=None,loss_fn = torch.nn.NLLLoss(),epoch_size=None, report_freq=200):\n",
|
||
" optimizer = optimizer or torch.optim.Adam(net.parameters(),lr=lr)\n",
|
||
" net.train()\n",
|
||
" total_loss,acc,count,i = 0,0,0,0\n",
|
||
" for labels,features in dataloader:\n",
|
||
" optimizer.zero_grad()\n",
|
||
" out = net(features)\n",
|
||
" loss = loss_fn(out,labels) #cross_entropy(out,labels)\n",
|
||
" loss.backward()\n",
|
||
" optimizer.step()\n",
|
||
" total_loss+=loss\n",
|
||
" _,predicted = torch.max(out,1)\n",
|
||
" acc+=(predicted==labels).sum()\n",
|
||
" count+=len(labels)\n",
|
||
" i+=1\n",
|
||
" if i%report_freq==0:\n",
|
||
" print(f\"{count}: acc={acc.item()/count}\")\n",
|
||
" if epoch_size and count>epoch_size:\n",
|
||
" break\n",
|
||
" return total_loss.item()/count, acc.item()/count"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 25,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"3200: acc=0.8028125\n",
|
||
"6400: acc=0.8371875\n",
|
||
"9600: acc=0.8534375\n",
|
||
"12800: acc=0.85765625\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(0.026090790722161722, 0.8620069296375267)"
|
||
]
|
||
},
|
||
"execution_count": 25,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"train_epoch(net,train_loader,epoch_size=15000)"
|
||
]
|
||
},
|
||
{
|
||
"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 zmást náš model.\n",
|
||
"\n",
|
||
"Abychom tento problém vyřešili, často se používají **reprezentace N-gramů** v metodách klasifikace dokumentů, kde frekvence každého slova, dvojice slov nebo trojice slov představuje užitečný prvek pro trénování klasifikátorů. Například v reprezentaci bigramů přidáme do slovníku všechny dvojice slov, kromě původních slov.\n",
|
||
"\n",
|
||
"Níže je příklad, jak vytvořit reprezentaci bigramů pomocí Scikit Learn:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 26,
|
||
"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": 26,
|
||
"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 některými technikami redukce dimenzionality, jako jsou *embeddingy*, o kterých budeme diskutovat v další jednotce.\n",
|
||
"\n",
|
||
"Abychom mohli použít reprezentaci N-gram v našem datasetu **AG News**, musíme vytvořit speciální slovník ngramů:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 27,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Bigram vocabulary length = 1308842\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"counter = collections.Counter()\n",
|
||
"for (label, line) in train_dataset:\n",
|
||
" l = tokenizer(line)\n",
|
||
" counter.update(torchtext.data.utils.ngrams_iterator(l,ngrams=2))\n",
|
||
" \n",
|
||
"bi_vocab = torchtext.vocab.vocab(counter, min_freq=1)\n",
|
||
"\n",
|
||
"print(\"Bigram vocabulary length = \",len(bi_vocab))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Mohli bychom použít stejný kód jako výše k natrénování klasifikátoru, avšak to by bylo velmi neefektivní z hlediska paměti. V další části natrénujeme bigramový klasifikátor pomocí embeddingů.\n",
|
||
"\n",
|
||
"> **Poznámka:** Můžete ponechat pouze ty ngramy, které se v textu vyskytují vícekrát, než je stanovený počet. Tím zajistíte, že méně časté bigramy budou vynechány, a výrazně se sníží dimenzionalita. K tomu nastavte parametr `min_freq` na vyšší hodnotu a sledujte, jak se mění délka slovníku.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Term Frequency Inverse Document Frequency TF-IDF\n",
|
||
"\n",
|
||
"V reprezentaci BoW jsou výskyty slov rovnoměrně váženy, bez ohledu na samotné slovo. Je však zřejmé, že častá slova, jako například *a*, *v* atd., jsou pro klasifikaci mnohem méně důležitá než specializované termíny. Ve skutečnosti jsou v většině úloh NLP některá slova relevantnější než jiná.\n",
|
||
"\n",
|
||
"**TF-IDF** znamená **termínová frekvence–inverzní dokumentová frekvence**. Jedná se o variaci bag of words, kde místo binární hodnoty 0/1, která označuje výskyt slova v dokumentu, se používá hodnota s plovoucí desetinnou čárkou, která souvisí s frekvencí výskytu slova v korpusu.\n",
|
||
"\n",
|
||
"Formálně 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ě počtu výskytů slova v dokumentu a je upravena podle počtu dokumentů v korpusu, které obsahují dané slovo, 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, $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": 28,
|
||
"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": 28,
|
||
"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": [
|
||
"## Závěr\n",
|
||
"\n",
|
||
"I když TF-IDF reprezentace poskytují váhování frekvence různým slovům, nejsou schopny reprezentovat význam nebo pořadí. Jak řekl slavný lingvista J. R. Firth v roce 1935: „Úplný význam slova je vždy kontextový a žádné studium významu mimo kontext nelze brát vážně.“ Později v tomto 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). Ačkoli se snažíme o přesnost, mějte 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 doporučujeme 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": "16af2a8bbb083ea23e5e41c7f5787656b2ce26968575d8763f2c4b17f9cd711f"
|
||
},
|
||
"kernelspec": {
|
||
"display_name": "Python 3.8.12 ('py38')",
|
||
"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"
|
||
},
|
||
"coopTranslator": {
|
||
"original_hash": "7b9040985e748e4e2d4c689892456ad7",
|
||
"translation_date": "2025-08-29T16:41:00+00:00",
|
||
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationPyTorch.ipynb",
|
||
"language_code": "cs"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
} |