{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-08T06:53:39.722807Z","iopub.execute_input":"2022-01-08T06:53:39.723115Z","iopub.status.idle":"2022-01-08T06:53:39.73252Z","shell.execute_reply.started":"2022-01-08T06:53:39.723086Z","shell.execute_reply":"2022-01-08T06:53:39.731712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Họ và tên: Nguyễn Mạnh Hưng  \nMSSV: 19021295  \nLớp: INT3405E 20\nGiáo viên hướng dẫn: Trần Quốc Long","metadata":{}},{"cell_type":"markdown","source":"### TABLE OF CONTENTS\n#### 1. Mô tả bài toán và đọc dữ liệu\n#### 2. Phân tích dữ liệu\n#### 3. Khởi tạo các hàm xử lý và train, validate dữ liệu\n#### 4. Thực thi các hàm xử lý dữ liệu\n#### 5. Dự đoán đầu ra trên test.csv","metadata":{}},{"cell_type":"markdown","source":"### 1. Mô tả bài toán và đọc dữ liệu","metadata":{}},{"cell_type":"markdown","source":"#### **Mô tả bài toán**: Đây là bài toán thuộc nhóm bài toán phân lớp, với đầu vào là một câu hỏi, đầu ra là 1 nếu câu hỏi đó là spam và 1 là ngược lại","metadata":{}},{"cell_type":"markdown","source":"#### Đọc dữ liệu từ file train.csv và test.csv","metadata":{}},{"cell_type":"code","source":"data = pd.read_csv('/kaggle/input/quora-insincere-questions-classification/train.csv')\nprint(data.head())\ntest_data = pd.read_csv('/kaggle/input/quora-insincere-questions-classification/test.csv')\nprint(test_data.head())\n","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:53:39.734511Z","iopub.execute_input":"2022-01-08T06:53:39.735256Z","iopub.status.idle":"2022-01-08T06:53:45.39544Z","shell.execute_reply.started":"2022-01-08T06:53:39.735217Z","shell.execute_reply":"2022-01-08T06:53:45.394632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 2. Phân tích dữ liệu:\n#### File csv gồm có 3 cột:  \n**Cột qid:** Mã câu hỏi   \n**Cột question_text:** Nội dung câu hỏi  \n**Cột target:** Nhãn câu hỏi được phân loại  \n","metadata":{}},{"cell_type":"code","source":"import torch\nfrom torch import nn\nimport re\nimport nltk\n","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:53:45.396548Z","iopub.execute_input":"2022-01-08T06:53:45.396793Z","iopub.status.idle":"2022-01-08T06:53:48.071467Z","shell.execute_reply.started":"2022-01-08T06:53:45.396757Z","shell.execute_reply":"2022-01-08T06:53:48.070657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 3. Thiết lập các hàm:\n* Xử lý dữ liệu\n* Tạo dictionary\n* Khởi tạo mô hình\n* Chuyển đổi dữ liệu thành dataset\n* Huấn luyện và đánh giá mô hình","metadata":{}},{"cell_type":"markdown","source":"#### **Hàm thực hiện tiền xử lý dữ liệu, bao gồm:**\n* Loại bỏ số  \n* Loại bỏ các dấu câu\n* Loại bỏ URL  \n* Loại bỏ emoji, symbol, icon  \n* Chuyển tất cả các chữ viết hoa về viết thường  \n* Tách từ, sử dụng thư viện nltk","metadata":{}},{"cell_type":"code","source":"\ndef _preprocess(list_sentence):\n    \n    # remove URL\n    \n    URL = r'http\\S+'\n    for i in range(len(list_sentence)):\n        list_sentence[i] = re.sub(URL, ' ', list_sentence[i])\n        \n    # remove emoji, icon, symbol\n    \n    emoji_pattern = re.compile(\"[\"\n                           u\"\\U0001F600-\\U0001F64F\"  # emoticons\n                           u\"\\U0001F300-\\U0001F5FF\"  # symbols & pictographs\n                           u\"\\U0001F680-\\U0001F6FF\"  # transport & map symbols\n                           u\"\\U0001F1E0-\\U0001F1FF\"  # flags (iOS)\n                           u\"\\U00002702-\\U000027B0\"\n                           u\"\\U000024C2-\\U0001F251\"\n                           \"]+\", flags=re.UNICODE)\n    for i in range(len(list_sentence)):\n        list_sentence[i] = emoji_pattern.sub(r' ', list_sentence[i])\n        \n    # remove punctuation and number\n    \n    punc = r'[0-9\\.\\,\\?\\!\\(\\)\\*\\^\\\"\\;\\:\\<\\>\\/\\\\\\-\\+\\=]+'\n    for i in range(len(list_sentence)):\n        list_sentence[i] = re.sub(punc, ' ', list_sentence[i])\n    \n    # remove duplicate space\n    list_set = []\n    for sen in list_sentence:\n        list_set.append(sen.split(' '))\n\n    print('step 1 completed')\n    list_set1 = []\n    for i in range(len(list_set)):\n        _set = []\n        for j in range(len(list_set[i])):\n            if list_set[i][j] != '':\n                _set.append(list_set[i][j])\n        list_set1.append(_set)\n\n    list_set = list_set1.copy()\n    list_sentence = []\n\n    for _set in list_set:\n        list_sentence.append(' '.join(_set))\n    \n    # lower sentence\n    \n    for i in range(len(list_sentence)):\n        list_sentence[i] = list_sentence[i].lower()\n    # segment word\n    \n    list_seq = []\n    for sen in list_sentence:\n        list_seq.append(nltk.word_tokenize(sen))\n    \n    return list_seq","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:53:48.073466Z","iopub.execute_input":"2022-01-08T06:53:48.073727Z","iopub.status.idle":"2022-01-08T06:53:48.084756Z","shell.execute_reply.started":"2022-01-08T06:53:48.073692Z","shell.execute_reply":"2022-01-08T06:53:48.083728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Các hàm xây dựng bộ từ vựng dựa trên các từ tách được trong file train và test.csv, sau đó tiền hành đánh số các từ trong các câu mới được tách dựa trên vị trí các từ trong tập từ điển","metadata":{}},{"cell_type":"code","source":"def count_word(list_seq):\n    list_vocab = []\n    for seq in list_seq:\n        list_vocab.extend(seq)\n    list_vocab = sorted(set(list_vocab))\n    fre_word = {}\n    for word in list_vocab:\n        fre_word[word] = 0\n    for seq in list_seq:\n        for word in seq:\n            fre_word[word] += 1\n    return fre_word\n\n\ndef create_vocab(fre_word, vocab_size=70000):\n    sort_word = sorted(fre_word, key=fre_word.get)\n    dict_word = {}\n    dict_word['[unk]'] = 0\n    index = 1\n    for i in range(len(sort_word) - vocab_size + 1, len(sort_word)):\n        dict_word[sort_word[i]] = index\n        index += 1\n    return dict_word\n\n\ndef index(word, dict_word):\n    if word in dict_word.keys():\n        return dict_word[word]\n    return dict_word['[unk]']\n\ndef word_to_index(list_seq, dict_word):\n    list_index = []\n    for seq in list_seq:\n        set_index = []\n        for word in seq:\n            set_index.append(index(word, dict_word))\n        list_index.append(set_index)\n    return list_index","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:32:45.272943Z","iopub.execute_input":"2022-01-07T15:32:45.273236Z","iopub.status.idle":"2022-01-07T15:32:45.284302Z","shell.execute_reply.started":"2022-01-07T15:32:45.273202Z","shell.execute_reply":"2022-01-07T15:32:45.283386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Hàm thực hiện loại bỏ các câu bị rỗng sau khi tiền xử lý","metadata":{}},{"cell_type":"code","source":"def remove_empty(list_seq, list_label):\n    new_seqs = []\n    new_labels = []\n    for i in range(len(list_seq)):\n        if len(list_seq[i]) > 0:\n            new_seqs.append(list_seq[i])\n            new_labels.append(list_label[i])\n\n    return [new_seqs, new_labels]","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:53:48.086313Z","iopub.execute_input":"2022-01-08T06:53:48.086589Z","iopub.status.idle":"2022-01-08T06:53:48.097805Z","shell.execute_reply.started":"2022-01-08T06:53:48.086544Z","shell.execute_reply":"2022-01-08T06:53:48.097078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Tiền hành chuyển dữ liệu đọc được thành các list để tiện xử lý","metadata":{}},{"cell_type":"code","source":"\n\n\nlist_sentence = []\nfor i in range(len(data)):\n    list_sentence.append(str(data['question_text'].loc[i]))\n\n\nlist_label = []\nfor i in range(len(data)):\n    list_label.append(float(data['target'].loc[i]))\n    \ntest_sentence = []\nfor i in range(len(test_data)):\n    test_sentence.append(str(test_data['question_text'].loc[i]))","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:53:48.099301Z","iopub.execute_input":"2022-01-08T06:53:48.099644Z","iopub.status.idle":"2022-01-08T06:54:37.294488Z","shell.execute_reply.started":"2022-01-08T06:53:48.099608Z","shell.execute_reply":"2022-01-08T06:54:37.29377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Tiền hành định lượng phân bố số lượng các câu theo các nhãn tương ứng trong tập train.csv","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\ncount0 = 0\ncount1 = 0\nfor label in list_label:\n    if int(label) == 0:\n        count0 += 1\n    else: count1 += 1\nprint('So luong nhan 0 la ', count0)\nprint('So luong nhan 1 la ', count1)\n\nleft = [1, 2]\n\n# heights of bars\nheight = [count0, count1]\n \n# labels for bars\ntick_label = [0, 1]\n \n# plotting a bar chart\nplt.bar(left, height, tick_label = tick_label,\n        width = 0.8, color = ['red', 'green'])\n \n# naming the x-axis\nplt.xlabel('label')\n# naming the y-axis\nplt.ylabel('the quantities')\n# plot title\nplt.title('Number each label in the orgin dataset')\n \n# function to show the plot\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:54:37.295656Z","iopub.execute_input":"2022-01-08T06:54:37.296281Z","iopub.status.idle":"2022-01-08T06:54:37.988401Z","shell.execute_reply.started":"2022-01-08T06:54:37.296244Z","shell.execute_reply":"2022-01-08T06:54:37.987655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Nhìn vào đồ thị có thể thấy được label 1 chỉ chiếm 6 % tổng số nhãn trong cả tập train data, điều này khiến mô hình bị imbalanced nặng, cái mà khiến mô hình dễ bias với các nhãn còn lại. Do đó, cần phải tìm cách khắc phục vấn đề này.  \nCó hai loại phương pháp cơ bản nhằm giải quyết vấn đề này, đó là oversampling và undersampling.Thực chất hai phương pháp vừa kể chỉ đơn giản là bồi thêm dữ liệu ở nhãn ít hơn hay cắt bớt giữ lieuj ở nhãn cao hơn sao cho lương dữ liệu ở các nhãn là như nhau. Ở đây, tôi sẽ tiến hành phương pháp undersampling, được thực hiện qua hàm _create_dataset.  \nTại hàm _create_dataset, tôi sẽ cắt bớt dữ liệu ở nhãn 0 một cách ngẫu nhiên, giữ lại một lượng dữ liệu ngang với lương dữ liệu ở label 1. Sau đó gộp hai dữ liệu label 0 mới và dữ liệu label 1 thành tập data để tiến hành training và testing. ","metadata":{}},{"cell_type":"markdown","source":"#### Khởi tạo mô hình mạng nơ-ron theo cách tiếp cận của lớp encoder của transformer, với 8 đầu multi-head attentions.","metadata":{}},{"cell_type":"code","source":"\nimport math\n#initialize transformer class\nclass self_transformer(nn.Module):\n        def __init__(self, input_dim, output_dim):\n            super(self_transformer, self).__init__()\n            self.linear1 = nn.Linear(input_dim, output_dim)\n            self.linear2 = nn.Linear(input_dim, output_dim)\n            self.linear3 = nn.Linear(input_dim, output_dim)\n            self.softmax = nn.Softmax(-1)\n        def forward(self, _input, output_dim):\n            question = self.linear1(_input) # 30x64\n            key = self.linear2(_input) # 30x64\n            value = self.linear3(_input) # 30x64\n            self_attention_ = torch.matmul(key, torch.transpose(question, - 2, -1))/math.sqrt(output_dim)# 30x30\n            self_attention = self.softmax(self_attention_) # 30x30\n            # print(self_attention.shape)\n            self_output = torch.matmul(self_attention, value)\n            # print(self_output.shape)\n            return self_output\n\nclass multi_head_transformer(nn.Module):\n    def __init__(self, input_dim, output_dim, num_class):\n        super(multi_head_transformer, self).__init__()\n        self.linear = []\n        for i in range(num_class):\n            self.linear.append(nn.Linear(input_dim, output_dim))\n    def forward(self, multi,output_dim):\n        result = 0.0\n        for i in range(len(multi)):\n            result += self.linear[i](multi[i])\n        result = torch.flatten(result, start_dim=-2)\n        result = result.mean(-1)\n        result = torch.sigmoid(result)\n        return result\n\n\ndef transform(_input, model_1, model_2, output_dim_encode,output_dim_decode):\n    encoders = []\n    for i in range(0, 8):\n        encoders.append(model_1[i](_input, output_dim_encode))\n    decoder = model_2(encoders, output_dim_decode)\n    return decoder\n\n","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:54:37.989849Z","iopub.execute_input":"2022-01-08T06:54:37.990313Z","iopub.status.idle":"2022-01-08T06:54:38.004137Z","shell.execute_reply.started":"2022-01-08T06:54:37.990269Z","shell.execute_reply":"2022-01-08T06:54:38.003335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Tạo các hàm để tiến hành chuyển các feature, label thành các dataset để tiến hành đưa vào mô hình, trong đó:\n* Hàm padding tiến hành đưa các features về cùng kích cỡ chiều dài  \n* Hàm create_pos tạo ma trận position encoding, giúp biểu thị ý nghĩa về vị trí các từ trong câu của các features  \n* Hàm process_data_to_input sẽ nhúng các feature, sử dụng hàm nhúng word2vec kết hợp với position embedding vừa kể trên  \n* Hàm create_transformer_model sẽ khởi tạo các tham số cần thiết của mô hình traing, gôm tạo mạng neuron, các hàm mất mát cũng như hàm tính toán xuống đồi  \n* Hàm split_dataset sẽ tiến hành chia dataset thành tập train và tập validation một cách ngẫu nhiên theo một tỉ lệ nhất định  \n* Hàm train_and_validation sẽ tiến hành training và sau đó sẽ tính toán accuarcy trên tập validation","metadata":{}},{"cell_type":"code","source":"\nfrom keras.preprocessing.sequence import pad_sequences\nfrom torch import nn\nimport random\nimport math\nfrom torch.utils.data import *\n\n\n#initialize some parameter for padding\n\ndef padding(list_seq, max_len):\n    return torch.from_numpy(pad_sequences(sequences=list_seq, maxlen=max_len))\n\n\n#processing pads into input before putting in transformer models\n\n\ndef create_pos(length, embed_dim=24):\n    position_encode = torch.zeros((length, embed_dim))\n    for i in range(length):\n        for j in range(embed_dim):\n            if j % 2 == 1:\n                position_encode[i][j] = math.sin(float(i+1)/10000**(float(j+1)/embed_dim))\n            else:\n                position_encode[i][j] = math.cos(float(i+1)/10000**(float(j)/embed_dim))\n    return position_encode\n\n\ndef process_data_to_input(data, embed_model, max_len):\n    return embed_model(data) + create_pos(max_len)\n \n \ndef create_transform_model(vocab_size, embed_dim):    \n    model_1 = []\n    for i in range(8):\n        model_1.append(self_transformer(input_dim=embed_dim, output_dim = 24))\n    model_2 = multi_head_transformer(input_dim = 24, output_dim=embed_dim, num_class=8)\n    embed_model = nn.Embedding(num_embeddings=vocab_size, embedding_dim=embed_dim)\n    \n    criterion = nn.L1Loss()\n    \n\n\n\n    optimizer = torch.optim.Adam([{'params':model_1[0].parameters()}, \n                                {'params':model_1[1].parameters()}, \n                                {'params':model_1[2].parameters()}, \n                                {'params':model_1[3].parameters()}, \n                                {'params':model_1[4].parameters()}, \n                                {'params':model_1[5].parameters()}, \n                                {'params':model_1[6].parameters()}, \n                                {'params':model_1[7].parameters()}, \n                                {'params':embed_model.parameters()},\n                                {'params':model_2.parameters()}], lr=0.00108)\n    \n    return [model_1, model_2, embed_model, criterion, optimizer]\n\n\n\n\ndef create_dataset(_input, label):\n    return [TensorDataset(_input, label), label.shape[0]]\n    # processed data\n\ndef _create_dataset(feature, label):\n    po_feature = []\n    ne_feature = []\n    po_label = []\n    ne_label = []\n    for i in range(feature.shape[0]):\n        if int(label[i]) == 0:\n            ne_feature.append(feature[i].unsqueeze(0))\n            ne_label.append(label[i].unsqueeze(0))\n        else:\n            po_feature.append(feature[i].unsqueeze(0))\n            po_label.append(label[i].unsqueeze(0))\n    min_count = min(len(ne_label), len(po_label))\n    print(min_count)\n\n    random_po = random.sample(range(0, len(po_label)), min_count)\n    random_ne = random.sample(range(0, len(ne_label)), min_count)\n\n    new_feature = []\n    new_label = []\n\n    for i in range(2*min_count):\n        if i % 2 == 0:\n            new_feature.append(po_feature[random_po[int(i/2)]])\n            new_label.append(po_label[random_po[int(i/2)]])\n        else:\n            new_feature.append(ne_feature[random_ne[int((i-1)/2)]])\n            new_label.append(ne_label[random_ne[int((i-1)/2)]])\n    new_feature = torch.cat(new_feature)\n    new_label = torch.cat(new_label)\n    print(new_feature.shape)\n    print(new_label.shape)\n\n    return [TensorDataset(new_feature, new_label), 2*min_count]\n\n\ndef split_dataset(data, data_size, percentage_attr):\n    train_size = int(data_size * percentage_attr)\n    test_size = data_size - train_size\n    input_train, input_test = random_split(data, [train_size, test_size])\n    train_loader = DataLoader(input_train.dataset, batch_size=16, shuffle=True)\n    test_loader = DataLoader(input_test.dataset, batch_size=16, shuffle=False)\n    return [train_loader, test_loader]\n\ndef train_and_validation(train_loader, test_loader, model_1, model_2, optimizer, criterion, encode_dim=24, decode_dim=16, num_epochs = 10):\n    validation_acc = []\n    for epoch in range(num_epochs):\n        for i, mini_data in enumerate(train_loader):\n            inputs, labels = mini_data\n            embed_layer = process_data_to_input(inputs, embed_model, padding_size)\n            optimizer.zero_grad()\n            outputs = transform(embed_layer, model_1, model_2, output_dim_encode=encode_dim, output_dim_decode=decode_dim)\n            \n            loss = criterion(outputs, labels)\n            loss.backward(retain_graph=True)\n            optimizer.step()\n            # print('hello')\n\n            if i % 300 == 0:\n                print(loss.data)\n            \n        print('complete epoch ' + str(epoch) +' completed')\n            \n        count = 0\n        total_count = 0    \n        for i, mini_data in enumerate(test_loader):\n            \n            inputs, labels = mini_data\n            embed_layer = process_data_to_input(inputs, embed_model, padding_size)\n            outputs = transform(embed_layer, model_1, model_2, output_dim_encode=encode_dim, output_dim_decode=decode_dim)\n            for j in range(outputs.shape[0]):\n                total_count += 1\n                if abs(outputs[j].data - labels[j].data) < 0.5:\n                    count += 1\n        \n        validation_acc.append(count/total_count)\n    predict_labels = []\n    real_labels = []\n    for i, mini_data in enumerate(test_loader):\n        \n        inputs, labels = mini_data\n        embed_layer = process_data_to_input(inputs, embed_model, padding_size)\n        outputs = transform(embed_layer, model_1, model_2, output_dim_encode=encode_dim, output_dim_decode=decode_dim)\n        for j in range(outputs.shape[0]):\n            predict_labels.append(outputs[j].data)\n            real_labels.append(labels[j].data)\n    for i in range(len(predict_labels)):\n        if predict_labels[i] > 0.5:\n            predict_labels[i] = 1\n        else:\n            predict_labels[i] = 0\n    return [validation_acc, predict_labels, real_labels]\n\n\n\n\n\n        \n        ","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:55:59.776919Z","iopub.execute_input":"2022-01-08T06:55:59.777343Z","iopub.status.idle":"2022-01-08T06:56:04.144179Z","shell.execute_reply.started":"2022-01-08T06:55:59.777305Z","shell.execute_reply":"2022-01-08T06:56:04.143429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 4. Thực thi các hàm xử lý dữ liệu và chạy mô hình","metadata":{}},{"cell_type":"markdown","source":"Sau khi khởi tạo các hàm thích hợp, bây giờ sẽ áp dụng các hàm đấy để xử lý dữ liệu và huấn luyện mô hình cũng như kiểm thử","metadata":{}},{"cell_type":"code","source":"nltk.download('punkt')","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:56:09.588496Z","iopub.execute_input":"2022-01-08T06:56:09.588756Z","iopub.status.idle":"2022-01-08T06:56:29.626808Z","shell.execute_reply.started":"2022-01-08T06:56:09.588728Z","shell.execute_reply":"2022-01-08T06:56:29.626086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list_seq = _preprocess(list_sentence)\ntest_seq = _preprocess(test_sentence)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:56:29.628466Z","iopub.execute_input":"2022-01-08T06:56:29.628965Z","iopub.status.idle":"2022-01-08T07:01:36.504562Z","shell.execute_reply.started":"2022-01-08T06:56:29.628911Z","shell.execute_reply":"2022-01-08T07:01:36.503843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Dưới đây là ví dụ một vài câu đã được xử lý","metadata":{}},{"cell_type":"code","source":"random_taken = random.sample(range(0, len(list_seq)), 5)\norgin_sentence = []\npos_preprocessed_sentence = []\nfor i in range(len(random_taken)):\n    orgin_sentence.append(list_sentence[random_taken[i]])\n    pos_preprocessed_sentence.append(list_seq[random_taken[i]])\nexample = pd.DataFrame({'Trước khi xử lý': orgin_sentence})\nexample['Sau khi xử lý'] = pos_preprocessed_sentence\nexample\n\n    ","metadata":{"execution":{"iopub.status.busy":"2022-01-08T07:01:36.505901Z","iopub.execute_input":"2022-01-08T07:01:36.506175Z","iopub.status.idle":"2022-01-08T07:01:36.526045Z","shell.execute_reply.started":"2022-01-08T07:01:36.506141Z","shell.execute_reply":"2022-01-08T07:01:36.525097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_seq = list_seq.copy()\nall_seq.extend(test_seq)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:39:03.981754Z","iopub.execute_input":"2022-01-07T15:39:03.981992Z","iopub.status.idle":"2022-01-07T15:39:04.010415Z","shell.execute_reply.started":"2022-01-07T15:39:03.981959Z","shell.execute_reply":"2022-01-07T15:39:04.009729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list_seq, list_label = remove_empty(list_seq, list_label)\nprint('Số câu còn lại sau khi loại bỏ các câu rỗng ', len(list_seq))\nprint('Số nhãn còn lại sau khi loại bỏ các nhãn ứng với câu rỗng ', len(list_label))\n","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:39:04.014411Z","iopub.execute_input":"2022-01-07T15:39:04.014866Z","iopub.status.idle":"2022-01-07T15:39:04.426893Z","shell.execute_reply.started":"2022-01-07T15:39:04.014838Z","shell.execute_reply":"2022-01-07T15:39:04.426191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfre_word = count_word(all_seq)\ndict_word = create_vocab(fre_word, vocab_size=70000)\nlist_index = word_to_index(list_seq, dict_word)\n","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:39:04.427951Z","iopub.execute_input":"2022-01-07T15:39:04.428181Z","iopub.status.idle":"2022-01-07T15:39:21.709294Z","shell.execute_reply.started":"2022-01-07T15:39:04.428146Z","shell.execute_reply":"2022-01-07T15:39:21.708555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Khởi tạo các tham số cần thiết, với:  \n* vocab_size: Kích thước từ vựng\n* batch_size: Kích thước mini batch  \n* embed_size: Kích thước nhúng từ \n* padding_size: Kích thước padding, các câu sẽ được căn chỉnh về độ dài cố định đúng bằng nó  \n* percentage_attr: Tỉ lệ lượng dữ liệu làm training và validating lấy ra từ tập data gốc\n","metadata":{}},{"cell_type":"code","source":"vocab_size = 70000\nbatch_size = 16\nembed_size = 24\npadding_size = 16\npercentage_attr = 0.96","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:39:21.710471Z","iopub.execute_input":"2022-01-07T15:39:21.710978Z","iopub.status.idle":"2022-01-07T15:39:21.715644Z","shell.execute_reply.started":"2022-01-07T15:39:21.710934Z","shell.execute_reply":"2022-01-07T15:39:21.714973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list_label = torch.tensor(list_label)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:39:21.716792Z","iopub.execute_input":"2022-01-07T15:39:21.717384Z","iopub.status.idle":"2022-01-07T15:39:21.836977Z","shell.execute_reply.started":"2022-01-07T15:39:21.717348Z","shell.execute_reply":"2022-01-07T15:39:21.836278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_1, model_2, embed_model, criterion, optimizer = create_transform_model(vocab_size, embed_size)\n\n\n\n\n\n\n\n    \n\n","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:39:21.838275Z","iopub.execute_input":"2022-01-07T15:39:21.838575Z","iopub.status.idle":"2022-01-07T15:39:21.875192Z","shell.execute_reply.started":"2022-01-07T15:39:21.838542Z","shell.execute_reply":"2022-01-07T15:39:21.874553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"padding_seq = padding(list_index, padding_size)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:39:21.876413Z","iopub.execute_input":"2022-01-07T15:39:21.876674Z","iopub.status.idle":"2022-01-07T15:39:30.695186Z","shell.execute_reply.started":"2022-01-07T15:39:21.87664Z","shell.execute_reply":"2022-01-07T15:39:30.694453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"processed_data, data_size = _create_dataset(padding_seq, list_label)\n\n","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:39:30.696581Z","iopub.execute_input":"2022-01-07T15:39:30.696814Z","iopub.status.idle":"2022-01-07T15:39:47.338112Z","shell.execute_reply.started":"2022-01-07T15:39:30.696783Z","shell.execute_reply":"2022-01-07T15:39:47.337404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Như đã đề cập hàm _create_dataset sẽ tiến hành undersampling dữ liệu sau đó chuyển thành dataset, ta cùng thống kê số lượng cặp feature và label ứng với nhãn 0 và 1 còn lại","metadata":{}},{"cell_type":"code","source":"\n\n\nleft = [1, 2]\n\n# heights of bars\nheight = [data_size/2, data_size/2]\n \n# labels for bars\ntick_label = [0, 1]\n \n# plotting a bar chart\nplt.bar(left, height, tick_label = tick_label,\n        width = 0.8, color = ['red', 'green'])\n \n# naming the x-axis\nplt.xlabel('label')\n# naming the y-axis\nplt.ylabel('the quantities')\n# plot title\nplt.title('Number each label in the updated dataset')\n \n# function to show the plot\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:40:56.063123Z","iopub.execute_input":"2022-01-07T15:40:56.063382Z","iopub.status.idle":"2022-01-07T15:40:56.229276Z","shell.execute_reply.started":"2022-01-07T15:40:56.063352Z","shell.execute_reply":"2022-01-07T15:40:56.228496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader, test_loader = split_dataset(processed_data, data_size,percentage_attr)\n","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:41:03.231809Z","iopub.execute_input":"2022-01-07T15:41:03.232853Z","iopub.status.idle":"2022-01-07T15:41:03.252975Z","shell.execute_reply.started":"2022-01-07T15:41:03.232798Z","shell.execute_reply":"2022-01-07T15:41:03.252137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### In ra accuracy, p score, r score, f1 score cho các nhãn","metadata":{}},{"cell_type":"code","source":"acc, predict_labels, real_labels = train_and_validation(train_loader, test_loader, model_1, model_2, optimizer, criterion)\nprint('Accuracy của mô hình trên tập validation là ', acc[len(acc) - 1], '\\n')\ntp = [0.0, 0.0]\npo = [0.0, 0.0]\nfn = [0.0, 0.0]\np_score = [0.0, 0.0]\nr_score = [0.0, 0.0]\nf1_score = [0.0, 0.0]\nfor label in range(2):\n    for i in range(len(predict_labels)):\n        if int(predict_labels[i]) == label:\n            po[label] += 1\n            if int(predict_labels[i]) == int(real_labels[i]):\n                tp[label] += 1\n        else:\n            if int(predict_labels[i]) != int(real_labels[i]):\n                fn[label] += 1\n    p_score[label] = tp[label] / (po[label] + 1e-4)\n    r_score[label] = tp[label] / (tp[label] + fn[label] + 1e-4)\n    f1_score[label] = 2 * p_score[label] * r_score[label] / (p_score[label] + r_score[label])\nprint('Với nhãn 0:\\nĐiểm precision là ', p_score[0], '\\nĐiểm recall là ', r_score[0], '\\nĐiểm f1 la ', f1_score[0], '\\n')\nprint('Với nhãn 1:\\nĐiểm precision là ', p_score[1], '\\nĐiểm recall là ', r_score[1], '\\nĐiểm f1 la ', f1_score[1], '\\n')","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:41:10.644877Z","iopub.execute_input":"2022-01-07T15:41:10.64514Z","iopub.status.idle":"2022-01-07T15:42:10.392168Z","shell.execute_reply.started":"2022-01-07T15:41:10.645108Z","shell.execute_reply":"2022-01-07T15:42:10.390646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 5. Dự đoán đầu ra trên test.csv","metadata":{}},{"cell_type":"markdown","source":"#### Now turn to predicting label for test.csv, the result is print in submission.csv","metadata":{}},{"cell_type":"code","source":"test_index = word_to_index(test_seq, dict_word)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:56:00.307342Z","iopub.execute_input":"2022-01-07T15:56:00.307604Z","iopub.status.idle":"2022-01-07T15:56:02.565407Z","shell.execute_reply.started":"2022-01-07T15:56:00.307575Z","shell.execute_reply":"2022-01-07T15:56:02.564665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"padding_test = padding(test_index, padding_size)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:56:02.566942Z","iopub.execute_input":"2022-01-07T15:56:02.567179Z","iopub.status.idle":"2022-01-07T15:56:05.058909Z","shell.execute_reply.started":"2022-01-07T15:56:02.567147Z","shell.execute_reply":"2022-01-07T15:56:05.058082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"padding_test = process_data_to_input(padding_test, embed_model, padding_size)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:56:05.060324Z","iopub.execute_input":"2022-01-07T15:56:05.061045Z","iopub.status.idle":"2022-01-07T15:56:05.588045Z","shell.execute_reply.started":"2022-01-07T15:56:05.061006Z","shell.execute_reply":"2022-01-07T15:56:05.586993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict(features, model_1, model_2, optimizer, criterion, encode_dim=24, decode_dim=16):\n    list_label = []\n    for i in range(features.shape[0]):\n        list_label.append( transform(features[i], model_1, model_2, output_dim_encode=encode_dim, output_dim_decode=decode_dim).data)\n    result = []\n    for i in range(len(list_label)):\n        if list_label[i] < 0.5:\n            result.append(0)\n        else: result.append(1)\n    return result","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:56:08.210091Z","iopub.execute_input":"2022-01-07T15:56:08.210631Z","iopub.status.idle":"2022-01-07T15:56:08.217079Z","shell.execute_reply.started":"2022-01-07T15:56:08.210593Z","shell.execute_reply":"2022-01-07T15:56:08.216404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result = predict(padding_test, model_1, model_2, optimizer, criterion, encode_dim=24, decode_dim=16)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(result[0:100])","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:55:40.309184Z","iopub.status.idle":"2022-01-07T15:55:40.309887Z","shell.execute_reply.started":"2022-01-07T15:55:40.309629Z","shell.execute_reply":"2022-01-07T15:55:40.309655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_data = pd.DataFrame({'qid': test_data['qid'].values})","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:55:15.116761Z","iopub.status.idle":"2022-01-07T15:55:15.117163Z","shell.execute_reply.started":"2022-01-07T15:55:15.116951Z","shell.execute_reply":"2022-01-07T15:55:15.116972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_data['prediction'] = result\nsubmit_data.to_csv('submission.csv', index=False)\nsubmit_data","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:55:15.121876Z","iopub.status.idle":"2022-01-07T15:55:15.122272Z","shell.execute_reply.started":"2022-01-07T15:55:15.12206Z","shell.execute_reply":"2022-01-07T15:55:15.122082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}