├── BERT.png ├── Modelling.ipynb ├── README.md ├── Regular expression.ipynb ├── RepresentationAnd Embedding.ipynb ├── Text_Normalization.ipynb ├── alice.txt ├── attention.png ├── biLM.jpg └── transformers.ipynb /BERT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyanhui/Language-processing-basics/e361f95e89eb5bf8c33ee06d5c6562ba30811f24/BERT.png -------------------------------------------------------------------------------- /Modelling.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "f3e17361-0d1a-4481-be04-24f529a073b6", 6 | "metadata": {}, 7 | "source": [ 8 | "The language models deal with input of vectors embedded which have arbitrary length, the objective will be dependant on the history information, neural networks accept fixed size of inputs, so we need to deal with context and history size. one way of modeling is to input only a fixed window of history. The introduction of encoders and decoders:\n", 9 | "\n", 10 | "Encoders : Send input through a smaller-than-necessary layer to force the neural network to find a small set of parameters that produced intermediate activations that approximates the output\n", 11 | "\n", 12 | "Decoder : A set of parameters that recovers information to produce the output" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "id": "95e07707-e9f6-4b56-b6a4-3b5105adae51", 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "## read the text file\n", 23 | "with open('Europarl-french-v7/europarl-en.txt', 'r') as file:\n", 24 | " lines_en = file.readlines()[:5000]\n", 25 | "with open('Europarl-french-v7/europarl-fr.txt', 'r') as file:\n", 26 | " lines_fr = file.readlines()[:5000]" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "id": "f287f3cc-e3a9-48ca-bee1-2d631a8848fa", 32 | "metadata": {}, 33 | "source": [ 34 | "## RNN and LSTM\n", 35 | "RNN structures : deal with different length of history, recurrently process each time slice\n", 36 | "![RNN](RNN.png)\n", 37 | "\n", 38 | "LSTM : instead of replacing the hidden state each time-slice, adding a memory cell to decide which part to forget or memmorize\n", 39 | "![LTSM](LSTM.png)\n", 40 | "\n", 41 | "a. forget gate : $f = \\sigma(W_{x,f}x+b_{x,f}+W_{h,f}h+b_{h,f}) $ output (0,1)\n", 42 | "\n", 43 | "b. input gate : $i = \\sigma(W_{x,i}x+b_{i,f}+W_{h,i}h+b_{h,i}) $ \n", 44 | "\n", 45 | "c. cell memory : $g = tanh(W_{x,g}x+b_{x,g}+W_{h,g}h+b_{h,g}) $ output range [-1,1]\n", 46 | "\n", 47 | "d. update cell state : $c = (f*c_{i-1})+(i*g)$\n", 48 | "\n", 49 | "e. output gate : $o = \\sigma(W_{x,o}x+b_{x,o}+W_{h,o}h+b_{h,o}) $ \n", 50 | "\n", 51 | "f. update hidden state: $h_i = o*tanh(c_i)$" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 43, 57 | "id": "c3e95975-f461-4ce5-b7a0-2550d079eb67", 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "import numpy as np\n", 62 | "import tensorflow as tf\n", 63 | "from transformers import BertTokenizer\n", 64 | "from tensorflow.keras.models import Sequential\n", 65 | "from tensorflow.keras.layers import SimpleRNN, LSTM, Dense, Input\n", 66 | "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", 67 | "\n", 68 | "# Create input sequences and labels for training\n", 69 | "tokenizer = BertTokenizer.from_pretrained(\"bert-base-cased\")\n", 70 | "input_sequences = []\n", 71 | "for line in lines_en[:500]:\n", 72 | " token_list = tokenizer.encode(line.replace(\"\\n\", \"\")[:512])\n", 73 | " input_sequences.append(token_list[:-2])\n", 74 | "\n", 75 | "max_sequence_length = max(len(seq) for seq in input_sequences)\n", 76 | "input_sequences = pad_sequences(input_sequences, maxlen=max_sequence_length, padding='pre')\n", 77 | "\n", 78 | "X, y = input_sequences[:, :-1], input_sequences[:, -1]\n", 79 | "y = tf.keras.utils.to_categorical(y, num_classes=tokenizer.vocab_size)\n", 80 | "X_ = X.reshape((X.shape[0], 1, X.shape[1]))" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 15, 86 | "id": "4305543a-da8e-470c-9e70-9ad3e8da0f58", 87 | "metadata": {}, 88 | "outputs": [ 89 | { 90 | "data": { 91 | "text/plain": [ 92 | "(500, 1, 104)" 93 | ] 94 | }, 95 | "execution_count": 15, 96 | "metadata": {}, 97 | "output_type": "execute_result" 98 | } 99 | ], 100 | "source": [ 101 | "X_.shape" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 17, 107 | "id": "329aaffd-2186-4743-a727-5a420bbf7a94", 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "(500, 28996)" 114 | ] 115 | }, 116 | "execution_count": 17, 117 | "metadata": {}, 118 | "output_type": "execute_result" 119 | } 120 | ], 121 | "source": [ 122 | "y.shape" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 47, 128 | "id": "d7e99b92-b0de-44d4-86f6-137a6360d993", 129 | "metadata": {}, 130 | "outputs": [ 131 | { 132 | "name": "stderr", 133 | "output_type": "stream", 134 | "text": [ 135 | "/opt/anaconda3/lib/python3.12/site-packages/keras/src/layers/rnn/rnn.py:200: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", 136 | " super().__init__(**kwargs)\n" 137 | ] 138 | }, 139 | { 140 | "data": { 141 | "text/plain": [ 142 | "" 143 | ] 144 | }, 145 | "execution_count": 47, 146 | "metadata": {}, 147 | "output_type": "execute_result" 148 | } 149 | ], 150 | "source": [ 151 | "# Build and train the SimpleRNN model\n", 152 | "model_rnn = Sequential()\n", 153 | "model_rnn.add(SimpleRNN(100, input_shape=(1, X_.shape[2])))\n", 154 | "model_rnn.add(Dense(tokenizer.vocab_size, activation='softmax'))\n", 155 | "model_rnn.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n", 156 | "model_rnn.fit(X_, y, epochs=100, verbose=0)\n", 157 | "\n", 158 | "# Build and train the LSTM model\n", 159 | "model_lstm = Sequential()\n", 160 | "model_lstm.add(LSTM(100, input_shape=(1, X_.shape[2])))\n", 161 | "model_lstm.add(Dense(tokenizer.vocab_size, activation='softmax'))\n", 162 | "model_lstm.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n", 163 | "model_lstm.fit(X_, y, epochs=100, verbose=0)\n" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": 49, 169 | "id": "e8498e2f-e8e7-4d7d-8c77-b4dc2b840df9", 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 52ms/step\n", 177 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step\n", 178 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 9ms/step\n", 179 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 10ms/step\n", 180 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 10ms/step\n", 181 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 43ms/step\n", 182 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 9ms/step\n", 183 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 9ms/step\n", 184 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 9ms/step\n", 185 | "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 10ms/step\n", 186 | "Generated Text (SimpleRNN): There should be no confusion in this debate. As environmentalists, we do not want an programmes employment them ##ity report\n", 187 | "Generated Text (LSTM): There should be no confusion in this debate. As environmentalists, we do not want an safety Europe them citizens Europe\n" 188 | ] 189 | } 190 | ], 191 | "source": [ 192 | "# Generate text using the trained models\n", 193 | "def generate_text(seed_text, model, max_sequence_len, num_words):\n", 194 | " for _ in range(num_words):\n", 195 | " token_list = tokenizer.encode(seed_text)\n", 196 | " token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')\n", 197 | " token_list = token_list.reshape((token_list.shape[0], 1, token_list.shape[1]))\n", 198 | " predicted = np.argmax(model.predict(token_list), axis=-1)\n", 199 | " output_word = tokenizer.decode(predicted)\n", 200 | " seed_text += \" \" + output_word\n", 201 | " return seed_text\n", 202 | "\n", 203 | "# Example of generating text with each model\n", 204 | "generated_text_rnn = generate_text(\"There should be no confusion in this debate. As environmentalists, we do not want an\", model_rnn, max_sequence_length, num_words=5)\n", 205 | "generated_text_lstm = generate_text(\"There should be no confusion in this debate. As environmentalists, we do not want an\", model_lstm, max_sequence_length, num_words=5)\n", 206 | "\n", 207 | "print(\"Generated Text (SimpleRNN):\", generated_text_rnn)\n", 208 | "print(\"Generated Text (LSTM):\", generated_text_lstm)" 209 | ] 210 | }, 211 | { 212 | "cell_type": "markdown", 213 | "id": "430984c2-68fd-4cf5-a425-e871fec12722", 214 | "metadata": {}, 215 | "source": [ 216 | "## Sequence to Sequence models\n", 217 | "When dealing with translation tasks, the input and output will look like\n", 218 | "\n", 219 | "$input_i = SOSx_{i,1}x_{i,2}\\dots x_{i,2}EOS$\n", 220 | "\n", 221 | "$ouput_i = SOSy_{i,1}y_{i,2}\\dots y_{i,2}EOS$\n", 222 | "\n", 223 | "there's no one-to-one mapping, the output could be of arbitrary length, the entire context is needed for translation.\n", 224 | "\n", 225 | "Then a sequence to sequence model structure is utilized, it encodes all the words until EOS reached, then after decoding all words, there's a encoding layer to put all results together\n", 226 | "![s2s](s2s.png)" 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": 19, 232 | "id": "0c199d2b-3b9c-475f-9649-3ec57d40ed0a", 233 | "metadata": {}, 234 | "outputs": [], 235 | "source": [ 236 | "import numpy as np\n", 237 | "import keras\n", 238 | "import os\n", 239 | "from pathlib import Path" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 35, 245 | "id": "bf8bc333-36d8-4e87-b1e1-2ecca4758790", 246 | "metadata": {}, 247 | "outputs": [], 248 | "source": [ 249 | "batch_size = 64 # Batch size for training.\n", 250 | "epochs = 16 # Number of epochs to train for.\n", 251 | "latent_dim = 256 # Latent dimensionality of the encoding space.\n", 252 | "num_samples = 1000 # Number of samples to train on." 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 37, 258 | "id": "997ac799-c57b-4e96-8142-fdea9cd9eeb3", 259 | "metadata": {}, 260 | "outputs": [ 261 | { 262 | "name": "stdout", 263 | "output_type": "stream", 264 | "text": [ 265 | "Number of samples: 1000\n", 266 | "Number of unique input tokens: 86\n", 267 | "Number of unique output tokens: 99\n", 268 | "Max sequence length for inputs: 683\n", 269 | "Max sequence length for outputs: 877\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "# Vectorize the data.\n", 275 | "input_texts = []\n", 276 | "target_texts = []\n", 277 | "input_characters = set()\n", 278 | "target_characters = set()\n", 279 | "\n", 280 | "for i in range(num_samples):\n", 281 | " input_text = lines_en[i]\n", 282 | " target_text = lines_fr[i]\n", 283 | " target_text = \"\\t\" + target_text + \"\\n\"\n", 284 | " input_texts.append(input_text)\n", 285 | " target_texts.append(target_text)\n", 286 | " for char in input_text:\n", 287 | " if char not in input_characters:\n", 288 | " input_characters.add(char)\n", 289 | " for char in target_text:\n", 290 | " if char not in target_characters:\n", 291 | " target_characters.add(char)\n", 292 | "\n", 293 | "input_characters = sorted(list(input_characters))\n", 294 | "target_characters = sorted(list(target_characters))\n", 295 | "num_encoder_tokens = len(input_characters)\n", 296 | "num_decoder_tokens = len(target_characters)\n", 297 | "max_encoder_seq_length = max([len(txt) for txt in input_texts])\n", 298 | "max_decoder_seq_length = max([len(txt) for txt in target_texts])\n", 299 | "\n", 300 | "print(\"Number of samples:\", len(input_texts))\n", 301 | "print(\"Number of unique input tokens:\", num_encoder_tokens)\n", 302 | "print(\"Number of unique output tokens:\", num_decoder_tokens)\n", 303 | "print(\"Max sequence length for inputs:\", max_encoder_seq_length)\n", 304 | "print(\"Max sequence length for outputs:\", max_decoder_seq_length)" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 39, 310 | "id": "65a922e2-3cd9-4f7e-ae16-26183ae06ce9", 311 | "metadata": {}, 312 | "outputs": [], 313 | "source": [ 314 | "input_token_index = dict([(char, i) for i, char in enumerate(input_characters)])\n", 315 | "target_token_index = dict([(char, i) for i, char in enumerate(target_characters)])\n", 316 | "\n", 317 | "encoder_input_data = np.zeros(\n", 318 | " (len(input_texts), max_encoder_seq_length, num_encoder_tokens),\n", 319 | " dtype=\"float32\",\n", 320 | ")\n", 321 | "decoder_input_data = np.zeros(\n", 322 | " (len(input_texts), max_decoder_seq_length, num_decoder_tokens),\n", 323 | " dtype=\"float32\",\n", 324 | ")\n", 325 | "decoder_target_data = np.zeros(\n", 326 | " (len(input_texts), max_decoder_seq_length, num_decoder_tokens),\n", 327 | " dtype=\"float32\",\n", 328 | ")\n", 329 | "\n", 330 | "for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)):\n", 331 | " for t, char in enumerate(input_text):\n", 332 | " encoder_input_data[i, t, input_token_index[char]] = 1.0\n", 333 | " encoder_input_data[i, t + 1 :, input_token_index[\" \"]] = 1.0\n", 334 | " for t, char in enumerate(target_text):\n", 335 | " # decoder_target_data is ahead of decoder_input_data by one timestep\n", 336 | " decoder_input_data[i, t, target_token_index[char]] = 1.0\n", 337 | " if t > 0:\n", 338 | " # decoder_target_data will be ahead by one timestep\n", 339 | " # and will not include the start character.\n", 340 | " decoder_target_data[i, t - 1, target_token_index[char]] = 1.0\n", 341 | " decoder_input_data[i, t + 1 :, target_token_index[\" \"]] = 1.0\n", 342 | " decoder_target_data[i, t:, target_token_index[\" \"]] = 1.0" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": 41, 348 | "id": "82680a1d-8762-44f5-918b-b025acb48363", 349 | "metadata": {}, 350 | "outputs": [], 351 | "source": [ 352 | "# Define an input sequence and process it.\n", 353 | "encoder_inputs = keras.Input(shape=(None, num_encoder_tokens))\n", 354 | "encoder = keras.layers.LSTM(latent_dim, return_state=True)\n", 355 | "encoder_outputs, state_h, state_c = encoder(encoder_inputs)\n", 356 | "\n", 357 | "# We discard `encoder_outputs` and only keep the states.\n", 358 | "encoder_states = [state_h, state_c]\n", 359 | "\n", 360 | "# Set up the decoder, using `encoder_states` as initial state.\n", 361 | "decoder_inputs = keras.Input(shape=(None, num_decoder_tokens))\n", 362 | "\n", 363 | "# We set up our decoder to return full output sequences,\n", 364 | "# and to return internal states as well. We don't use the\n", 365 | "# return states in the training model, but we will use them in inference.\n", 366 | "decoder_lstm = keras.layers.LSTM(latent_dim, return_sequences=True, return_state=True)\n", 367 | "decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)\n", 368 | "decoder_dense = keras.layers.Dense(num_decoder_tokens, activation=\"softmax\")\n", 369 | "decoder_outputs = decoder_dense(decoder_outputs)\n", 370 | "\n", 371 | "# Define the model that will turn\n", 372 | "# `encoder_input_data` & `decoder_input_data` into `decoder_target_data`\n", 373 | "model = keras.Model([encoder_inputs, decoder_inputs], decoder_outputs)" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": 43, 379 | "id": "4238ca01-375a-4e92-9059-61f920d846d8", 380 | "metadata": {}, 381 | "outputs": [ 382 | { 383 | "name": "stdout", 384 | "output_type": "stream", 385 | "text": [ 386 | "Epoch 1/16\n", 387 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.6275 - loss: 2.6168 - val_accuracy: 0.8410 - val_loss: 0.9426\n", 388 | "Epoch 2/16\n", 389 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m30s\u001b[0m 2s/step - accuracy: 0.8151 - loss: 1.0525 - val_accuracy: 0.8409 - val_loss: 0.9267\n", 390 | "Epoch 3/16\n", 391 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8183 - loss: 1.0300 - val_accuracy: 0.8409 - val_loss: 0.8873\n", 392 | "Epoch 4/16\n", 393 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8169 - loss: 1.0070 - val_accuracy: 0.8409 - val_loss: 0.8595\n", 394 | "Epoch 5/16\n", 395 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8182 - loss: 0.9703 - val_accuracy: 0.8405 - val_loss: 0.9735\n", 396 | "Epoch 6/16\n", 397 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8213 - loss: 0.9795 - val_accuracy: 0.8409 - val_loss: 0.7349\n", 398 | "Epoch 7/16\n", 399 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m30s\u001b[0m 2s/step - accuracy: 0.8169 - loss: 0.9208 - val_accuracy: 0.8407 - val_loss: 0.7991\n", 400 | "Epoch 8/16\n", 401 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m30s\u001b[0m 2s/step - accuracy: 0.8141 - loss: 0.8940 - val_accuracy: 0.8404 - val_loss: 0.6042\n", 402 | "Epoch 9/16\n", 403 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m30s\u001b[0m 2s/step - accuracy: 0.8155 - loss: 0.7221 - val_accuracy: 0.8408 - val_loss: 0.9141\n", 404 | "Epoch 10/16\n", 405 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8228 - loss: 0.8052 - val_accuracy: 0.8405 - val_loss: 0.5939\n", 406 | "Epoch 11/16\n", 407 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8189 - loss: 0.6609 - val_accuracy: 0.8339 - val_loss: 0.6076\n", 408 | "Epoch 12/16\n", 409 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8103 - loss: 0.9425 - val_accuracy: 0.8405 - val_loss: 0.5868\n", 410 | "Epoch 13/16\n", 411 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8163 - loss: 0.6757 - val_accuracy: 0.8405 - val_loss: 0.5785\n", 412 | "Epoch 14/16\n", 413 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m30s\u001b[0m 2s/step - accuracy: 0.8134 - loss: 0.6801 - val_accuracy: 0.8406 - val_loss: 0.5760\n", 414 | "Epoch 15/16\n", 415 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m31s\u001b[0m 2s/step - accuracy: 0.8135 - loss: 0.6676 - val_accuracy: 0.8332 - val_loss: 0.5806\n", 416 | "Epoch 16/16\n", 417 | "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m30s\u001b[0m 2s/step - accuracy: 0.8113 - loss: 0.7723 - val_accuracy: 0.8390 - val_loss: 0.5860\n" 418 | ] 419 | }, 420 | { 421 | "data": { 422 | "text/plain": [ 423 | "" 424 | ] 425 | }, 426 | "execution_count": 43, 427 | "metadata": {}, 428 | "output_type": "execute_result" 429 | } 430 | ], 431 | "source": [ 432 | "model.compile(\n", 433 | " optimizer=\"rmsprop\", loss=\"categorical_crossentropy\", metrics=[\"accuracy\"]\n", 434 | ")\n", 435 | "model.fit(\n", 436 | " [encoder_input_data, decoder_input_data],\n", 437 | " decoder_target_data,\n", 438 | " batch_size=batch_size,\n", 439 | " epochs=epochs,\n", 440 | " validation_split=0.2,\n", 441 | ")\n", 442 | "# Save model\n", 443 | "# model.save(\"s2s_model.keras\")" 444 | ] 445 | }, 446 | { 447 | "cell_type": "code", 448 | "execution_count": 61, 449 | "id": "40668421-3b25-40a4-809f-6a74d18d5598", 450 | "metadata": {}, 451 | "outputs": [ 452 | { 453 | "name": "stdout", 454 | "output_type": "stream", 455 | "text": [ 456 | "-\n", 457 | "Input sentence: Are state aid to business or inter-company agreements legitimate in a market economy, and who must supervise these exceptions to the absolute rules of the market economy?\n", 458 | "\n", 459 | "Decoded sentence: eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\n" 460 | ] 461 | } 462 | ], 463 | "source": [ 464 | "encoder_inputs = model.input[0] # input_1\n", 465 | "encoder_outputs, state_h_enc, state_c_enc = model.layers[2].output # lstm_1\n", 466 | "encoder_states = [state_h_enc, state_c_enc]\n", 467 | "encoder_model = keras.Model(encoder_inputs, encoder_states)\n", 468 | "\n", 469 | "decoder_inputs = model.input[1] # input_2\n", 470 | "decoder_state_input_h = keras.Input(shape=(latent_dim,))\n", 471 | "decoder_state_input_c = keras.Input(shape=(latent_dim,))\n", 472 | "decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]\n", 473 | "decoder_lstm = model.layers[3]\n", 474 | "decoder_outputs, state_h_dec, state_c_dec = decoder_lstm(\n", 475 | " decoder_inputs, initial_state=decoder_states_inputs\n", 476 | ")\n", 477 | "decoder_states = [state_h_dec, state_c_dec]\n", 478 | "decoder_dense = model.layers[4]\n", 479 | "decoder_outputs = decoder_dense(decoder_outputs)\n", 480 | "decoder_model = keras.Model(\n", 481 | " [decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states\n", 482 | ")\n", 483 | "\n", 484 | "## translation with this model\n", 485 | "reverse_input_char_index = dict((i, char) for char, i in input_token_index.items())\n", 486 | "reverse_target_char_index = dict((i, char) for char, i in target_token_index.items())\n", 487 | "\n", 488 | "\n", 489 | "def decode_sequence(input_seq):\n", 490 | " # Encode the input as state vectors.\n", 491 | " states_value = encoder_model.predict(input_seq, verbose=0)\n", 492 | " \n", 493 | " # Generate empty target sequence of length 1.\n", 494 | " target_seq = np.zeros((1, 1, num_decoder_tokens))\n", 495 | " # Populate the first character of target sequence with the start character.\n", 496 | " target_seq[0, 0, target_token_index[\"\\t\"]] = 1.0\n", 497 | "\n", 498 | " # Sampling loop for a batch of sequences\n", 499 | " # (to simplify, here we assume a batch of size 1).\n", 500 | " stop_condition = False\n", 501 | " decoded_sentence = \"\"\n", 502 | " while not stop_condition:\n", 503 | " output_tokens, h, c = decoder_model.predict(\n", 504 | " [target_seq] + states_value, verbose=0\n", 505 | " )\n", 506 | "\n", 507 | " # Sample a token\n", 508 | " sampled_token_index = np.argmax(output_tokens[0, -1, :])\n", 509 | " sampled_char = reverse_target_char_index[sampled_token_index]\n", 510 | " decoded_sentence += sampled_char\n", 511 | "\n", 512 | " # Exit condition: either hit max length\n", 513 | " # or find stop character.\n", 514 | " if sampled_char == \"\\n\" or len(decoded_sentence) > max_decoder_seq_length:\n", 515 | " stop_condition = True\n", 516 | "\n", 517 | " # Update the target sequence (of length 1).\n", 518 | " target_seq = np.zeros((1, 1, num_decoder_tokens))\n", 519 | " target_seq[0, 0, sampled_token_index] = 1.0\n", 520 | "\n", 521 | " # Update states\n", 522 | " states_value = [h, c]\n", 523 | " return decoded_sentence\n", 524 | "\n", 525 | "\n", 526 | "# Take one sequence \n", 527 | "# for trying out decoding.\n", 528 | "input_seq = encoder_input_data[num_samples - 1:num_samples]\n", 529 | "decoded_sentence = decode_sequence(input_seq)\n", 530 | "print(\"-\")\n", 531 | "print(\"Input sentence:\", input_texts[num_samples - 1])\n", 532 | "print(\"Decoded sentence:\", decoded_sentence)" 533 | ] 534 | }, 535 | { 536 | "cell_type": "code", 537 | "execution_count": null, 538 | "id": "eca2a9a9-609f-4e7c-8bb9-c22836a0a008", 539 | "metadata": {}, 540 | "outputs": [], 541 | "source": [] 542 | } 543 | ], 544 | "metadata": { 545 | "kernelspec": { 546 | "display_name": "Python 3 (ipykernel)", 547 | "language": "python", 548 | "name": "python3" 549 | }, 550 | "language_info": { 551 | "codemirror_mode": { 552 | "name": "ipython", 553 | "version": 3 554 | }, 555 | "file_extension": ".py", 556 | "mimetype": "text/x-python", 557 | "name": "python", 558 | "nbconvert_exporter": "python", 559 | "pygments_lexer": "ipython3", 560 | "version": "3.12.4" 561 | } 562 | }, 563 | "nbformat": 4, 564 | "nbformat_minor": 5 565 | } 566 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Here's a brief walk through of basic language modelling. There are mainly four parts of this content. 2 | 3 | 1. Word nomalization, preprocessing words to more standard forms. 4 | 2. Representation, embedding the words into vectors. 5 | 3. Modelling, recurrent models and sequence to sequence model. 6 | 4. Transformers, the attention mechanism and architecture of transformers. 7 | -------------------------------------------------------------------------------- /Regular expression.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "c20c2c81-1624-4c97-8ef7-390f0bf8e521", 6 | "metadata": {}, 7 | "source": [ 8 | "## Character classes\n", 9 | "s : white space characters\n", 10 | "\n", 11 | "S : Non-white space characters\n", 12 | "\n", 13 | "d : digits\n", 14 | "\n", 15 | "D : Non-digits\n", 16 | "\n", 17 | "w : any word character\n", 18 | "\n", 19 | "W : None-word character\n", 20 | "\n", 21 | "b : word boundary" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "id": "aade9e67-d098-4bf7-a767-3dd1c38a7157", 27 | "metadata": {}, 28 | "source": [ 29 | "## Symbols\n", 30 | "#### repeaters\n", 31 | "\\* : 0-inf repeatition\n", 32 | "\n", 33 | "\\+ : 1-inf repeatition\n", 34 | "\n", 35 | "{number} : number times of repeatition {2,} : more than 2; {2,5} : 2-5 times\n", 36 | "\n", 37 | "#### blurry search\n", 38 | "\n", 39 | "? : may or may not\n", 40 | "\n", 41 | ". : any character\n", 42 | "\n", 43 | "#### positions\n", 44 | "\n", 45 | "^ : beginning\n", 46 | "\n", 47 | "$ : end\n", 48 | "\n", 49 | "\\number : matches the number th character\n", 50 | "\n", 51 | "#### range\n", 52 | "[a-z] : lower letters\n", 53 | "\n", 54 | "[A-Z] : cap letters\n", 55 | "\n", 56 | "[0-9] : digits\n", 57 | "\n", 58 | "() : groups\n", 59 | "\n", 60 | "[^] : negation\n", 61 | "\n", 62 | "(a|b|c) : a or b or c\n", 63 | "\n", 64 | "#### comments\n", 65 | "\n", 66 | "(?#) : intermediate comment\n", 67 | "\n", 68 | "\\# : end of line comment" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "id": "e9cf10d8-dfc9-41c5-968f-c0271629a887", 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [] 78 | } 79 | ], 80 | "metadata": { 81 | "kernelspec": { 82 | "display_name": "Python 3 (ipykernel)", 83 | "language": "python", 84 | "name": "python3" 85 | }, 86 | "language_info": { 87 | "codemirror_mode": { 88 | "name": "ipython", 89 | "version": 3 90 | }, 91 | "file_extension": ".py", 92 | "mimetype": "text/x-python", 93 | "name": "python", 94 | "nbconvert_exporter": "python", 95 | "pygments_lexer": "ipython3", 96 | "version": "3.12.4" 97 | } 98 | }, 99 | "nbformat": 4, 100 | "nbformat_minor": 5 101 | } 102 | -------------------------------------------------------------------------------- /RepresentationAnd Embedding.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "df4826be-2d80-4d9a-9521-54092a018867", 6 | "metadata": {}, 7 | "source": [ 8 | "# Representation\n", 9 | "converts the words to numerical vectors" 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "id": "df247f1d-2125-40f8-9299-b2c789915e06", 15 | "metadata": { 16 | "jp-MarkdownHeadingCollapsed": true 17 | }, 18 | "source": [ 19 | "### One-hot Encoding (Dummy Encoding)\n", 20 | "Converts categories into multiple binary columns where only one bit is active (1) per entry.\n", 21 | "\n", 22 | "PROS: numerical categorical data,eliminating ordinality (like year 1, 2, 3 ,4 don't provide order information)\n", 23 | "\n", 24 | "CONS: higher dimension, sparse observation for some dimensions, overfitting when too many categories" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 7, 30 | "id": "340958c7-349d-405c-b1ca-6cb98730714e", 31 | "metadata": {}, 32 | "outputs": [ 33 | { 34 | "name": "stdout", 35 | "output_type": "stream", 36 | "text": [ 37 | "Original Data:\n", 38 | " Employee id Gender Remarks\n", 39 | "0 10 M Good\n", 40 | "1 20 F Nice\n", 41 | "2 15 F Good\n", 42 | "3 25 M Great\n", 43 | "4 30 F Nice\n", 44 | "\n", 45 | "One-Hot Encoded Data using Pandas:\n", 46 | " Employee id Gender_M Remarks_Great Remarks_Nice\n", 47 | "0 10 True False False\n", 48 | "1 20 False False True\n", 49 | "2 15 False False False\n", 50 | "3 25 True True False\n", 51 | "4 30 False False True\n", 52 | "\n", 53 | "One-Hot Encoded Data using Scikit-Learn:\n", 54 | " Employee id Gender_F Gender_M Remarks_Good Remarks_Great Remarks_Nice\n", 55 | "0 10 0.0 1.0 1.0 0.0 0.0\n", 56 | "1 20 1.0 0.0 0.0 0.0 1.0\n", 57 | "2 15 1.0 0.0 1.0 0.0 0.0\n", 58 | "3 25 0.0 1.0 0.0 1.0 0.0\n", 59 | "4 30 1.0 0.0 0.0 0.0 1.0\n", 60 | "\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "import pandas as pd\n", 66 | "from sklearn.preprocessing import OneHotEncoder\n", 67 | "data = {\n", 68 | " 'Employee id': [10, 20, 15, 25, 30],\n", 69 | " 'Gender': ['M', 'F', 'F', 'M', 'F'],\n", 70 | " 'Remarks': ['Good', 'Nice', 'Good', 'Great', 'Nice']\n", 71 | "}\n", 72 | "\n", 73 | "df = pd.DataFrame(data)\n", 74 | "print(f\"Original Data:\\n{df}\\n\")\n", 75 | "# Use pd.get_dummies() to one-hot encode the categorical columns\n", 76 | "df_pandas_encoded = pd.get_dummies(df, columns=['Gender', 'Remarks'], drop_first=True)\n", 77 | "print(f\"One-Hot Encoded Data using Pandas:\\n{df_pandas_encoded}\\n\")\n", 78 | "\n", 79 | "encoder = OneHotEncoder(sparse_output=False)\n", 80 | "categorical_columns = ['Gender', 'Remarks']\n", 81 | "one_hot_encoded = encoder.fit_transform(df[categorical_columns])\n", 82 | "one_hot_df = pd.DataFrame(one_hot_encoded, \n", 83 | " columns=encoder.get_feature_names_out(categorical_columns))\n", 84 | "\n", 85 | "df_sklearn_encoded = pd.concat([df.drop(categorical_columns, axis=1), one_hot_df], axis=1)\n", 86 | "\n", 87 | "print(f\"One-Hot Encoded Data using Scikit-Learn:\\n{df_sklearn_encoded}\\n\")\n" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "id": "d9fccfa5-1f1e-4611-b470-ddb2f4380567", 93 | "metadata": {}, 94 | "source": [ 95 | "### Bag of Words\n", 96 | "\n", 97 | "step1 : preprocessing the text into list of words\n", 98 | "\n", 99 | "step2 : summarize the frequency of each words and select most frequent n words\n", 100 | "\n", 101 | "step2 : set binary vector, where the frequent word positions are 1 otherwise 0" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 1, 107 | "id": "0fde6258-a653-499c-813c-e75d2e4b96db", 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "## read the text file\n", 112 | "with open('de-en.txt', 'r') as file:\n", 113 | " lines = file.readlines()" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 5, 119 | "id": "c105b384-e3ae-43b0-a5d7-d4f6d26798d3", 120 | "metadata": {}, 121 | "outputs": [ 122 | { 123 | "name": "stdout", 124 | "output_type": "stream", 125 | "text": [ 126 | "['wiederaufnahme der sitzungsperiode ich erkläre die am freitag dem 17', 'dezember unterbrochene sitzungsperiode des europäischen parlaments für wiederaufgenommen wünsche ihnen nochmals alles gute zum jahreswechsel und hoffe daß sie schöne ferien hatten', 'wie sie feststellen konnten ist der gefürchtete millenium bug nicht eingetreten', 'doch sind bürger einiger unserer mitgliedstaaten opfer von schrecklichen naturkatastrophen geworden', 'im parlament besteht der wunsch nach einer aussprache im verlauf dieser sitzungsperiode in den nächsten tagen', 'heute möchte ich sie bitten das ist auch der wunsch einiger kolleginnen und kollegen allen opfern der stürme insbesondere in den verschiedenen ländern der europäischen union in einer schweigeminute zu gedenken', 'ich bitte sie sich zu einer schweigeminute zu erheben', 'das parlament erhebt sich zu einer schweigeminute', 'frau präsidentin zur geschäftsordnung', 'wie sie sicher aus der presse und dem fernsehen wissen gab es in sri lanka mehrere bombenexplosionen mit zahlreichen toten']\n" 127 | ] 128 | } 129 | ], 130 | "source": [ 131 | "import nltk \n", 132 | "import re \n", 133 | "import numpy as np \n", 134 | " \n", 135 | "## preprocessing \n", 136 | "dataset = nltk.sent_tokenize(''.join(lines))\n", 137 | "for i in range(len(dataset)):\n", 138 | " dataset[i] = dataset[i].lower() # Convert to lowercase\n", 139 | " dataset[i] = re.sub(r'\\W', ' ', dataset[i]) # Remove non-word characters\n", 140 | " dataset[i] = re.sub(r'\\s+', ' ', dataset[i]).strip() # Remove extra spaces\n", 141 | "\n", 142 | "# Output cleaned sentences\n", 143 | "print(dataset[:10]) " 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": 7, 149 | "id": "18ad339c-570e-4157-a185-c086890a0e9b", 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [ 153 | "## frequency\n", 154 | "word2count = {} \n", 155 | "for data in dataset: \n", 156 | " words = nltk.word_tokenize(data) \n", 157 | " for word in words: \n", 158 | " if word not in word2count.keys(): \n", 159 | " word2count[word] = 1\n", 160 | " else: \n", 161 | " word2count[word] += 1" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 15, 167 | "id": "7e8a99d2-e5eb-4a50-9e9b-9ebf93343b1e", 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [ 171 | "## results\n", 172 | "import heapq \n", 173 | "freq_words = heapq.nlargest(200, word2count, key=word2count.get)\n", 174 | "BoW = [] \n", 175 | "for data in dataset[:500]: \n", 176 | " vector = [] \n", 177 | " for word in freq_words: \n", 178 | " if word in nltk.word_tokenize(data): \n", 179 | " vector.append(1) \n", 180 | " else: \n", 181 | " vector.append(0) \n", 182 | " BoW.append(vector) \n", 183 | "BoW = np.asarray(BoW) " 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": 21, 189 | "id": "8bbbcf00-5a8b-4d01-beb3-bd10332596af", 190 | "metadata": {}, 191 | "outputs": [ 192 | { 193 | "data": { 194 | "text/plain": [ 195 | "['wiederaufnahme der sitzungsperiode ich erkläre die am freitag dem 17',\n", 196 | " 'dezember unterbrochene sitzungsperiode des europäischen parlaments für wiederaufgenommen wünsche ihnen nochmals alles gute zum jahreswechsel und hoffe daß sie schöne ferien hatten',\n", 197 | " 'wie sie feststellen konnten ist der gefürchtete millenium bug nicht eingetreten']" 198 | ] 199 | }, 200 | "execution_count": 21, 201 | "metadata": {}, 202 | "output_type": "execute_result" 203 | } 204 | ], 205 | "source": [ 206 | "dataset[:3]" 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "execution_count": 23, 212 | "id": "8c8117fc-3746-4d00-858d-be07d99e7182", 213 | "metadata": {}, 214 | "outputs": [ 215 | { 216 | "data": { 217 | "text/plain": [ 218 | "array([[1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 219 | " 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 220 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 221 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 222 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 223 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 224 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 225 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 226 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 227 | " 0, 0],\n", 228 | " [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,\n", 229 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,\n", 230 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,\n", 231 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 232 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,\n", 233 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 234 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 235 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 236 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 237 | " 0, 0],\n", 238 | " [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,\n", 239 | " 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 240 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 241 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 242 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 243 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 244 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 245 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 246 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 247 | " 0, 0]])" 248 | ] 249 | }, 250 | "execution_count": 23, 251 | "metadata": {}, 252 | "output_type": "execute_result" 253 | } 254 | ], 255 | "source": [ 256 | "BoW[:3]" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "id": "78551ad2-4645-43fb-9c78-6ccfec416900", 263 | "metadata": {}, 264 | "outputs": [], 265 | "source": [] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "id": "93e179e3-18e4-4980-8968-5e284a59c99c", 270 | "metadata": {}, 271 | "source": [ 272 | "## N-gram\n", 273 | "Contiguous sequence of n items(characters,words,sub-words) from a given sample of text or speech, an N-gram language model predicts the probability of a given N-gram within any sequence of words. i.e. the possibility of 'python' being next term if given previous sequence as ['Natural', 'language','prcessing','in']\n", 274 | "\n", 275 | "P(w_n|w_1,w_2,w_3,...,w_{i-1}) = \\frac{w_1,w_2,w_3,...,w_i}{P(w_1,w_2,w_3,...,w_{i-1})}\n", 276 | "\n", 277 | "\\approx \\frac{w_1,w_2,w_3,...,w_n}{P(w_{i-n},w_{i-n+1},...,w_{n-1})}" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 26, 283 | "id": "b250cee5-dc76-4775-b30b-93e93289f6db", 284 | "metadata": {}, 285 | "outputs": [], 286 | "source": [ 287 | "import nltk\n", 288 | "from nltk import bigrams, trigrams\n", 289 | "from nltk.corpus import reuters\n", 290 | "from collections import defaultdict" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 38, 296 | "id": "da1202c9-5365-45d6-92a3-d04995303073", 297 | "metadata": {}, 298 | "outputs": [ 299 | { 300 | "name": "stdout", 301 | "output_type": "stream", 302 | "text": [ 303 | "Next Word: No prediction available\n" 304 | ] 305 | } 306 | ], 307 | "source": [ 308 | "# Join the lines into a single string\n", 309 | "text = ' '.join(lines)\n", 310 | "# Tokenize the text\n", 311 | "words = nltk.word_tokenize(text)\n", 312 | "# Create trigrams\n", 313 | "tri_grams = list(trigrams(words))\n", 314 | "\n", 315 | "# Build a trigram model\n", 316 | "model = defaultdict(lambda: defaultdict(lambda: 0))\n", 317 | "# Count frequency of co-occurrence\n", 318 | "for w1, w2, w3 in tri_grams:\n", 319 | " model[(w1, w2)][w3] += 1\n", 320 | "\n", 321 | "# Transform the counts into probabilities\n", 322 | "for w1_w2 in model:\n", 323 | " total_count = float(sum(model[w1_w2].values()))\n", 324 | " for w3 in model[w1_w2]:\n", 325 | " model[w1_w2][w3] /= total_count\n", 326 | "\n", 327 | "# Function to predict the next word\n", 328 | "def predict_next_word(w1, w2):\n", 329 | " next_word = model[w1, w2]\n", 330 | " if next_word:\n", 331 | " predicted_word = max(next_word, key=next_word.get) # Choose the most likely next word\n", 332 | " return predicted_word\n", 333 | " else:\n", 334 | " return \"No prediction available\"\n", 335 | "\n", 336 | "# Example usage\n", 337 | "print(\"Next Word:\", predict_next_word('Hund', 'läuft'))\n" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 36, 343 | "id": "2e8db58a-bcf3-4caf-b431-fe54936affe5", 344 | "metadata": {}, 345 | "outputs": [ 346 | { 347 | "name": "stdout", 348 | "output_type": "stream", 349 | "text": [ 350 | "Next Word: heart\n" 351 | ] 352 | } 353 | ], 354 | "source": [ 355 | "print(\"Next Word:\", predict_next_word('not', 'my'))" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": null, 361 | "id": "5ca4cb3e-9386-41c0-b017-8eb9ce02a216", 362 | "metadata": {}, 363 | "outputs": [], 364 | "source": [ 365 | "print(\"Next Word:\", predict_next_word('not', 'my'))" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": 41, 371 | "id": "60b74938-8d98-4e67-a579-2cd6a0a18179", 372 | "metadata": {}, 373 | "outputs": [ 374 | { 375 | "data": { 376 | "text/plain": [ 377 | "'(Die Sitzung wird um 10.50 Uhr geschlossen.)\\n'" 378 | ] 379 | }, 380 | "execution_count": 41, 381 | "metadata": {}, 382 | "output_type": "execute_result" 383 | } 384 | ], 385 | "source": [ 386 | "lines[-1]" 387 | ] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "id": "364d013e-fdb8-442a-9dea-bb1c763053d0", 392 | "metadata": {}, 393 | "source": [ 394 | "### TF-IDF (Term Frequency-Inverse Document Frequency)\n", 395 | "evaluate the importance of a word in a document relative to a collection of documents\n", 396 | "\n", 397 | "Term Frequency = numbers of term t appearing in document d/total terms in document d\n", 398 | "\n", 399 | "Inverse Document Frequency = log(total number of documents/number of documents containing term t)\n", 400 | "\n", 401 | "Common but irrelavent word such as 'in' and 'out' could have high TF, yet IDF alone can't reflect the importance of document specified terms (i.e. keyword in papers). TF-IDF balances common and rare words to highlight the most meaningful terms." 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": null, 407 | "id": "71725640-49b6-431a-9861-93ed3678ec30", 408 | "metadata": {}, 409 | "outputs": [], 410 | "source": [ 411 | "from sklearn.feature_extraction.text import TfidfVectorizer\n", 412 | "\n", 413 | "# assign documents\n", 414 | "d0 = 'Apples are fruits'\n", 415 | "d1 = 'Tomatoes are fruits'\n", 416 | "d2 = 'Tomatoes are also vegetables'\n", 417 | "\n", 418 | "# merge documents into a single corpus\n", 419 | "string = [d0, d1, d2]\n", 420 | "\n", 421 | "# get tf-df values\n", 422 | "tfidf = TfidfVectorizer()\n", 423 | "result = tfidf.fit_transform(string)" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "id": "73d531f1-a64e-484d-a66a-fb757cbd9444", 429 | "metadata": {}, 430 | "source": [ 431 | "the words 'apple','also' are highlighted because they only appear in one documents, and 'tomamtoes','fruits' are considered important because they are frequent yet not common" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 50, 437 | "id": "f6576c89-ee0d-4519-8d94-81a2264aef0f", 438 | "metadata": {}, 439 | "outputs": [ 440 | { 441 | "name": "stdout", 442 | "output_type": "stream", 443 | "text": [ 444 | "\n", 445 | "idf values:\n", 446 | "also : 1.6931471805599454\n", 447 | "apples : 1.6931471805599454\n", 448 | "are : 1.0\n", 449 | "fruits : 1.2876820724517808\n", 450 | "tomatoes : 1.2876820724517808\n", 451 | "vegetables : 1.6931471805599454\n" 452 | ] 453 | } 454 | ], 455 | "source": [ 456 | "print('\\nidf values:')\n", 457 | "for word, idf_value in zip(tfidf.get_feature_names_out(), tfidf.idf_):\n", 458 | " print(word, ':', idf_value)" 459 | ] 460 | }, 461 | { 462 | "cell_type": "markdown", 463 | "id": "f9bfc364-498e-497c-9894-7874e59b055f", 464 | "metadata": {}, 465 | "source": [ 466 | "form of output in tf-idf values: (ith document, jth word) tf-idf" 467 | ] 468 | }, 469 | { 470 | "cell_type": "code", 471 | "execution_count": 52, 472 | "id": "49f161f9-3846-4c5f-add1-f7035a1e97fe", 473 | "metadata": {}, 474 | "outputs": [ 475 | { 476 | "name": "stdout", 477 | "output_type": "stream", 478 | "text": [ 479 | "\n", 480 | "Word indexes:\n", 481 | "{'apples': 1, 'are': 2, 'fruits': 3, 'tomatoes': 4, 'also': 0, 'vegetables': 5}\n", 482 | "\n", 483 | "tf-idf value:\n", 484 | " (0, 3)\t0.5478321549274363\n", 485 | " (0, 2)\t0.4254405389711991\n", 486 | " (0, 1)\t0.7203334490549893\n", 487 | " (1, 4)\t0.6198053799406072\n", 488 | " (1, 3)\t0.6198053799406072\n", 489 | " (1, 2)\t0.48133416873660545\n", 490 | " (2, 5)\t0.5844829010200651\n", 491 | " (2, 0)\t0.5844829010200651\n", 492 | " (2, 4)\t0.444514311537431\n", 493 | " (2, 2)\t0.34520501686496574\n", 494 | "\n", 495 | "tf-idf values in matrix form:\n", 496 | "[[0. 0.72033345 0.42544054 0.54783215 0. 0. ]\n", 497 | " [0. 0. 0.48133417 0.61980538 0.61980538 0. ]\n", 498 | " [0.5844829 0. 0.34520502 0. 0.44451431 0.5844829 ]]\n" 499 | ] 500 | } 501 | ], 502 | "source": [ 503 | "# get indexing\n", 504 | "print('\\nWord indexes:')\n", 505 | "print(tfidf.vocabulary_)\n", 506 | "\n", 507 | "# display tf-idf values\n", 508 | "print('\\ntf-idf value:')\n", 509 | "print(result)\n", 510 | "\n", 511 | "# in matrix form\n", 512 | "print('\\ntf-idf values in matrix form:')\n", 513 | "print(result.toarray())" 514 | ] 515 | }, 516 | { 517 | "cell_type": "markdown", 518 | "id": "976989e7-22ba-49b9-8a1a-14dbf9a5ee12", 519 | "metadata": {}, 520 | "source": [ 521 | "# Embedding : trained representation models" 522 | ] 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "id": "d0244a58-a4d2-4d45-8bca-2e283a5a45b5", 527 | "metadata": {}, 528 | "source": [ 529 | "### Word2Vec\n", 530 | "trained through skip-gram or CBOW(continuous bag of words), a shallow network with 2 hidden layers. 'The dog is running'\n", 531 | "\n", 532 | "Skip-gram : predict the context with target words 'dog'>>'the''is''running'\n", 533 | "\n", 534 | "CBOW : predict target words with given window of context 'the' 'is' 'runing' >> 'dog'\n", 535 | "\n", 536 | "PROS : semantic representation, distributional pattern reflects semantic similarities, allows vector arithmetic\n", 537 | "\n", 538 | "Application : machine translation, text classification, sentiment analysis, and information retrieval" 539 | ] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "execution_count": 1, 544 | "id": "d526ab3e-0d4a-4cc5-8037-4d4156197ce6", 545 | "metadata": {}, 546 | "outputs": [], 547 | "source": [ 548 | "import gensim\n", 549 | "from gensim.models import Word2Vec\n", 550 | "from nltk.tokenize import sent_tokenize, word_tokenize\n", 551 | "import warnings\n", 552 | "warnings.filterwarnings(action='ignore')\n", 553 | " \n", 554 | " \n", 555 | "sample = open(\"alice.txt\")\n", 556 | "s = sample.read()\n", 557 | "f = s.replace(\"\\n\", \" \")\n", 558 | " \n", 559 | "data = []\n", 560 | "for i in sent_tokenize(f):\n", 561 | " temp = []\n", 562 | " for j in word_tokenize(i):\n", 563 | " temp.append(j.lower())\n", 564 | " data.append(temp)" 565 | ] 566 | }, 567 | { 568 | "cell_type": "code", 569 | "execution_count": 3, 570 | "id": "5f798c93-e635-4ea6-a7e2-6b02cebe2056", 571 | "metadata": {}, 572 | "outputs": [ 573 | { 574 | "name": "stdout", 575 | "output_type": "stream", 576 | "text": [ 577 | "Cosine similarity between 'alice' and 'wonderland' - CBOW : 0.98673964\n", 578 | "Cosine similarity between 'alice' and 'machines' - CBOW : 0.9174969\n" 579 | ] 580 | } 581 | ], 582 | "source": [ 583 | "# CBOW model\n", 584 | "model1 = gensim.models.Word2Vec(data, min_count=1,\n", 585 | " vector_size=100, window=5)\n", 586 | " \n", 587 | "print(\"Cosine similarity between 'alice' \" +\n", 588 | " \"and 'wonderland' - CBOW : \",\n", 589 | " model1.wv.similarity('alice', 'wonderland'))\n", 590 | " \n", 591 | "print(\"Cosine similarity between 'alice' \" +\n", 592 | " \"and 'machines' - CBOW : \",\n", 593 | " model1.wv.similarity('alice', 'machines'))\n", 594 | " " 595 | ] 596 | }, 597 | { 598 | "cell_type": "code", 599 | "execution_count": 5, 600 | "id": "63ce15d8-3af5-4543-93a4-2e5b3d705cea", 601 | "metadata": {}, 602 | "outputs": [ 603 | { 604 | "name": "stdout", 605 | "output_type": "stream", 606 | "text": [ 607 | "Cosine similarity between 'alice' and 'wonderland' - Skip Gram : 0.8623241\n", 608 | "Cosine similarity between 'alice' and 'machines' - Skip Gram : 0.87525654\n" 609 | ] 610 | } 611 | ], 612 | "source": [ 613 | "#Skip Gram model\n", 614 | "model2 = gensim.models.Word2Vec(data, min_count=1, vector_size=100,\n", 615 | " window=5, sg=1)\n", 616 | "\n", 617 | "print(\"Cosine similarity between 'alice' \" +\n", 618 | " \"and 'wonderland' - Skip Gram : \",\n", 619 | " model2.wv.similarity('alice', 'wonderland'))\n", 620 | " \n", 621 | "print(\"Cosine similarity between 'alice' \" +\n", 622 | " \"and 'machines' - Skip Gram : \",\n", 623 | " model2.wv.similarity('alice', 'machines'))\n" 624 | ] 625 | }, 626 | { 627 | "cell_type": "markdown", 628 | "id": "12b58f6c-9101-4f87-8faa-d98cbb11466e", 629 | "metadata": {}, 630 | "source": [ 631 | "### GloVe\n", 632 | "unsupervised learning using the statistical co-occurrence data of words in a given corpus, minimize the weighted distance between embedding and co-occurance matrix(seen as a possibility matrix)\n", 633 | "\n", 634 | "application : named entity recoginition, translation, semantic search, word analogy, word clustering" 635 | ] 636 | }, 637 | { 638 | "cell_type": "code", 639 | "execution_count": 11, 640 | "id": "9132a2c2-5a54-4e0d-9043-66d84c4cbda5", 641 | "metadata": {}, 642 | "outputs": [ 643 | { 644 | "name": "stdout", 645 | "output_type": "stream", 646 | "text": [ 647 | "Number of unique words in dictionary= 6\n", 648 | "Dictionary is = {'language': 1, 'text': 2, 'leader': 3, 'the': 4, 'prime': 5, 'natural': 6}\n", 649 | "Dense vector for first word is => [-5.79900026e-01 -1.10100001e-01 -1.15569997e+00 -2.99059995e-03\n", 650 | " -2.06129998e-01 4.52890009e-01 -1.66710004e-01 -1.03820002e+00\n", 651 | " -9.92410004e-01 3.98840010e-01 5.92299998e-01 2.29900002e-01\n", 652 | " 1.52129996e+00 -1.77640006e-01 -2.97259986e-01 -3.92349988e-01\n", 653 | " -7.84709990e-01 1.55939996e-01 6.90769970e-01 5.95369995e-01\n", 654 | " -4.43399996e-01 5.35139978e-01 3.28530014e-01 1.24370003e+00\n", 655 | " 1.29719996e+00 -1.38779998e+00 -1.09249997e+00 -4.09249991e-01\n", 656 | " -5.69710016e-01 -3.46560001e-01 3.71630001e+00 -1.04890001e+00\n", 657 | " -4.67079997e-01 -4.47389990e-01 6.22999994e-03 1.96490008e-02\n", 658 | " -4.01609987e-01 -6.29130006e-01 -8.25060010e-01 4.55909997e-01\n", 659 | " 8.26259971e-01 5.70909977e-01 2.11989999e-01 4.68650013e-01\n", 660 | " -6.00269973e-01 2.99199998e-01 6.79440022e-01 1.42379999e+00\n", 661 | " -3.21520008e-02 -1.26029998e-01]\n" 662 | ] 663 | } 664 | ], 665 | "source": [ 666 | "from tensorflow.keras.preprocessing.text import Tokenizer\n", 667 | "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", 668 | "import numpy as np\n", 669 | " \n", 670 | "x = {'text', 'the', 'leader', 'prime', 'natural', 'language'}\n", 671 | " \n", 672 | "# create the dict.\n", 673 | "tokenizer = Tokenizer()\n", 674 | "tokenizer.fit_on_texts(x)\n", 675 | " \n", 676 | "# number of unique words in dict.\n", 677 | "print(\"Number of unique words in dictionary=\", \n", 678 | " len(tokenizer.word_index))\n", 679 | "print(\"Dictionary is = \", tokenizer.word_index)\n", 680 | " \n", 681 | "# download glove and unzip it in Notebook.\n", 682 | "#!wget http://nlp.stanford.edu/data/glove.6B.zip\n", 683 | "#!unzip glove*.zip\n", 684 | " \n", 685 | "def embedding_for_vocab(filepath, word_index,\n", 686 | " embedding_dim):\n", 687 | " vocab_size = len(word_index) + 1\n", 688 | " \n", 689 | " # Adding again 1 because of reserved 0 index\n", 690 | " embedding_matrix_vocab = np.zeros((vocab_size,\n", 691 | " embedding_dim))\n", 692 | " \n", 693 | " with open(filepath, encoding=\"utf8\") as f:\n", 694 | " for line in f:\n", 695 | " word, *vector = line.split()\n", 696 | " if word in word_index:\n", 697 | " idx = word_index[word]\n", 698 | " embedding_matrix_vocab[idx] = np.array(\n", 699 | " vector, dtype=np.float32)[:embedding_dim]\n", 700 | " \n", 701 | " return embedding_matrix_vocab\n", 702 | " \n", 703 | "# matrix for vocab: word_index\n", 704 | "embedding_dim = 50\n", 705 | "embedding_matrix_vocab = embedding_for_vocab('glove/glove.6B.50d.txt', tokenizer.word_index,embedding_dim)\n", 706 | " \n", 707 | "print(\"Dense vector for first word is => \",embedding_matrix_vocab[1])" 708 | ] 709 | }, 710 | { 711 | "cell_type": "markdown", 712 | "id": "037bb3c0-f6d6-4450-81f3-4c7400419591", 713 | "metadata": {}, 714 | "source": [ 715 | "### fastText\n", 716 | "developed by Facebook's AI Research (FAIR) lab, instead of representing words as single entities, FastText breaks them down into smaller components called character n-grams. It's extension of word2Vec model, particularly useful for handling languages with rich morphology or for tasks where out-of-vocabulary words are common\n", 717 | "\n", 718 | "\"\" and \"\". all considered for 'basketball'" 719 | ] 720 | }, 721 | { 722 | "cell_type": "code", 723 | "execution_count": 13, 724 | "id": "fa746e85-8408-4ec8-9004-47521b11c9c5", 725 | "metadata": {}, 726 | "outputs": [ 727 | { 728 | "name": "stdout", 729 | "output_type": "stream", 730 | "text": [ 731 | "Most similar words to 'sunflower': [('response', 0.2742580771446228), ('time', 0.19048680365085602), ('computer', 0.18673823773860931), ('survey', 0.07351218163967133), ('system', 0.06112516671419144), ('interface', 0.03289278596639633), ('trees', 0.009829370304942131), ('human', -0.0001683309383224696), ('eps', -0.016743149608373642), ('user', -0.029780348762869835)]\n" 732 | ] 733 | } 734 | ], 735 | "source": [ 736 | "from gensim.models import FastText\n", 737 | "from gensim.test.utils import common_texts\n", 738 | "\n", 739 | "# Training FastText model\n", 740 | "corpus = common_texts\n", 741 | "model = FastText(sentences=corpus, vector_size=100, window=5, min_count=1, workers=4, sg=1)\n", 742 | "\n", 743 | "# Example usage: getting embeddings for a word\n", 744 | "word_embedding = model.wv['sunflower']\n", 745 | "similar_words = model.wv.most_similar('sunflower')\n", 746 | "print(\"Most similar words to 'sunflower':\", similar_words)" 747 | ] 748 | }, 749 | { 750 | "cell_type": "markdown", 751 | "id": "1dbe3279-5d7c-4a4b-8019-39051df91d96", 752 | "metadata": {}, 753 | "source": [ 754 | "## pre-trained embedding" 755 | ] 756 | }, 757 | { 758 | "cell_type": "markdown", 759 | "id": "40486d4c-2acb-4f78-abaa-20f148cdbb7f", 760 | "metadata": {}, 761 | "source": [ 762 | "### Embeddings from Language Models (ELMo)\n", 763 | "word vectors are calculated using a two-layer bidirectional language model (biLM). Using the complete sentence containing that word, ELMo captures the context of the word and can generate different embeddings for the same word used in a different context in different sentences." 764 | ] 765 | }, 766 | { 767 | "cell_type": "code", 768 | "execution_count": 11, 769 | "id": "89e09c63-d0f7-4295-83ab-ea297421d2c1", 770 | "metadata": {}, 771 | "outputs": [ 772 | { 773 | "data": { 774 | "image/jpeg": "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", 775 | "text/plain": [ 776 | "" 777 | ] 778 | }, 779 | "execution_count": 11, 780 | "metadata": {}, 781 | "output_type": "execute_result" 782 | } 783 | ], 784 | "source": [ 785 | "from IPython.display import Image\n", 786 | "Image(filename='biLM.jpg')" 787 | ] 788 | }, 789 | { 790 | "cell_type": "code", 791 | "execution_count": 16, 792 | "id": "83828987-8049-4346-8ef8-ad749ebbef1f", 793 | "metadata": {}, 794 | "outputs": [ 795 | { 796 | "name": "stdout", 797 | "output_type": "stream", 798 | "text": [ 799 | "Shape of the embeddings: (2, 6, 1024)\n", 800 | "Word embeddings for the word 'WATCH' in the first sentence:\n", 801 | "[ 0.54308295 -0.3439697 0.24777155 ... 0.652064 -0.75163364\n", 802 | " 0.6272552 ]\n", 803 | "Word embeddings for the word 'WATCH' in the second sentence:\n", 804 | "[-0.08213355 0.01050331 -0.01454124 ... 0.4870539 -0.5445795\n", 805 | " 0.52623993]\n" 806 | ] 807 | } 808 | ], 809 | "source": [ 810 | "import tensorflow as tf\n", 811 | "import tensorflow_hub as hub\n", 812 | "\n", 813 | "# Load the ELMo model from TensorFlow Hub\n", 814 | "elmo = hub.load(\"https://tfhub.dev/google/elmo/3\")\n", 815 | "\n", 816 | "# Example sentence (no need to split the sentence into words)\n", 817 | "sentences = [\n", 818 | " \"I love to watch TV\",\n", 819 | " \"I am wearing a wrist watch\"\n", 820 | "]\n", 821 | "\n", 822 | "# Convert the sentence to a tensor\n", 823 | "input_tensor = tf.constant(sentences)\n", 824 | "\n", 825 | "# Get the ELMo embeddings for the sentence\n", 826 | "embeddings = elmo.signatures['default'](input_tensor)['elmo']\n", 827 | "\n", 828 | "# The shape of the output embeddings will be [batch_size, sequence_length, embedding_dim]\n", 829 | "# You can get the embedding for each word in the sentence\n", 830 | "print(\"Shape of the embeddings:\", embeddings.shape)\n", 831 | "\n", 832 | "print(\"Word embeddings for the word 'WATCH' in the first sentence:\")\n", 833 | "print(embeddings[0][4].numpy()) # 4th index for the word \"watch\" in the first sentence\n", 834 | "\n", 835 | "print(\"Word embeddings for the word 'WATCH' in the second sentence:\")\n", 836 | "print(embeddings[1][5].numpy()) # 5th index for the word \"watch\" in the second sentence" 837 | ] 838 | }, 839 | { 840 | "cell_type": "markdown", 841 | "id": "58f882cc-8ccd-4f6f-aee0-5ffeaa72e979", 842 | "metadata": {}, 843 | "source": [ 844 | "### BERT(Bidirectional Encoder Representations from Transformers)\n", 845 | "Encoder only bidirection tranformer archetecture\n", 846 | "\n", 847 | "Pretraining : 1. Masked Language Model: guessing missing (masked) words, BERT adds a special layer on top of its learning system to make these guesses, focuses on missing words. 2. Next Sentence Prediction (NSP) : guessing if one sentence follows another\n", 848 | "\n", 849 | "Fine-tuning : supervised learning on labeled data" 850 | ] 851 | }, 852 | { 853 | "cell_type": "code", 854 | "execution_count": 19, 855 | "id": "6d4ad01d-29a3-4a34-99fd-2bce322f8031", 856 | "metadata": {}, 857 | "outputs": [ 858 | { 859 | "data": { 860 | "application/vnd.jupyter.widget-view+json": { 861 | "model_id": "8eec2d290efc4595bb9bbcffc9ded4b3", 862 | "version_major": 2, 863 | "version_minor": 0 864 | }, 865 | "text/plain": [ 866 | "tokenizer_config.json: 0%| | 0.00/49.0 [00:00\n", 341 | " bos_piece: \n", 342 | " eos_piece: \n", 343 | " pad_piece: \n", 344 | " unk_surface: ⁇ \n", 345 | " enable_differential_privacy: 0\n", 346 | " differential_privacy_noise_level: 0\n", 347 | " differential_privacy_clipping_threshold: 0\n", 348 | "}\n", 349 | "normalizer_spec {\n", 350 | " name: nmt_nfkc\n", 351 | " add_dummy_prefix: 1\n", 352 | " remove_extra_whitespaces: 1\n", 353 | " escape_whitespaces: 1\n", 354 | " normalization_rule_tsv: \n", 355 | "}\n", 356 | "denormalizer_spec {}\n", 357 | "trainer_interface.cc(353) LOG(INFO) SentenceIterator is not specified. Using MultiFileSentenceIterator.\n", 358 | "trainer_interface.cc(185) LOG(INFO) Loading corpus: de-en.txt\n", 359 | "trainer_interface.cc(147) LOG(INFO) Loaded 1000000 lines\n", 360 | "trainer_interface.cc(124) LOG(WARNING) Too many sentences are loaded! (1917286), which may slow down training.\n", 361 | "trainer_interface.cc(126) LOG(WARNING) Consider using --input_sentence_size= and --shuffle_input_sentence=true.\n", 362 | "trainer_interface.cc(129) LOG(WARNING) They allow to randomly sample sentences from the entire corpus.\n", 363 | "trainer_interface.cc(409) LOG(INFO) Loaded all 1917286 sentences\n", 364 | "trainer_interface.cc(425) LOG(INFO) Adding meta_piece: \n", 365 | "trainer_interface.cc(425) LOG(INFO) Adding meta_piece: \n", 366 | "trainer_interface.cc(425) LOG(INFO) Adding meta_piece: \n", 367 | "trainer_interface.cc(430) LOG(INFO) Normalizing sentences...\n", 368 | "trainer_interface.cc(539) LOG(INFO) all chars count=322814382\n", 369 | "trainer_interface.cc(550) LOG(INFO) Done: 99.9565% characters are covered.\n", 370 | "trainer_interface.cc(560) LOG(INFO) Alphabet size=78\n", 371 | "trainer_interface.cc(561) LOG(INFO) Final character coverage=0.999565\n", 372 | "trainer_interface.cc(592) LOG(INFO) Done! preprocessed 1917286 sentences.\n", 373 | "unigram_model_trainer.cc(265) LOG(INFO) Making suffix array...\n", 374 | "unigram_model_trainer.cc(269) LOG(INFO) Extracting frequent sub strings... node_num=171000070\n", 375 | "unigram_model_trainer.cc(312) LOG(INFO) Initialized 1000078 seed sentencepieces\n", 376 | "trainer_interface.cc(598) LOG(INFO) Tokenizing input sentences with whitespace: 1917286\n", 377 | "trainer_interface.cc(609) LOG(INFO) Done! 636628\n", 378 | "unigram_model_trainer.cc(602) LOG(INFO) Using 636628 sentences for EM training\n", 379 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=262286 obj=11.5537 num_tokens=1480006 num_tokens/piece=5.64272\n", 380 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=192464 obj=8.56834 num_tokens=1484136 num_tokens/piece=7.71124\n", 381 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=144182 obj=8.53139 num_tokens=1521601 num_tokens/piece=10.5533\n", 382 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=143918 obj=8.52441 num_tokens=1521914 num_tokens/piece=10.5749\n", 383 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=107917 obj=8.54047 num_tokens=1598786 num_tokens/piece=14.815\n", 384 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=107903 obj=8.53847 num_tokens=1598825 num_tokens/piece=14.8172\n", 385 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=80919 obj=8.56552 num_tokens=1688640 num_tokens/piece=20.8683\n", 386 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=80916 obj=8.56284 num_tokens=1688832 num_tokens/piece=20.8714\n", 387 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=60684 obj=8.60481 num_tokens=1793327 num_tokens/piece=29.5519\n", 388 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=60681 obj=8.60143 num_tokens=1793295 num_tokens/piece=29.5528\n", 389 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=45507 obj=8.66115 num_tokens=1909712 num_tokens/piece=41.9652\n", 390 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=45507 obj=8.65248 num_tokens=1909647 num_tokens/piece=41.9638\n", 391 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=34129 obj=8.73865 num_tokens=2036594 num_tokens/piece=59.6734\n", 392 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=34127 obj=8.73085 num_tokens=2036564 num_tokens/piece=59.676\n", 393 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=25595 obj=8.84363 num_tokens=2179325 num_tokens/piece=85.1465\n", 394 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=25594 obj=8.83303 num_tokens=2179339 num_tokens/piece=85.1504\n", 395 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=19194 obj=8.98148 num_tokens=2329866 num_tokens/piece=121.385\n", 396 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=19194 obj=8.95582 num_tokens=2330030 num_tokens/piece=121.394\n", 397 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=14395 obj=9.15899 num_tokens=2496081 num_tokens/piece=173.399\n", 398 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=14395 obj=9.12097 num_tokens=2496129 num_tokens/piece=173.403\n", 399 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=10796 obj=9.37226 num_tokens=2669939 num_tokens/piece=247.308\n", 400 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=10796 obj=9.32831 num_tokens=2670057 num_tokens/piece=247.319\n", 401 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=0 size=8800 obj=9.5417 num_tokens=2798452 num_tokens/piece=318.006\n", 402 | "unigram_model_trainer.cc(618) LOG(INFO) EM sub_iter=1 size=8800 obj=9.51506 num_tokens=2799060 num_tokens/piece=318.075\n", 403 | "trainer_interface.cc(687) LOG(INFO) Saving model: mymodel.model\n", 404 | "trainer_interface.cc(699) LOG(INFO) Saving vocabs: mymodel.vocab\n" 405 | ] 406 | } 407 | ], 408 | "source": [ 409 | "import sentencepiece as spm\n", 410 | "\n", 411 | "# Train a tokenizer on a corpus\n", 412 | "spm.SentencePieceTrainer.train(input=\"de-en.txt\", model_prefix=\"mymodel\", vocab_size=8000)\n", 413 | "sp = spm.SentencePieceProcessor(model_file=\"mymodel.model\")" 414 | ] 415 | }, 416 | { 417 | "cell_type": "code", 418 | "execution_count": 32, 419 | "id": "69f057dd-3da4-41a9-9d71-2ef9b991283e", 420 | "metadata": {}, 421 | "outputs": [ 422 | { 423 | "name": "stdout", 424 | "output_type": "stream", 425 | "text": [ 426 | "['▁Hel', 'lo', '▁wo', 'r', 'l', 'd', ',', '▁her', 'e', \"'\", 's', '▁an', '▁', 'ill', 'ust', 'r', 'ation', '▁', 'for', '▁', 'to', 'ken', 'iz', 'ation', '▁', 'wi', 'th', '▁B', 'P', 'E', '!']\n" 427 | ] 428 | } 429 | ], 430 | "source": [ 431 | "# Tokenize a sentence\n", 432 | "text = \"Hello world, here's an illustration for tokenization with BPE!\"\n", 433 | "tokens = sp.encode(text, out_type=str)\n", 434 | "print(tokens)" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": 34, 440 | "id": "287b4367-162f-496d-9b1c-d3b68a3f87c3", 441 | "metadata": {}, 442 | "outputs": [ 443 | { 444 | "name": "stdout", 445 | "output_type": "stream", 446 | "text": [ 447 | "Hello world, here's an illustration for tokenization with BPE!\n" 448 | ] 449 | } 450 | ], 451 | "source": [ 452 | "# Decode into sentence\n", 453 | "decoded_text = sp.decode(tokens)\n", 454 | "print(decoded_text)" 455 | ] 456 | }, 457 | { 458 | "cell_type": "markdown", 459 | "id": "c6ecee0e-455c-49dc-8509-8997826a33ba", 460 | "metadata": {}, 461 | "source": [ 462 | "# Lemmatization\n", 463 | "reduce words to base or root form" 464 | ] 465 | }, 466 | { 467 | "cell_type": "code", 468 | "execution_count": 1, 469 | "id": "f53e939b-2f76-4005-b86d-1d4bf24a03ce", 470 | "metadata": {}, 471 | "outputs": [ 472 | { 473 | "name": "stderr", 474 | "output_type": "stream", 475 | "text": [ 476 | "[nltk_data] Downloading package wordnet to /Users/xiao/nltk_data...\n", 477 | "[nltk_data] Downloading package omw-1.4 to /Users/xiao/nltk_data...\n" 478 | ] 479 | }, 480 | { 481 | "name": "stdout", 482 | "output_type": "stream", 483 | "text": [ 484 | "running\n", 485 | "run\n" 486 | ] 487 | } 488 | ], 489 | "source": [ 490 | "import nltk\n", 491 | "from nltk.stem import WordNetLemmatizer\n", 492 | "from nltk.corpus import wordnet\n", 493 | "\n", 494 | "# Download necessary NLTK resources\n", 495 | "nltk.download('wordnet')\n", 496 | "nltk.download('omw-1.4')\n", 497 | "\n", 498 | "lemmatizer = WordNetLemmatizer()\n", 499 | "\n", 500 | "# Lemmatize a word (default POS is noun)\n", 501 | "print(lemmatizer.lemmatize(\"running\")) # \"running\" → \"running\" (as noun by default)\n", 502 | "print(lemmatizer.lemmatize(\"running\", pos=wordnet.VERB)) # \"running\" → \"run\" (as verb)" 503 | ] 504 | }, 505 | { 506 | "cell_type": "code", 507 | "execution_count": 3, 508 | "id": "f8c12c41-2964-4375-90fa-dc36459901f4", 509 | "metadata": {}, 510 | "outputs": [ 511 | { 512 | "name": "stdout", 513 | "output_type": "stream", 514 | "text": [ 515 | "You -> you\n", 516 | "'re -> be\n", 517 | "looking -> look\n", 518 | "at -> at\n", 519 | "illustrations -> illustration\n", 520 | "for -> for\n", 521 | "tokenization -> tokenization\n", 522 | "with -> with\n", 523 | "SpaCy -> SpaCy\n", 524 | "! -> !\n" 525 | ] 526 | } 527 | ], 528 | "source": [ 529 | "import spacy\n", 530 | "\n", 531 | "# Load the pre-trained model for English\n", 532 | "nlp = spacy.load(\"en_core_web_sm\")\n", 533 | "# Sample sentence\n", 534 | "doc = nlp(\"You're looking at illustrations for tokenization with SpaCy!\")\n", 535 | "# Lemmatize each token in the sentence\n", 536 | "for token in doc:\n", 537 | " print(f\"{token.text} -> {token.lemma_}\")" 538 | ] 539 | }, 540 | { 541 | "cell_type": "markdown", 542 | "id": "3d5fe6ed-aaf1-4143-acc4-bb3a9aef8af9", 543 | "metadata": {}, 544 | "source": [ 545 | "# Stemming\n", 546 | "reduces words to root by removing suffixes.Porter/Lancaster/Snowball/Lovis/Rule-based stemmer\n", 547 | "\n", 548 | "Porter stemmer is moderate with regard to agressiveness, only support English\n", 549 | "\n", 550 | "Lancaster stemmer is the most agressive, only support English\n", 551 | "\n", 552 | "Snowball is modified upon Porter, moderately agressive, supports over 30 languages" 553 | ] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": 18, 558 | "id": "794f06e3-e52f-4e8f-a5c5-473a71ceb327", 559 | "metadata": {}, 560 | "outputs": [ 561 | { 562 | "name": "stderr", 563 | "output_type": "stream", 564 | "text": [ 565 | "[nltk_data] Downloading package punkt to /Users/xiao/nltk_data...\n", 566 | "[nltk_data] Package punkt is already up-to-date!\n" 567 | ] 568 | } 569 | ], 570 | "source": [ 571 | "import nltk\n", 572 | "from nltk.stem import PorterStemmer\n", 573 | "\n", 574 | "# Download necessary data from NLTK (if needed)\n", 575 | "nltk.download('punkt')\n", 576 | "\n", 577 | "# Sample sentence\n", 578 | "sentence = \"You're looking at illustrations for stemming with nltk!\"\n", 579 | "# Tokenize the sentence into words\n", 580 | "words = nltk.word_tokenize(sentence)" 581 | ] 582 | }, 583 | { 584 | "cell_type": "code", 585 | "execution_count": 20, 586 | "id": "c39a79f0-e78b-46fd-afe5-c264c42d2a27", 587 | "metadata": {}, 588 | "outputs": [ 589 | { 590 | "name": "stdout", 591 | "output_type": "stream", 592 | "text": [ 593 | "Original words: ['You', \"'re\", 'looking', 'at', 'illustrations', 'for', 'stemming', 'with', 'nltk', '!']\n", 594 | "Stemmed words: ['you', \"'re\", 'look', 'at', 'illustr', 'for', 'stem', 'with', 'nltk', '!']\n" 595 | ] 596 | } 597 | ], 598 | "source": [ 599 | "# PorterStemmer object\n", 600 | "stemmer = PorterStemmer()\n", 601 | "# Stem each word\n", 602 | "stemmed_words = [stemmer.stem(word) for word in words]\n", 603 | "\n", 604 | "# Print the results\n", 605 | "print(f\"Original words: {words}\")\n", 606 | "print(f\"Stemmed words: {stemmed_words}\")" 607 | ] 608 | }, 609 | { 610 | "cell_type": "code", 611 | "execution_count": 22, 612 | "id": "69a497fc-c950-4942-bdd6-c4e82462155f", 613 | "metadata": {}, 614 | "outputs": [ 615 | { 616 | "name": "stdout", 617 | "output_type": "stream", 618 | "text": [ 619 | "Stemmed words: ['you', \"'re\", 'look', 'at', 'illust', 'for', 'stem', 'with', 'nltk', '!']\n" 620 | ] 621 | } 622 | ], 623 | "source": [ 624 | "# LancasterStemmer\n", 625 | "from nltk.stem import LancasterStemmer\n", 626 | "lancaster_stemmer = LancasterStemmer()\n", 627 | "stemmed_words = [lancaster_stemmer.stem(word) for word in words]\n", 628 | "print(f\"Stemmed words: {stemmed_words}\")" 629 | ] 630 | }, 631 | { 632 | "cell_type": "code", 633 | "execution_count": 24, 634 | "id": "a87f7337-6baa-4273-9fd6-942dff120c11", 635 | "metadata": {}, 636 | "outputs": [ 637 | { 638 | "name": "stdout", 639 | "output_type": "stream", 640 | "text": [ 641 | "Stemmed words: ['you', 're', 'look', 'at', 'illustr', 'for', 'stem', 'with', 'nltk', '!']\n" 642 | ] 643 | } 644 | ], 645 | "source": [ 646 | "#SnowballStemmer\n", 647 | "from nltk.stem import SnowballStemmer\n", 648 | "snowball_stemmer = SnowballStemmer('english')\n", 649 | "stemmed_words = [snowball_stemmer.stem(word) for word in words]\n", 650 | "print(f\"Stemmed words: {stemmed_words}\")" 651 | ] 652 | }, 653 | { 654 | "cell_type": "markdown", 655 | "id": "9b592532-7807-4e99-9ae7-8b86b26e56e5", 656 | "metadata": {}, 657 | "source": [ 658 | "# Stopword removal\n", 659 | "remove common words" 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "execution_count": 30, 665 | "id": "eba8b8b2-f5ef-4b5b-8b08-729a75cf26e6", 666 | "metadata": {}, 667 | "outputs": [ 668 | { 669 | "name": "stderr", 670 | "output_type": "stream", 671 | "text": [ 672 | "[nltk_data] Downloading package punkt to /Users/xiao/nltk_data...\n", 673 | "[nltk_data] Package punkt is already up-to-date!\n", 674 | "[nltk_data] Downloading package stopwords to /Users/xiao/nltk_data...\n" 675 | ] 676 | }, 677 | { 678 | "name": "stdout", 679 | "output_type": "stream", 680 | "text": [ 681 | "Filtered Words: ['example', 'sentence', 'demonstrate', 'stopword', 'removal', '.']\n" 682 | ] 683 | }, 684 | { 685 | "name": "stderr", 686 | "output_type": "stream", 687 | "text": [ 688 | "[nltk_data] Unzipping corpora/stopwords.zip.\n" 689 | ] 690 | } 691 | ], 692 | "source": [ 693 | "import nltk\n", 694 | "from nltk.corpus import stopwords\n", 695 | "from nltk.tokenize import word_tokenize\n", 696 | "\n", 697 | "# Download the stopwords list (only needed once)\n", 698 | "nltk.download('punkt')\n", 699 | "nltk.download('stopwords')\n", 700 | "\n", 701 | "# Sample text\n", 702 | "text = \"This is an example sentence to demonstrate stopword removal.\"\n", 703 | "\n", 704 | "# Tokenize the text into words\n", 705 | "words = word_tokenize(text)\n", 706 | "\n", 707 | "# Get the list of stopwords in English\n", 708 | "stop_words = set(stopwords.words(\"english\"))\n", 709 | "\n", 710 | "# Remove stopwords from the tokenized words\n", 711 | "filtered_words = [word for word in words if word.lower() not in stop_words]\n", 712 | "\n", 713 | "print(\"Filtered Words:\", filtered_words)" 714 | ] 715 | }, 716 | { 717 | "cell_type": "code", 718 | "execution_count": 32, 719 | "id": "58500ea2-28f3-4bbe-b816-4823eeffd0e9", 720 | "metadata": {}, 721 | "outputs": [ 722 | { 723 | "name": "stdout", 724 | "output_type": "stream", 725 | "text": [ 726 | "Filtered Words: ['example', 'sentence', 'demonstrate', 'stopword', 'removal', '.']\n" 727 | ] 728 | } 729 | ], 730 | "source": [ 731 | "import spacy\n", 732 | "\n", 733 | "# Load the pre-trained model for English\n", 734 | "nlp = spacy.load(\"en_core_web_sm\")\n", 735 | "\n", 736 | "# Sample text\n", 737 | "text = \"This is an example sentence to demonstrate stopword removal.\"\n", 738 | "\n", 739 | "# Process the text with spaCy\n", 740 | "doc = nlp(text)\n", 741 | "\n", 742 | "# Filter out stopwords from the tokens\n", 743 | "filtered_words = [token.text for token in doc if not token.is_stop]\n", 744 | "\n", 745 | "print(\"Filtered Words:\", filtered_words)" 746 | ] 747 | }, 748 | { 749 | "cell_type": "markdown", 750 | "id": "7401bf7a-2762-491d-8b8c-d8cd197aad69", 751 | "metadata": {}, 752 | "source": [ 753 | "# Parts of speech tagging\n", 754 | "assigns a part of speech to each word in sentence based on definition and context." 755 | ] 756 | }, 757 | { 758 | "cell_type": "code", 759 | "execution_count": 26, 760 | "id": "0c1e3f5f-4e22-496d-a8ea-2ed9b12bb500", 761 | "metadata": {}, 762 | "outputs": [ 763 | { 764 | "name": "stdout", 765 | "output_type": "stream", 766 | "text": [ 767 | "You -> PRON\n", 768 | "'re -> AUX\n", 769 | "looking -> VERB\n", 770 | "at -> ADP\n", 771 | "illustrations -> NOUN\n", 772 | "for -> ADP\n", 773 | "POS -> PROPN\n", 774 | "tagging -> VERB\n", 775 | "with -> ADP\n", 776 | "Spacy -> PROPN\n", 777 | "! -> PUNCT\n" 778 | ] 779 | } 780 | ], 781 | "source": [ 782 | "import spacy\n", 783 | "\n", 784 | "# Load the pre-trained model for English\n", 785 | "nlp = spacy.load(\"en_core_web_sm\")\n", 786 | "\n", 787 | "# Sample sentence\n", 788 | "sentence = \"You're looking at illustrations for POS tagging with Spacy!\"\n", 789 | "\n", 790 | "# Process the sentence\n", 791 | "doc = nlp(sentence)\n", 792 | "\n", 793 | "# Display POS tags for each token\n", 794 | "for token in doc:\n", 795 | " print(f\"{token.text} -> {token.pos_}\")" 796 | ] 797 | }, 798 | { 799 | "cell_type": "code", 800 | "execution_count": 28, 801 | "id": "a56c06b2-89ba-4948-b9e6-f4f875756a1c", 802 | "metadata": {}, 803 | "outputs": [ 804 | { 805 | "name": "stderr", 806 | "output_type": "stream", 807 | "text": [ 808 | "[nltk_data] Downloading package punkt to /Users/xiao/nltk_data...\n", 809 | "[nltk_data] Package punkt is already up-to-date!\n", 810 | "[nltk_data] Downloading package averaged_perceptron_tagger to\n", 811 | "[nltk_data] /Users/xiao/nltk_data...\n" 812 | ] 813 | }, 814 | { 815 | "name": "stdout", 816 | "output_type": "stream", 817 | "text": [ 818 | "You -> PRP\n", 819 | "'re -> VBP\n", 820 | "looking -> VBG\n", 821 | "at -> IN\n", 822 | "illustrations -> NNS\n", 823 | "for -> IN\n", 824 | "POS -> NNP\n", 825 | "tagging -> VBG\n", 826 | "with -> IN\n", 827 | "nltk -> NN\n", 828 | "! -> .\n" 829 | ] 830 | }, 831 | { 832 | "name": "stderr", 833 | "output_type": "stream", 834 | "text": [ 835 | "[nltk_data] Unzipping taggers/averaged_perceptron_tagger.zip.\n" 836 | ] 837 | } 838 | ], 839 | "source": [ 840 | "import nltk\n", 841 | "from nltk.tokenize import word_tokenize\n", 842 | "\n", 843 | "# Download necessary NLTK data\n", 844 | "nltk.download('punkt')\n", 845 | "nltk.download('averaged_perceptron_tagger')\n", 846 | "\n", 847 | "# Sample sentence\n", 848 | "sentence = \"You're looking at illustrations for POS tagging with nltk!\"\n", 849 | "\n", 850 | "# Tokenize the sentence\n", 851 | "tokens = word_tokenize(sentence)\n", 852 | "\n", 853 | "# Perform POS tagging\n", 854 | "tags = nltk.pos_tag(tokens)\n", 855 | "\n", 856 | "# Display POS tags\n", 857 | "for word, tag in tags:\n", 858 | " print(f\"{word} -> {tag}\")" 859 | ] 860 | }, 861 | { 862 | "cell_type": "code", 863 | "execution_count": null, 864 | "id": "cec42e2a-f326-4d25-9ff0-b6a6c0766690", 865 | "metadata": {}, 866 | "outputs": [], 867 | "source": [] 868 | } 869 | ], 870 | "metadata": { 871 | "kernelspec": { 872 | "display_name": "Python 3 (ipykernel)", 873 | "language": "python", 874 | "name": "python3" 875 | }, 876 | "language_info": { 877 | "codemirror_mode": { 878 | "name": "ipython", 879 | "version": 3 880 | }, 881 | "file_extension": ".py", 882 | "mimetype": "text/x-python", 883 | "name": "python", 884 | "nbconvert_exporter": "python", 885 | "pygments_lexer": "ipython3", 886 | "version": "3.10.14" 887 | } 888 | }, 889 | "nbformat": 4, 890 | "nbformat_minor": 5 891 | } 892 | -------------------------------------------------------------------------------- /attention.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyanhui/Language-processing-basics/e361f95e89eb5bf8c33ee06d5c6562ba30811f24/attention.png -------------------------------------------------------------------------------- /biLM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyanhui/Language-processing-basics/e361f95e89eb5bf8c33ee06d5c6562ba30811f24/biLM.jpg -------------------------------------------------------------------------------- /transformers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "008cb64e-dc3c-4bf0-88c1-2639681fe897", 6 | "metadata": {}, 7 | "source": [ 8 | "## Attention\n", 9 | "The distribution between sentence parts. The rnn structure depend highly on the exact previous text, to emphasize the connection between context, we use a hidden state, attention.\n", 10 | "\n", 11 | "### Calculation\n", 12 | "How's the attention layer calculated:\n", 13 | "\n", 14 | "1. Set query(Q), key(K), value(V) vecters for each embedded token. $Q = X * W_Q$, $K = X * W_K$, $V = X * W_V$\n", 15 | "2. for each token i, calculate the score $softmax((q_i * k_j)/\\sqrt(d_k)) * v_j$, and sum the results for all j. d_k lowers the scale of first score(usually the dimension of key vector), softmax normalizes them, v_j ensures the values we want to focus stay intact\n", 16 | "\n", 17 | "The calculation here in matrix form is $Z = SoftMax(\\frac{QK^T}{\\sqrt(d_k)})V$\n", 18 | "\n", 19 | "### Multi-head attention\n", 20 | "splits up the controller states into chunks and operates the self attention on each chunk separately and then recombines with a fully connected network.\n", 21 | "\n", 22 | "![Multi-heads attention](attention.png)\n", 23 | "\n", 24 | "The picture here is from https://jalammar.github.io/illustrated-transformer/\n", 25 | "\n", 26 | "### Masked attention\n", 27 | "Attention shouldn't have access to text in time j at time i (if j > i), so the attentions reading from right to left are masked out with a casual masking matrix\n", 28 | "\n", 29 | "M_{casual} =\n", 30 | "\\begin{bmatrix}\n", 31 | "0 & -\\infty & -\\infty & -\\infty & -\\infty \\\\\n", 32 | "0 & 0 & -\\infty & -\\infty & -\\infty \\\\\n", 33 | "0 & 0 & 0 & -\\infty & -\\infty \\\\\n", 34 | "0 & 0 & 0 & 0 & -\\infty \\\\\n", 35 | "0 & 0 & 0 & 0 & 0 \\\\\n", 36 | "\\end{bmatrix}\n" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 10, 42 | "id": "8256d3ed-52ea-4ae9-aeed-f6d7c417fea8", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "def dot_product_attention(q, k, v, bias, dropout_rate=0.0):\n", 47 | " \"\"\"Dot-product attention.\n", 48 | "\n", 49 | " Args:\n", 50 | " q: Tensor with shape [..., length_q, depth_k].\n", 51 | " k: Tensor with shape [..., length_kv, depth_k]. Leading dimensions must\n", 52 | " match with q.\n", 53 | " v: Tensor with shape [..., length_kv, depth_v] Leading dimensions must\n", 54 | " match with q.\n", 55 | " bias: bias Tensor (see attention_bias())\n", 56 | " dropout_rate: a float.\n", 57 | "\n", 58 | " Returns:\n", 59 | " Tensor with shape [..., length_q, depth_v].\n", 60 | " \"\"\"\n", 61 | " logits = tf.matmul(q, k, transpose_b=True) # [..., length_q, length_kv]\n", 62 | " logits = tf.multiply(logits, 1.0 / math.sqrt(float(get_shape_list(q)[-1])))\n", 63 | " if bias is not None:\n", 64 | " # `attention_mask` = [B, T]\n", 65 | " from_shape = get_shape_list(q)\n", 66 | " if len(from_shape) == 4:\n", 67 | " broadcast_ones = tf.ones([from_shape[0], 1, from_shape[2], 1], tf.float32)\n", 68 | " elif len(from_shape) == 5:\n", 69 | " # from_shape = [B, N, Block_num, block_size, depth]#\n", 70 | " broadcast_ones = tf.ones([from_shape[0], 1, from_shape[2], from_shape[3],\n", 71 | " 1], tf.float32)\n", 72 | "\n", 73 | " bias = tf.matmul(broadcast_ones,\n", 74 | " tf.cast(bias, tf.float32), transpose_b=True)\n", 75 | "\n", 76 | " # Since attention_mask is 1.0 for positions we want to attend and 0.0 for\n", 77 | " # masked positions, this operation will create a tensor which is 0.0 for\n", 78 | " # positions we want to attend and -10000.0 for masked positions.\n", 79 | " adder = (1.0 - bias) * -10000.0\n", 80 | "\n", 81 | " # Since we are adding it to the raw scores before the softmax, this is\n", 82 | " # effectively the same as removing these entirely.\n", 83 | " logits += adder\n", 84 | " else:\n", 85 | " adder = 0.0\n", 86 | "\n", 87 | " attention_probs = tf.nn.softmax(logits, name=\"attention_probs\")\n", 88 | " attention_probs = dropout(attention_probs, dropout_rate)\n", 89 | " return tf.matmul(attention_probs, v)\n", 90 | " \n", 91 | "def attention_layer(from_tensor,\n", 92 | " to_tensor,\n", 93 | " attention_mask=None,\n", 94 | " num_attention_heads=1,\n", 95 | " query_act=None,\n", 96 | " key_act=None,\n", 97 | " value_act=None,\n", 98 | " attention_probs_dropout_prob=0.0,\n", 99 | " initializer_range=0.02,\n", 100 | " batch_size=None,\n", 101 | " from_seq_length=None,\n", 102 | " to_seq_length=None,\n", 103 | " use_einsum=True):\n", 104 | " \"\"\"Performs multi-headed attention from `from_tensor` to `to_tensor`.\n", 105 | "\n", 106 | " Args:\n", 107 | " from_tensor: float Tensor of shape [batch_size, from_seq_length,\n", 108 | " from_width].\n", 109 | " to_tensor: float Tensor of shape [batch_size, to_seq_length, to_width].\n", 110 | " attention_mask: (optional) int32 Tensor of shape [batch_size, seq_length].\n", 111 | " The values should be 1 or 0. The attention scores will effectively\n", 112 | " be set to -infinity for any positions in the mask that are 0, and\n", 113 | " will be unchanged for positions that are 1.\n", 114 | " num_attention_heads: int. Number of attention heads.\n", 115 | " query_act: (optional) Activation function for the query transform.\n", 116 | " key_act: (optional) Activation function for the key transform.\n", 117 | " value_act: (optional) Activation function for the value transform.\n", 118 | " attention_probs_dropout_prob: (optional) float. Dropout probability of the\n", 119 | " attention probabilities.\n", 120 | " initializer_range: float. Range of the weight initializer.\n", 121 | " batch_size: (Optional) int. If the input is 2D, this might be the batch size\n", 122 | " of the 3D version of the `from_tensor` and `to_tensor`.\n", 123 | " from_seq_length: (Optional) If the input is 2D, this might be the seq length\n", 124 | " of the 3D version of the `from_tensor`.\n", 125 | " to_seq_length: (Optional) If the input is 2D, this might be the seq length\n", 126 | " of the 3D version of the `to_tensor`.\n", 127 | " use_einsum: bool. Whether to use einsum or reshape+matmul for dense layers\n", 128 | "\n", 129 | " Returns:\n", 130 | " float Tensor of shape [batch_size, from_seq_length, num_attention_heads,\n", 131 | " size_per_head].\n", 132 | "\n", 133 | " Raises:\n", 134 | " ValueError: Any of the arguments or tensor shapes are invalid.\n", 135 | " \"\"\"\n", 136 | " from_shape = get_shape_list(from_tensor, expected_rank=[2, 3])\n", 137 | " to_shape = get_shape_list(to_tensor, expected_rank=[2, 3])\n", 138 | " size_per_head = int(from_shape[2]/num_attention_heads)\n", 139 | "\n", 140 | " if len(from_shape) != len(to_shape):\n", 141 | " raise ValueError(\n", 142 | " \"The rank of `from_tensor` must match the rank of `to_tensor`.\")\n", 143 | "\n", 144 | " if len(from_shape) == 3:\n", 145 | " batch_size = from_shape[0]\n", 146 | " from_seq_length = from_shape[1]\n", 147 | " to_seq_length = to_shape[1]\n", 148 | " elif len(from_shape) == 2:\n", 149 | " if (batch_size is None or from_seq_length is None or to_seq_length is None):\n", 150 | " raise ValueError(\n", 151 | " \"When passing in rank 2 tensors to attention_layer, the values \"\n", 152 | " \"for `batch_size`, `from_seq_length`, and `to_seq_length` \"\n", 153 | " \"must all be specified.\")\n", 154 | "\n", 155 | " # Scalar dimensions referenced here:\n", 156 | " # B = batch size (number of sequences)\n", 157 | " # F = `from_tensor` sequence length\n", 158 | " # T = `to_tensor` sequence length\n", 159 | " # N = `num_attention_heads`\n", 160 | " # H = `size_per_head`\n", 161 | "\n", 162 | " # `query_layer` = [B, F, N, H]\n", 163 | " q = dense_layer_3d(from_tensor, num_attention_heads, size_per_head,\n", 164 | " create_initializer(initializer_range), query_act,\n", 165 | " use_einsum, \"query\")\n", 166 | "\n", 167 | " # `key_layer` = [B, T, N, H]\n", 168 | " k = dense_layer_3d(to_tensor, num_attention_heads, size_per_head,\n", 169 | " create_initializer(initializer_range), key_act,\n", 170 | " use_einsum, \"key\")\n", 171 | " # `value_layer` = [B, T, N, H]\n", 172 | " v = dense_layer_3d(to_tensor, num_attention_heads, size_per_head,\n", 173 | " create_initializer(initializer_range), value_act,\n", 174 | " use_einsum, \"value\")\n", 175 | " q = tf.transpose(q, [0, 2, 1, 3])\n", 176 | " k = tf.transpose(k, [0, 2, 1, 3])\n", 177 | " v = tf.transpose(v, [0, 2, 1, 3])\n", 178 | " if attention_mask is not None:\n", 179 | " attention_mask = tf.reshape(\n", 180 | " attention_mask, [batch_size, 1, to_seq_length, 1])\n", 181 | " # 'new_embeddings = [B, N, F, H]'\n", 182 | " new_embeddings = dot_product_attention(q, k, v, attention_mask,\n", 183 | " attention_probs_dropout_prob)\n", 184 | "\n", 185 | " return tf.transpose(new_embeddings, [0, 2, 1, 3])\n", 186 | " " 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "id": "9f5fce83-6ad3-4f24-843e-06af60b87c2e", 192 | "metadata": {}, 193 | "source": [ 194 | "## Transformers\n", 195 | "\n", 196 | "Transformers are a multi-layer neural attention model\n", 197 | "\n", 198 | "General transformer models: BERT, ALBERT, RoBERTa(robust optimized BERT), DistilBERT, ELECTRA, XLM / XLM-RoBERTa(cross-lingual), GPT, etc.\n", 199 | "\n", 200 | "![Bert](BERT.png)\n", 201 | "this picture is from https://huggingface.co/blog/bert-101#3-bert-model-size--architecture" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": null, 207 | "id": "0e580605-1fd6-479b-b374-d598ade23277", 208 | "metadata": {}, 209 | "outputs": [], 210 | "source": [] 211 | } 212 | ], 213 | "metadata": { 214 | "kernelspec": { 215 | "display_name": "Python 3 (ipykernel)", 216 | "language": "python", 217 | "name": "python3" 218 | }, 219 | "language_info": { 220 | "codemirror_mode": { 221 | "name": "ipython", 222 | "version": 3 223 | }, 224 | "file_extension": ".py", 225 | "mimetype": "text/x-python", 226 | "name": "python", 227 | "nbconvert_exporter": "python", 228 | "pygments_lexer": "ipython3", 229 | "version": "3.12.4" 230 | } 231 | }, 232 | "nbformat": 4, 233 | "nbformat_minor": 5 234 | } 235 | --------------------------------------------------------------------------------