{"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":"markdown","source":"# Báo cáo bài tập lớn cuối kỳ\n\nHọ và tên: Lê Thị Bích Duyên\n\nMSV: 19021254\n\nLớp: 2122I_INT3405E_20 \n\n## Nội dung\n1. Mô tả bài toán\n2. Phân tích dữ liệu\n3. Tiền xử lý dữ liệu\n4. Xây dựng mô hình\n5. Huấn luyện và dự đoán\n6. Submission\n\n# 1. Mô tả bài toán\nQuora là một nền tảng cho phép mọi người có thể đặt câu hỏi và nhận lại những câu trả lời chất lượng từ cộng đồng để giúp đỡ và học hỏi lẫn nhau. \nBài toán đặt ra là làm sao để loại bỏ những câu hỏi thiếu chân thành - dựa trên những tiên đề sai lầm hoặc có ý định đưa ra một tuyên bố hơn là tìm kiếm những câu trả lời hữu ích.\n- Input: câu hỏi trên quora ở dạng text\n- Output: 0 hoặc 1 (chân thành hoặc không chân thành)\n\n# 2. Phân tích dữ liệu\n","metadata":{}},{"cell_type":"code","source":"# import các thư viện cần thiết\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n#import os\n\nimport nltk\nimport tensorflow as tf\nimport tensorflow_addons as tfa\nimport gc\nimport re\nimport spacy\n\nfrom wordcloud import WordCloud, STOPWORDS, ImageColorGenerator\nfrom nltk.stem import PorterStemmer, SnowballStemmer\nfrom nltk.stem.lancaster import LancasterStemmer\n\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras.models import *\nfrom tensorflow.keras.preprocessing.text import Tokenizer\nfrom tensorflow.keras.preprocessing.sequence import pad_sequences\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.initializers import Constant\nfrom tensorflow.keras.utils import plot_model\nfrom tensorflow.keras.optimizers import Adam\n\nfrom sklearn import metrics\nfrom sklearn.model_selection import train_test_split, KFold, StratifiedKFold\nfrom sklearn.datasets import make_classification\n\nfrom pandarallel import pandarallel\npandarallel.initialize()\nfrom tqdm.notebook import tqdm\nfrom IPython.core.display import display, HTML\ntqdm().pandas()\n","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:23:31.707764Z","iopub.execute_input":"2022-01-08T05:23:31.708657Z","iopub.status.idle":"2022-01-08T05:23:39.502148Z","shell.execute_reply.started":"2022-01-08T05:23:31.708551Z","shell.execute_reply":"2022-01-08T05:23:39.501498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# đọc tập dữ liệu csv vào dataframe\ntrain_df = pd.read_csv(\"/kaggle/input/quora-insincere-questions-classification/train.csv\")\ntest_df = pd.read_csv(\"/kaggle/input/quora-insincere-questions-classification/test.csv\")\n\n# train_df.head(5)\ntrain_df.info()\ntest_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:23:39.503654Z","iopub.execute_input":"2022-01-08T05:23:39.50404Z","iopub.status.idle":"2022-01-08T05:23:46.262383Z","shell.execute_reply.started":"2022-01-08T05:23:39.504011Z","shell.execute_reply":"2022-01-08T05:23:46.261756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Dữ liệu train gồm 1306122 hàng với 3 trường dữ liệu\n- qid: mã định danh câu hỏi\n- question_text: câu hỏi dạng text trên quora\n- target: nhãn của câu hỏi, 0 tương ứng với sincere, 1 tương ứng với insincere\n\nNhận thấy dữ liệu train và test có các giá trị đều hợp lệ, không có giá trị nào null","metadata":{}},{"cell_type":"code","source":"# phân tích số lượng câu hỏi sincere và insincere\ntrain_df['words_num'] = train_df.question_text.parallel_apply(lambda x: len(x.split()))\n\nsincere_ques = train_df[train_df.target==0]\ninsincere_ques = train_df[train_df.target==1]\n\n# xây dựng bảng, biểu đồ phân tích dữ liệu\nfig, ax = plt.subplots(1,2)\nax[0] = fig.add_axes([0,0,1,1])\nax[1] = fig.add_axes([1.2,0,1,1])\n# bar chart\nax[0].set_title('Statistics of sincere and insincere question')\nax[0].bar(['sincere', 'insincere'], train_df.target.value_counts(),\n         color=(0.9, 0.4, 0.6, 0.6))\nfor p in ax[0].patches:\n    height = p.get_height()\n    ax[0].annotate('{}'.format(height),\n      xy=(p.get_x() + p.get_width() / 2, height),\n      xytext=(0, 3), # 3 points vertical offset\n      textcoords=\"offset points\",ha='center')\n# pie chart\nrates = [sincere_ques.shape[0]/train_df.shape[0] * 100, \n        insincere_ques.shape[0]/train_df.shape[0] * 100]\n\nplt.pie(rates, labels=['sincere', 'insincere'],autopct='%1.1f%%', shadow=False, \n        colors=(\"grey\",\"orange\"),startangle=90)\nplt.show()\n\n# train_df['target'].value_counts().plot(kind='bar')","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:23:46.263817Z","iopub.execute_input":"2022-01-08T05:23:46.264379Z","iopub.status.idle":"2022-01-08T05:23:49.106415Z","shell.execute_reply.started":"2022-01-08T05:23:46.264329Z","shell.execute_reply":"2022-01-08T05:23:49.10539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# in ra một số mẫu câu hỏi sincere và insincere\nprint('sincere question: ')\ndisplay(sincere_ques.head(5))\nprint('insincere question: ')\ndisplay(insincere_ques.head(5))","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:23:49.109097Z","iopub.execute_input":"2022-01-08T05:23:49.109545Z","iopub.status.idle":"2022-01-08T05:23:49.133814Z","shell.execute_reply.started":"2022-01-08T05:23:49.109498Z","shell.execute_reply":"2022-01-08T05:23:49.132999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Từ biểu đồ trên ta thấy số câu hỏi sincere chênh lệch khá lớn, gấp khoảng 15 lần so với câu hỏi insincere. Vì kích thước dữ liệu ở các lớp không cân bằng nhau, nên ta sử dụng phép đo Precision-Recall, lấy F1-score (harmonic mean của precision và recall) để đánh giá mô hình. F1 càng cao thì bộ phân lớp càng tốt.\n\n$\\frac{2}{F_1}=\\frac{1}{precision}+\\frac{1}{recall}$\n\ntrong đó: \n- precision - độ chính xác: tỉ lệ số điểm true positive (TP) trong số những điểm được phân loại là positive (TP + FP).\n- recall - độ bao phủ: tỉ lệ số điểm true positive (TP) trong số những điểm thực sự là positive (TP + FN).\n\n(https://exposedjunction.com/f1-score-la-gi/)\n\nKhông thể sử dụng accuracy (tính bằng tỉ lệ số điểm dự đoán đúng/tổng số điểm trong tập kiểm thử) để đánh giá mô hình vì nó sẽ dự đoán câu hỏi hầu hết thuộc nhóm sincere, mô hình sẽ có sai số lớn và không dùng được.\n","metadata":{}},{"cell_type":"code","source":"# phân tích số lượng từ trong câu hỏi\nfig2, axes = plt.subplots(1,2)\naxes[0] = fig2.add_axes([0,0,1,1.2])\naxes[1] = fig2.add_axes([1.2,0,1,1])\n# table\nrowLabels = [\"min_len\",\"mean_len\",\"max_len\"]\ncolLabels = [\"sincere_question\",\"insincere_question\"]\ndata = [[np.min(sincere_ques['words_num']), np.min(insincere_ques['words_num'])],\n       [np.mean(sincere_ques['words_num']), np.mean(insincere_ques['words_num'])],\n       [np.max(sincere_ques['words_num']), np.max(insincere_ques['words_num'])]]\ndf = pd.DataFrame(data, columns=colLabels)\naxes[0].axis('off')\ntable=axes[0].table(cellText=df.values,colLabels=df.columns,rowLabels=rowLabels,bbox=[0, 0, 1, 0.8])\ntable.auto_set_font_size(False)\ntable.set_fontsize(14)\n# density plot\naxes[1].set_title('Density plot of number of words in every question') \nsns.set(style=\"darkgrid\")\nsns.kdeplot(train_df.words_num, shade=True, color='red')\nsns.kdeplot(sincere_ques.words_num, shade=True, color='blue')\nsns.kdeplot(insincere_ques.words_num, shade=True, color='orange')\nplt.legend([\"all\", \"sincere\", \"insincere\"])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:23:49.134845Z","iopub.execute_input":"2022-01-08T05:23:49.135651Z","iopub.status.idle":"2022-01-08T05:24:02.662537Z","shell.execute_reply.started":"2022-01-08T05:23:49.135617Z","shell.execute_reply":"2022-01-08T05:24:02.661412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Nhận xét: đồ thị của câu hỏi sincere (chân thành) hẹp và dốc hơn câu hỏi không chân thành => câu hỏi chân thành có xu hướng ít từ hơn.\n- câu hỏi sincere có độ dài trung bình là 12.5 từ trên một câu, câu dài nhất là 134 từ, hầu hết độ dài đều nằm trong khoảng dưới 55 từ\n- câu hỏi insincere có độ dài trung bình 17.3 từ, câu dài nhất là 64 từ và độ dài hầu hết đều nằm trong khoảng 55 từ trở xuống","metadata":{}},{"cell_type":"markdown","source":"# 3. Tiền xử lý dữ liệu\nVì dữ liệu dạng text thường phức tạp do bản thân các từ là dữ liệu rời rạc, nhiều nhiễu nên để chuyển thành dạng máy tính có thể hiểu được ta cần phải xử lý trước dữ liệu.\n\nCác bước bao gồm:\n\n**B1: Clean dữ liệu:**\n- bỏ các kí tự đặc biệt (dấu câu...)\n- bỏ các tag không cần thiết (công thức toán, đường link)\n- sửa các lỗi chính tả thường gặp\n- lowercase\n- chuyển các từ viết tắt về dạng nguyên bản\n- bỏ các stopword (ví dụ như the, is,... không có ngữ nghĩa cụ thể) - ở đây em không bỏ các stopword vì tuy các từ này đứng riêng lẻ thì ko có ngữ nghĩa nhưng nếu xóa hết thì nghĩa của câu sẽ bị ảnh hưởng khá nhiều, dự đoán có thể làm giảm độ chính xác của mô hình.\n\n**B2: Tokenization** \n\n**B3: Convert to sequences** ","metadata":{}},{"cell_type":"code","source":"# tạo sample data từ train data để thử nghiệm các hàm tiền xử lý\ntrain_suffle = train_df.sample(frac = 1,random_state=123).reset_index(drop=True)\nsample = train_suffle.sample(n=100, random_state=123)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:24:02.665057Z","iopub.execute_input":"2022-01-08T05:24:02.665512Z","iopub.status.idle":"2022-01-08T05:24:03.580814Z","shell.execute_reply.started":"2022-01-08T05:24:02.665465Z","shell.execute_reply":"2022-01-08T05:24:03.579852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# từ điển từ viết tắt\ncontraction_dict= {\"cant\": 'can not',\"doesnt\": 'does not',\"dont\": 'do not',\"i'm'a\": 'i am about to',\"i'm'o\": 'i am going to',\"i'm\": 'i am',\"i've\": 'i have',\"i'll\": 'i will',\"i'll've\": 'i will have',\"i'd've\": 'i would have',\"i'd\": 'i would',\"whatcha\": 'what are you',\"amn't\": 'am not',\"ain't\": 'are not',\"aren't\": 'are not',\"'cause\": 'because',\"can't\": 'can not',\"can't've\": 'can not have',\"could've\": 'could have',\"couldn't\": 'could not',\"couldn't've\": 'could not have',\"daren't\": 'dare not',\"daresn't\": 'dare not',\"dasn't\": 'dare not',\"didn't\": 'did not','didn’t': 'did not',\"don't\": 'do not','don’t': 'do not',\"doesn't\": 'does not',\"e'er\": 'ever',\"everyone's\": 'everyone is',\"finna\": 'fixing to',\"gimme\": 'give me',\"gon't\": 'go not',\"gonna\": 'going to',\"gotta\": 'got to',\"hadn't\": 'had not',\"hadn't've\": 'had not have',\"hasn't\": 'has not',\"haven't\": 'have not',\"he've\": 'he have',\"he's\": 'he is',\"he'll\": 'he will',\"he'll've\": 'he will have',\"he'd\": 'he would',\"he'd've\": 'he would have',\"here's\": 'here is',\"how're\": 'how are',\"how'd\": 'how did',\"how'd'y\": 'how do you',\"how's\": 'how is',\"how'll\": 'how will',\"isn't\": 'is not',\"it's\": 'it is',\"'tis\": 'it is',\"'twas\": 'it was',\"it'll\": 'it will',\"it'll've\": 'it will have',\"it'd\": 'it would',\"it'd've\": 'it would have',\"kinda\": 'kind of',\"let's\": 'let us',\"luv\": 'love',\"ma'am\": 'madam',\"may've\": 'may have',\"mayn't\": 'may not',\"might've\": 'might have',\"mightn't\": 'might not',\"mightn't've\": 'might not have',\"must've\": 'must have',\"mustn't\": 'must not',\"mustn't've\": 'must not have',\"needn't\": 'need not',\"needn't've\": 'need not have',\"ne'er\": 'never',\"o'\": 'of',\"o'clock\": 'of the clock',\"ol'\": 'old',\"oughtn't\": 'ought not',\"oughtn't've\": 'ought not have',\"o'er\": 'over',\"shan't\": 'shall not',\"sha'n't\": 'shall not',\"shalln't\": 'shall not',\"shan't've\": 'shall not have',\"she's\": 'she is',\"she'll\": 'she will',\"she'd\": 'she would',\"she'd've\": 'she would have',\"should've\": 'should have',\"shouldn't\": 'should not',\"shouldn't've\": 'should not have',\"so've\": 'so have',\"so's\": 'so is',\"somebody's\": 'somebody is',\"someone's\": 'someone is',\"something's\": 'something is',\"sux\": 'sucks',\"that're\": 'that are',\"that's\": 'that is',\"that'll\": 'that will',\"that'd\": 'that would',\"that'd've\": 'that would have',\"em\": 'them',\"there're\": 'there are',\"there's\": 'there is',\"there'll\": 'there will',\"there'd\": 'there would',\"there'd've\": 'there would have',\"these're\": 'these are',\"they're\": 'they are',\"they've\": 'they have',\"they'll\": 'they will',\"they'll've\": 'they will have',\"they'd\": 'they would',\"they'd've\": 'they would have',\"this's\": 'this is',\"those're\": 'those are',\"to've\": 'to have',\"wanna\": 'want to',\"wasn't\": 'was not',\"we're\": 'we are',\"we've\": 'we have',\"we'll\": 'we will',\"we'll've\": 'we will have',\"we'd\": 'we would',\"we'd've\": 'we would have',\"weren't\": 'were not',\"what're\": 'what are',\"what'd\": 'what did',\"what've\": 'what have',\"what's\": 'what is',\"what'll\": 'what will',\"what'll've\": 'what will have',\"when've\": 'when have',\"when's\": 'when is',\"where're\": 'where are',\"where'd\": 'where did',\"where've\": 'where have',\"where's\": 'where is',\"which's\": 'which is',\"who're\": 'who are',\"who've\": 'who have',\"who's\": 'who is',\"who'll\": 'who will',\"who'll've\": 'who will have',\"who'd\": 'who would',\"who'd've\": 'who would have',\"why're\": 'why are',\"why'd\": 'why did',\"why've\": 'why have',\"why's\": 'why is',\"will've\": 'will have',\"won't\": 'will not',\"won't've\": 'will not have',\"would've\": 'would have',\"wouldn't\": 'would not',\"wouldn't've\": 'would not have',\"y'all\": 'you all',\"y'all're\": 'you all are',\"y'all've\": 'you all have',\"y'all'd\": 'you all would',\"y'all'd've\": 'you all would have',\"you're\": 'you are',\"you've\": 'you have',\"you'll've\": 'you shall have',\"you'll\": 'you will',\"you'd've\": 'you would have',\"you'd\": 'you would','jan.': 'january','feb.': 'february','mar.': 'march','apr.': 'april','jun.': 'june','jul.': 'july','aug.': 'august','sep.': 'september','oct.': 'october','nov.': 'november','dec.': 'december','I’m': 'I am','I’m’a': 'I am about to','I’m’o': 'I am going to','I’ve': 'I have','I’ll': 'I will','I’ll’ve': 'I will have','I’d': 'I would','I’d’ve': 'I would have','amn’t': 'am not','ain’t': 'are not','aren’t': 'are not','’cause': 'because','can’t': 'can not','can’t’ve': 'can not have','could’ve': 'could have','couldn’t': 'could not','couldn’t’ve': 'could not have','daren’t': 'dare not','daresn’t': 'dare not','dasn’t': 'dare not','doesn’t': 'does not','e’er': 'ever','everyone’s': 'everyone is','gon’t': 'go not','hadn’t': 'had not','hadn’t’ve': 'had not have','hasn’t': 'has not','haven’t': 'have not','he’ve': 'he have','he’s': 'he is','he’ll': 'he will','he’ll’ve': 'he will have','he’d': 'he would','he’d’ve': 'he would have','here’s': 'here is','how’re': 'how are','how’d': 'how did','how’d’y': 'how do you','how’s': 'how is','how’ll': 'how will','isn’t': 'is not','it’s': 'it is','’tis': 'it is','’twas': 'it was','it’ll': 'it will','it’ll’ve': 'it will have','it’d': 'it would','it’d’ve': 'it would have','let’s': 'let us','ma’am': 'madam','may’ve': 'may have','mayn’t': 'may not','might’ve': 'might have','mightn’t': 'might not','mightn’t’ve': 'might not have','must’ve': 'must have','mustn’t': 'must not','mustn’t’ve': 'must not have','needn’t': 'need not','needn’t’ve': 'need not have','ne’er': 'never','o’': 'of','o’clock': 'of the clock','ol’': 'old','oughtn’t': 'ought not','oughtn’t’ve': 'ought not have','o’er': 'over','shan’t': 'shall not','sha’n’t': 'shall not','shalln’t': 'shall not','shan’t’ve': 'shall not have','she’s': 'she is','she’ll': 'she will','she’d': 'she would','she’d’ve': 'she would have','should’ve': 'should have','shouldn’t': 'should not','shouldn’t’ve': 'should not have','so’ve': 'so have','so’s': 'so is','somebody’s': 'somebody is','someone’s': 'someone is','something’s': 'something is','that’re': 'that are','that’s': 'that is','that’ll': 'that will','that’d': 'that would','that’d’ve': 'that would have','there’re': 'there are','there’s': 'there is','there’ll': 'there will','there’d': 'there would','there’d’ve': 'there would have','these’re': 'these are','they’re': 'they are','they’ve': 'they have','they’ll': 'they will','they’ll’ve': 'they will have','they’d': 'they would','they’d’ve': 'they would have','this’s': 'this is','those’re': 'those are','to’ve': 'to have','wasn’t': 'was not','we’re': 'we are','we’ve': 'we have','we’ll': 'we will','we’ll’ve': 'we will have','we’d': 'we would','we’d’ve': 'we would have','weren’t': 'were not','what’re': 'what are','what’d': 'what did','what’ve': 'what have','what’s': 'what is','what’ll': 'what will','what’ll’ve': 'what will have','when’ve': 'when have','when’s': 'when is','where’re': 'where are','where’d': 'where did','where’ve': 'where have','where’s': 'where is','which’s': 'which is','who’re': 'who are','who’ve': 'who have','who’s': 'who is','who’ll': 'who will','who’ll’ve': 'who will have','who’d': 'who would','who’d’ve': 'who would have','why’re': 'why are','why’d': 'why did','why’ve': 'why have','why’s': 'why is','will’ve': 'will have','won’t': 'will not','won’t’ve': 'will not have','would’ve': 'would have','wouldn’t': 'would not','wouldn’t’ve': 'would not have','y’all': 'you all','y’all’re': 'you all are','y’all’ve': 'you all have','y’all’d': 'you all would','y’all’d’ve': 'you all would have','you’re': 'you are','you’ve': 'you have','you’ll’ve': 'you shall have','you’ll': 'you will','you’d': 'you would','you’d’ve': 'you would have', 'aka': 'also known as', 'approx.': 'approximately'}\n# các lỗi chính tả thường gặp hoặc các từ cách viết khác nhưng cùng nghĩa\nmispell_dict = {'colour': 'color', 'centre': 'center', 'favourite': 'favorite', 'travelling': 'traveling', 'counselling': 'counseling', 'theatre': 'theater', 'cancelled': 'canceled', 'labour': 'labor', 'organisation': 'organization', 'wwii': 'world war 2', 'citicise': 'criticize', 'youtu ': 'youtube ', 'Qoura': 'Quora', 'sallary': 'salary', 'Whta': 'What', 'narcisist': 'narcissist', 'howdo': 'how do', 'whatare': 'what are', 'howcan': 'how can', 'howmuch': 'how much', 'howmany': 'how many', 'whydo': 'why do', 'doI': 'do I', 'theBest': 'the best', 'howdoes': 'how does', 'mastrubation': 'masturbation', 'mastrubate': 'masturbate', \"mastrubating\": 'masturbating', 'pennis': 'penis', 'Etherium': 'bitcoin', 'narcissit': 'narcissist', 'bigdata': 'big data', '2k17': '2017', '2k18': '2018', 'qouta': 'quota', 'exboyfriend': 'ex boyfriend', 'airhostess': 'air hostess', \"whst\": 'what', 'watsapp': 'whatsapp', 'demonitisation': 'demonetization', 'demonitization': 'demonetization', 'demonetisation': 'demonetization','electroneum':'bitcoin','nanodegree':'degree','hotstar':'star','dream11':'dream','ftre':'fire','tensorflow':'framework','unocoin':'bitcoin','lnmiit':'limit','unacademy':'academy','altcoin':'bitcoin','altcoins':'bitcoin','litecoin':'bitcoin','coinbase':'bitcoin','cryptocurency':'cryptocurrency','simpliv':'simple','quoras':'quora','schizoids':'psychopath','remainers':'remainder','twinflame':'soulmate','quorans':'quora','brexit':'demonetized','iiest':'institute','dceu':'comics','pessat':'exam','uceed':'college','bhakts':'devotee','boruto':'anime','cryptocoin':'bitcoin','blockchains':'blockchain','fiancee':'fiance','redmi':'smartphone','oneplus':'smartphone','qoura':'quora','deepmind':'framework','ryzen':'cpu','whattsapp':'whatsapp','undertale':'adventure','zenfone':'smartphone','cryptocurencies':'cryptocurrencies','koinex':'bitcoin','zebpay':'bitcoin','binance':'bitcoin','whtsapp':'whatsapp','reactjs':'framework','bittrex':'bitcoin','bitconnect':'bitcoin','bitfinex':'bitcoin','yourquote':'your quote','whyis':'why is','jiophone':'smartphone','dogecoin':'bitcoin','onecoin':'bitcoin','poloniex':'bitcoin','7700k':'cpu','angular2':'framework','segwit2x':'bitcoin','hashflare':'bitcoin','940mx':'gpu','openai':'framework','hashflare':'bitcoin','1050ti':'gpu','nearbuy':'near buy','freebitco':'bitcoin','antminer':'bitcoin','filecoin':'bitcoin','whatapp':'whatsapp','empowr':'empower','1080ti':'gpu','crytocurrency':'cryptocurrency','8700k':'cpu','whatsaap':'whatsapp','g4560':'cpu','payymoney':'pay money','fuckboys':'fuck boys','intenship':'internship','zcash':'bitcoin','demonatisation':'demonetization','narcicist':'narcissist','mastuburation':'masturbation','trignometric':'trigonometric','cryptocurreny':'cryptocurrency','howdid':'how did','crytocurrencies':'cryptocurrencies','phycopath':'psychopath','bytecoin':'bitcoin','possesiveness':'possessiveness','scollege':'college','humanties':'humanities','altacoin':'bitcoin','demonitised':'demonetized','brasília':'brazilia','accolite':'accolyte','econimics':'economics','varrier':'warrier','quroa':'quora','statergy':'strategy','langague':'language','splatoon':'game','7600k':'cpu','gate2018':'gate 2018','in2018':'in 2018','narcassist':'narcissist','jiocoin':'bitcoin','hnlu':'hulu','7300hq':'cpu','weatern':'western','interledger':'blockchain','deplation':'deflation', 'cryptocurrencies':'cryptocurrency', 'bitcoin':'blockchain cryptocurrency'}","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:24:03.582516Z","iopub.execute_input":"2022-01-08T05:24:03.582795Z","iopub.status.idle":"2022-01-08T05:24:03.633023Z","shell.execute_reply.started":"2022-01-08T05:24:03.582763Z","shell.execute_reply":"2022-01-08T05:24:03.632092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# remove tag------------------------------------------------------------------------------------\n# xóa các tag không mang nhiều ý nghĩa như url, các biểu thức toán\ndef remove_tag(x):\n    if '[math]' in x:\n        x = re.sub('\\[math\\].*?math\\]', 'math_equation', x)\n    if 'http' in x or 'www' in x:\n        x = re.sub('(?:(?:https?|ftp):\\/\\/)?[\\w/\\-?=%.]+\\.[\\w/\\-?=%.]+', 'url', x)\n    return x\n\n# remove numbers--------------------------------------------------------------------------------\n# thay số bằng # vì hầu hết các embedding đều xử lý text như vậy, sau này khi kết hợp vs embedding\n# để huấn luyện mô hình sẽ tốt hơn\ndef clean_numbers(x):\n    if bool(re.search(r'\\d', x)):\n        x = re.sub('[0-9]{5,}', '#####', x)\n        x = re.sub('[0-9]{4}', '####', x)\n        x = re.sub('[0-9]{3}', '###', x)\n        x = re.sub('[0-9]{2}', '##', x)\n    return x\n\n# spell missing--------------------------------------------------------------------------------\ndef _get_mispell(mispell_dict):\n    mispell_re = re.compile('(%s)' % '|'.join(mispell_dict.keys()))\n    return mispell_dict, mispell_re\n\nmispellings, mispellings_re = _get_mispell(mispell_dict)\ndef misspell_fix(text):\n    def replace(match):\n        return mispellings[match.group(0)]\n    return mispellings_re.sub(replace, text)\n\n# abbreviation - từ viết tắt-------------------------------------------------------------------\ndef contraction_fix(word):\n    try:\n        a=contraction_dict[word]\n    except KeyError:\n        a=word\n    return a\n\ndef abbreviation_fix(text):\n    text = \" \".join([contraction_fix(w) for w in text.split()])\n    return text\n\n#stemming text--------------------------------------------------------------------------------\n# ex: studies --> studi, fishes-->fish\ndef stemming(text):\n    ls = LancasterStemmer()\n    text = \" \".join([ls.stem(w) for w in text.split()])\n    return text\n\n# example-----------------------------------\ntext = \"i am travelling around the world.\"\ntext2 = \"i'd've gone to japan\"\nprint('before\\n'+text+'\\n'+text2)\nprint('after')\nprint(misspell_fix(text))\nprint(stemming(text))\nprint(abbreviation_fix(text2))","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:24:03.634488Z","iopub.execute_input":"2022-01-08T05:24:03.634756Z","iopub.status.idle":"2022-01-08T05:24:03.662833Z","shell.execute_reply.started":"2022-01-08T05:24:03.634728Z","shell.execute_reply":"2022-01-08T05:24:03.661917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sử dụng các hàm bên trên để clean text\n# clean text gồm: xóa tag, sửa lỗi misspell, từ viết tắt,---------------------------------------------\n                # xóa kí tự đặc biệt, clean số\ndef clean_text(text, lowercase=True):\n    text = remove_tag(text)\n    if lowercase:\n        text = text.lower()\n    text = misspell_fix(text)\n    text = abbreviation_fix(text)\n    # xóa kí tự đặc biệt khác chữ và số\n    text = re.sub(r'[^a-zA-Z0-9]', ' ', text)\n    # clean số\n    text = clean_numbers(text)\n    # text = stemming(text)\n    return text\n\n# clean text cho toàn bộ tập dữ liệu------------------------------------------------------------------\ndef clean_data(question_text, lowercase=True, preview=False):\n    data_clean = pd.DataFrame()\n    data_clean['question_text'] = question_text\n    data_clean['clean']= data_clean.question_text.parallel_apply(lambda x: clean_text(x, lowercase))\n    if preview:\n        display(data_clean.head(100))\n    return data_clean.clean\n\n# example---------------------------------------------------------\ntext='I really like may'\nprint(text.lower())\nsample['clean']=clean_data(sample[\"question_text\"], preview=True)\n#display(sample)\n","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:24:03.66411Z","iopub.execute_input":"2022-01-08T05:24:03.664915Z","iopub.status.idle":"2022-01-08T05:24:03.887722Z","shell.execute_reply.started":"2022-01-08T05:24:03.664882Z","shell.execute_reply":"2022-01-08T05:24:03.886679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Tokenization và Convert to sequences:\n- `create_tokenizer()`: để chuyển 1 câu thành tập các từ riêng lẻ, (mỗi token là một từ), sử dụng Tokenizer của keras để tạo một bộ từ điển token, từ xuất hiện càng nhiều thì index của nó càng nhỏ\n    - khi sử dụng bộ vocab tokenizer được tạo ra để chuyển văn bản thành chuỗi số thì có thể có những từ ở văn bản không nằm trong tokenizer, vì vậy ta dùng `'<OOV>'` để thay thế cho chúng.\n    VD: tokenizer tìm được: `['<OOV>':1,'this': 2, 'fat': 3]`\n    \n    văn bản cần chuyển: `text` = `this cat is very fat`\n    \n    => sau khi sử dụng tokenizer: `text` = `[2 1 1 1 3]`\n- `convert_to_sequences()`: sử dụng từ điển đã tạo để chuyển text sang chuỗi số để máy tính hiểu được, padding và truncating để đồng bộ chiều dài các câu thành một giá trị cố định\n\n    dựa vào biểu đồ đã phân tích ở phần 2 ta nhận thấy hầu hết các câu hỏi đều có độ dài từ 55 từ trở xuống, câu dài hơn có số lượng rất ít nên ta chọn độ dài chung cho các chuỗi là 70 từ\n","metadata":{}},{"cell_type":"code","source":"SEQUENCES_LENGTH = 70\n\n# tokenize text------------------------------------------------------------------------------------\ndef create_tokenizer(text_data, preview=False, amount=10):\n    tokenizer = Tokenizer(oov_token='<OOV>')\n    tokenizer.fit_on_texts(list(text_data))    \n    if preview:\n        print(\"Size of Vocab dictionary: \", len(tokenizer.word_index))\n        print(\"Preview: \"+str(amount))\n        print(list(tokenizer.word_index.items())[:amount])\n    return tokenizer\n\n# convert text to sequence by token dictionary----------------------------------------------------\ndef convert_to_sequences(tokenizer, text_data, padding=True, sequences_len=0):\n    # convert to sequences\n    word_sequences = tokenizer.texts_to_sequences(text_data)\n    # padding sequences để các chuỗi đều có độ dài bằng nhau\n    if padding:\n        word_sequences= pad_sequences(word_sequences, maxlen=sequences_len, \n                          padding='post', truncating='post') \n    return word_sequences  \n    \n# example----------------------------------------------\ntokenizer=create_tokenizer(sample.clean, preview=True)\n#print(len(token_data.word_index)+1)\npadded_sequences = convert_to_sequences(tokenizer, sample['clean'],\n                                        sequences_len=SEQUENCES_LENGTH)\nprint(\"5 first sequences:\")\nfor sequence in padded_sequences[:5]:\n    print(sequence)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:24:03.893397Z","iopub.execute_input":"2022-01-08T05:24:03.894124Z","iopub.status.idle":"2022-01-08T05:24:03.937217Z","shell.execute_reply.started":"2022-01-08T05:24:03.89407Z","shell.execute_reply":"2022-01-08T05:24:03.936346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Như vậy là các hàm preprocessing đã xây dựng và hoạt động tốt, em sẽ áp dụng để xử lý dữ liệu của bài toán ở phần 5.","metadata":{}},{"cell_type":"markdown","source":"# 4. Mô hình huấn luyện","metadata":{}},{"cell_type":"markdown","source":"Xây dựng mô hình huấn luyện bằng Bidirectional LSTM (Long Short-Term Memory Networks)\n\nTrước khi hiểu mô hình LSTM là gì thì ta cần hiểu qua về mạng RNN - recurrent neural network.\nRNN có thể mang thông tin từ các layer trước đến layer sau, nên nó có thể dùng để xử lý thông tin dạng chuỗi. Một ví dụ của RNN trong bài toán dự đoán video, RNN có thể mang thông tin của frame ảnh từ state trước tới state sau, tuy nhiên state ở trước đó càng xa thì càng bị vanishing gradient, nghĩa là thông tin chỉ mang được qua một lượng state nhất định\nhay nói cách khác là model chỉ học được từ các state gần nó - short term memory\n\nVì vậy, mô hình Long short term memory ra đời để giải quyết vấn đề khi ta cần các thông tin từ state ở trước đó rất xa và tránh được vanishing gradient. Nó vẫn giữ tư tưởng chính của RNN là sự sao chép kiến trúc theo dạng chuỗi nhưng có phần phức tạp hơn.\n\n- Bidirectional LSTM là một biến thể của LSTM. Trong khi LSTM đơn hướng do đầu vào duy nhất mà nó lấy là từ quá khứ nên nó không thể lưu giữ các thông tin ở tương lai. BiLSTM sẽ chạy thông tin đầu vào theo hai cách: từ quá khứ đến tương lai và từ tương lai trở lại. Do đó nó có thể hiểu được ngữ cảnh của văn bản tốt hơn.\n\nVD: một ví dụ về dự đoán cần thông tin từ tương lai trong đoạn text là:\n\n   `Tôi phải đi học. Hôm qua trời ... Sáng nay đường ướt và trơn trượt`\n\nTa không thể đoán được nếu như chỉ sử dụng thông tin từ quá khứ, mà cần sử dụng thông tin ở câu sau, tức là từ tương lai ` sáng nay` để dự đoán từ còn thiếu là `mưa` \n\n","metadata":{}},{"cell_type":"code","source":"# f1 score\nf1 = tfa.metrics.F1Score(num_classes=1, threshold=0.5)\nprint('success')\nreduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.5, \n                              patience=2, min_lr=0.0001, verbose=0)\nprint('success')\nearlystopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=5, \n                              verbose=1, mode='auto', restore_best_weights=True)\nprint('success')\ncallbacks = [earlystopping, reduce_lr]\n\n# hàm để xây dựng model-------------------------------------------------------------------------------\ndef build_Model_LSTM(features=120000, embedding_dim=200, lr=0.001, embedding_matrix=None):\n    input_x = Input(shape=(SEQUENCES_LENGTH))\n    if not(embedding_matrix is None):\n        embedding = Embedding(features, embedding_dim, input_length=SEQUENCES_LENGTH,\n                              weights=[embedding_matrix], trainable=False)(input_x)\n    else:\n        embedding = Embedding(features, embedding_dim, input_length=SEQUENCES_LENGTH)(input_x)\n    x = Bidirectional(LSTM(128, return_sequences=True))(embedding)\n    x = Bidirectional(LSTM(64, return_sequences=True))(x)\n    x = GlobalMaxPool1D()(x)\n    x = Dense(64, activation=\"relu\")(x)\n    x = Dense(1, activation=\"sigmoid\")(x)\n    model = Model(inputs=input_x, outputs=x)\n    opt = Adam(lr)\n    model.compile(loss='binary_crossentropy', optimizer=opt, metrics=[f1])\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:24:03.93858Z","iopub.execute_input":"2022-01-08T05:24:03.939067Z","iopub.status.idle":"2022-01-08T05:24:04.016935Z","shell.execute_reply.started":"2022-01-08T05:24:03.939032Z","shell.execute_reply":"2022-01-08T05:24:04.015915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5. Huấn luyện và dự đoán\n## 5.1. Huấn luyện","metadata":{}},{"cell_type":"code","source":"EMBEDDING_DIM = 300\n\nbatch_size = 512\nnum_epochs = 10\nlearning_rate = 0.001\n\n\n# B1: preprocessing=====================================================================\n# clean tập dữ liệu train và dữ liệu test\nprint('B1: clean text: wait about 40s...')\ntrain_text = clean_data(train_suffle.question_text, lowercase=True)\ntrain_target = train_suffle.target\n\ntest_X = clean_data(test_df.question_text, lowercase=True)\n\n# B2: chia train_df thành 2 tập train và validate theo tỉ lệ 8:2========================\nprint('B2: splitting train_df')\ntrain_X, val_X, train_Y, val_Y = train_test_split(train_text, train_target,\n                                                  test_size=0.2, random_state=165)\n\n# B3: convert to sequences==============================================================\nprint('B3: convert to sequences....')\n\ntokenizer = create_tokenizer(train_X)\nprint('Create vocab dict success. Start converting..')\n\ntrain_X_seq = convert_to_sequences(tokenizer, train_X, sequences_len=SEQUENCES_LENGTH)\nval_X_seq = convert_to_sequences(tokenizer, val_X, sequences_len=SEQUENCES_LENGTH)\ntest_X_seq = convert_to_sequences(tokenizer, test_X, sequences_len=SEQUENCES_LENGTH)\nprint('Convert successfully.')\n\nfeatures = len(tokenizer.word_index)+1\nprint('features: '+str(features))","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:24:04.018761Z","iopub.execute_input":"2022-01-08T05:24:04.0194Z","iopub.status.idle":"2022-01-08T05:25:53.153942Z","shell.execute_reply.started":"2022-01-08T05:24:04.019355Z","shell.execute_reply":"2022-01-08T05:25:53.152556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Sử dụng TPU để cải thiện tốc độ training, em thấy nhanh hơn khoảng 3 lần so với GPU và không gặp tình trạng bị dừng lại do truy cập quá mức bộ nhớ\n\nhttps://www.kaggle.com/kutaykutlu/tpus-resnet50-leaf-disease#Detect-TPU","metadata":{}},{"cell_type":"code","source":"# sử dụng TPU\nstrategy = None\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect() # TPU detection\n    strategy = tf.distribute.TPUStrategy(tpu)\n    print('TPU')\nexcept ValueError:\n    if len(tf.config.list_physical_devices('GPU')) > 0:\n        strategy = tf.distribute.MirroredStrategy()\n        print('GPU')\n    else:\n        strategy = tf.distribute.get_strategy()\n        print('CPU')","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:25:53.155506Z","iopub.execute_input":"2022-01-08T05:25:53.155768Z","iopub.status.idle":"2022-01-08T05:25:58.990323Z","shell.execute_reply.started":"2022-01-08T05:25:53.155728Z","shell.execute_reply":"2022-01-08T05:25:58.989716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Khi không sử dụng thêm các pretrain embedding thì private score đạt được là 0.644 có thể xem ở version 4 và đoạn code dưới đây.","metadata":{}},{"cell_type":"code","source":"with strategy.scope():\n    # B4: build model=====================================================================\n    f1 = tfa.metrics.F1Score(num_classes=1, threshold=0.5)\n    print('B4: bulding model....')\n    model = build_Model_LSTM()\n    model.summary()\n\n#     # B5: train model=====================================================================\n#     print('B5: start tranning....')\n#     model.fit(train_X_seq, train_Y, batch_size=batch_size, epochs=num_epochs, \n#               validation_data=(val_X_seq, val_Y), callbacks=callbacks)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:25:58.991314Z","iopub.execute_input":"2022-01-08T05:25:58.991529Z","iopub.status.idle":"2022-01-08T05:26:01.484036Z","shell.execute_reply.started":"2022-01-08T05:25:58.991503Z","shell.execute_reply":"2022-01-08T05:26:01.483088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5.2. Sử dụng model đã huấn luyện để dự đoán","metadata":{}},{"cell_type":"code","source":"# tìm threshold phù hợp để đạt được f1_score cao nhất\ndef best_threshold(y_train,train_preds):\n    f1_score = [0,0,0] # idx, cur, max\n    threshold = 0\n    for f1_score[0] in tqdm(np.arange(0.1, 0.9, 0.01)):\n        f1_score[1] = metrics.f1_score(y_train, np.array(train_preds)>f1_score[0])\n        if f1_score[1] > f1_score[2]:\n            threshold = f1_score[0]\n            f1_score[2] = f1_score[1]\n    print('best threshold: ')\n    print(threshold)\n    print(f1_score[2])\n    return threshold, f1_score[2]","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:26:01.487196Z","iopub.execute_input":"2022-01-08T05:26:01.487475Z","iopub.status.idle":"2022-01-08T05:26:01.495598Z","shell.execute_reply.started":"2022-01-08T05:26:01.487442Z","shell.execute_reply":"2022-01-08T05:26:01.494659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict_by(trained_model):\n    val_pred = trained_model.predict(val_X_seq, verbose=1, batch_size=256)\n    threshold, f1_score = best_threshold(val_Y, val_pred)\n\n    test_pred = trained_model.predict(test_X_seq, verbose=1, batch_size=256)\n\n    print(metrics.classification_report(val_Y,(val_pred>threshold).astype(int)))\n    return threshold, f1_score, val_pred, test_pred\n\n# predict by trained model========================================================\n# with strategy.scope():\n#     test_pred, threshold = predict_by(model)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:26:01.496948Z","iopub.execute_input":"2022-01-08T05:26:01.497662Z","iopub.status.idle":"2022-01-08T05:26:01.507777Z","shell.execute_reply.started":"2022-01-08T05:26:01.497625Z","shell.execute_reply":"2022-01-08T05:26:01.506918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Cải thiện dự đoán bằng cách kết hợp các embedding cho sẵn\nỞ đây em thử nghiệm với 3 loại embedding là:\n- Paragram\n- GloVe - Global Vectors: mô hình là thuật toán học tập không giám sát để tạo ra các biểu diễn vector cho các từ, GloVe học bằng cách xây dựng ma trận đồng xuất hiện, cơ bản là nó tính tần suất một từ xuất hiện trong ngữ cảnh\n- Wiki: hay FastText khá khác với nhúng trên, trong khi GloVe coi đơn vị nhỏ nhất để đào tạo là một từ thì FastText sử dụng các kí tự n-gram làm đơn vị huấn luyện nhỏ nhất. Lợi ích lớn nhất của việc sử dụng FastText là nó tạo ra các nhúng từ tốt hơn cho các từ hiếm hoặc thậm chí là các từ không được tìm ra trong quá trình trainning do các vector kí tự n-gram có khả năng xuất hiện trong các từ khác nhiều hơn. Đây là điều GloVe không thể đạt được.\n    \n    VD: word vector `apple` có thể được chia thành các word vector unit riêng biệt là `ap`, `app`, `ple`.\n","metadata":{}},{"cell_type":"code","source":"def get_coefs(word, *arr): \n    return word, np.asarray(arr, dtype='float32')\n# lấy số dòng của file embedding\ndef get_lines_num(file_name): \n    return sum(1 for _ in open(file_name, encoding=\"utf8\", errors='ignore'))\n# chuyển file embedding thành dict\ndef load_embedding(file_name): \n    print('loading embedding file..')\n    return dict(get_coefs(*o.split(\" \")) for o in tqdm(open(file_name, encoding=\"utf8\", errors='ignore'), \n                                                       total=get_lines_num(file_name)) if len(o) > 100)\n\ndef embedding_matrix(embeddings_vec, features, token_word_index):\n    print('load success. start embedding matrix..')\n    # features = len(tokenizer.word_index)+1\n    # embedding_vec is dict created by load_embedding()\n    all_embs = np.stack(embeddings_vec.values()) \n    emb_mean,emb_std = all_embs.mean(), all_embs.std()\n    embed_size = all_embs.shape[1]\n\n    nb_words = features\n    embedding_matrix = np.random.normal(emb_mean, emb_std, (nb_words, embed_size))\n    print('yes1')\n    for word, i in token_word_index.items():\n        if i >= features: continue\n        embedding_vector = embeddings_vec.get(word) \n        if embedding_vector is not None: embedding_matrix[i] = embedding_vector\n    print('yes2')\n    return embedding_matrix","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:26:01.509265Z","iopub.execute_input":"2022-01-08T05:26:01.509878Z","iopub.status.idle":"2022-01-08T05:26:01.522486Z","shell.execute_reply.started":"2022-01-08T05:26:01.509829Z","shell.execute_reply":"2022-01-08T05:26:01.521347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"GLOVE_PATH = 'glove.840B.300d/glove.840B.300d.txt'\nPARA_PATH = 'paragram_300_sl999/paragram_300_sl999.txt'\nWIKI_PATH = 'wiki-news-300d-1M/wiki-news-300d-1M.vec'\n\n!unzip -n /kaggle/input/quora-insincere-questions-classification/embeddings.zip {GLOVE_PATH} -d .\n\nglove_vec = load_embedding(GLOVE_PATH)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:26:01.523572Z","iopub.execute_input":"2022-01-08T05:26:01.523776Z","iopub.status.idle":"2022-01-08T05:32:19.558864Z","shell.execute_reply.started":"2022-01-08T05:26:01.523752Z","shell.execute_reply":"2022-01-08T05:32:19.557421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### a. Huấn luyện model với GloVe embedding\nKết quả đạt được là f1_score đã tăng lên 0.68 so với f1_score khi không sử dụng nhúng là 0.64. Khi huấn luyện có thêm GloVe ở version 8 thì Private score tăng lên 0.686 ","metadata":{}},{"cell_type":"code","source":"glove_emb_matrix = embedding_matrix(glove_vec, features, tokenizer.word_index)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:32:19.561278Z","iopub.execute_input":"2022-01-08T05:32:19.561698Z","iopub.status.idle":"2022-01-08T05:32:34.568137Z","shell.execute_reply.started":"2022-01-08T05:32:19.561635Z","shell.execute_reply":"2022-01-08T05:32:34.56714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# apply glove\n# TPU\nwith strategy.scope():\n# B4: build model========================================================================\n    f1 = tfa.metrics.F1Score(num_classes=1, threshold=0.5)\n    print('B4: bulding model with glove embedding....')\n    glove_model = build_Model_LSTM(features, EMBEDDING_DIM, learning_rate, glove_emb_matrix)\n    #glove_model.summary()\n\n# B5: train model========================================================================\n    print('B5: start tranning....')\n    glove_model.fit(train_X_seq, train_Y, batch_size=batch_size, epochs=num_epochs, \n              validation_data=(val_X_seq, val_Y), callbacks=callbacks)\n# predict by trained model===============================================================\n    glove_threshold, glove_f1_score, glove_val_pred, glove_test_pred = predict_by(glove_model)\n    \n    ","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:32:34.602779Z","iopub.execute_input":"2022-01-08T05:32:34.603118Z","iopub.status.idle":"2022-01-08T05:41:25.695773Z","shell.execute_reply.started":"2022-01-08T05:32:34.603088Z","shell.execute_reply":"2022-01-08T05:41:25.694751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# giảm tải cho bộ nhớ\ndel glove_vec\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:41:25.698847Z","iopub.execute_input":"2022-01-08T05:41:25.699105Z","iopub.status.idle":"2022-01-08T05:41:27.798846Z","shell.execute_reply.started":"2022-01-08T05:41:25.699073Z","shell.execute_reply":"2022-01-08T05:41:27.798015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### b. Huấn luyện model với wiki","metadata":{}},{"cell_type":"code","source":"!unzip -n /kaggle/input/quora-insincere-questions-classification/embeddings.zip {WIKI_PATH} -d .\n\nwiki_vec = load_embedding(WIKI_PATH)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:41:27.901647Z","iopub.execute_input":"2022-01-08T05:41:27.902018Z","iopub.status.idle":"2022-01-08T05:44:09.156427Z","shell.execute_reply.started":"2022-01-08T05:41:27.901987Z","shell.execute_reply":"2022-01-08T05:44:09.152969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wiki_emb_matrix = embedding_matrix(wiki_vec, features, tokenizer.word_index)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:44:09.16808Z","iopub.execute_input":"2022-01-08T05:44:09.16843Z","iopub.status.idle":"2022-01-08T05:44:22.057111Z","shell.execute_reply.started":"2022-01-08T05:44:09.168385Z","shell.execute_reply":"2022-01-08T05:44:22.056024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# apply wiki\n# TPU\nwith strategy.scope():\n# B4: build model========================================================================\n    f1 = tfa.metrics.F1Score(num_classes=1, threshold=0.5)\n    print('B4: bulding model with glove embedding....')\n    wiki_model = build_Model_LSTM(features, EMBEDDING_DIM, learning_rate, wiki_emb_matrix)\n\n# B5: train model========================================================================\n    print('B5: start tranning....')\n    wiki_model.fit(train_X_seq, train_Y, batch_size=batch_size, epochs=num_epochs, \n              validation_data=(val_X_seq, val_Y), callbacks=callbacks)\n# predict by trained model===============================================================\n    wiki_threshold, wiki_f1_score, wiki_val_pred, wiki_test_pred = predict_by(wiki_model)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:44:22.058823Z","iopub.execute_input":"2022-01-08T05:44:22.05959Z","iopub.status.idle":"2022-01-08T05:54:00.664019Z","shell.execute_reply.started":"2022-01-08T05:44:22.059539Z","shell.execute_reply":"2022-01-08T05:54:00.663364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# giảm tải cho bộ nhớ\ndel wiki_vec\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:54:00.665868Z","iopub.execute_input":"2022-01-08T05:54:00.666098Z","iopub.status.idle":"2022-01-08T05:54:02.418899Z","shell.execute_reply.started":"2022-01-08T05:54:00.66607Z","shell.execute_reply":"2022-01-08T05:54:02.418085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### c. Huấn luyện model với para","metadata":{}},{"cell_type":"code","source":"!unzip -n /kaggle/input/quora-insincere-questions-classification/embeddings.zip {PARA_PATH} -d .\n\npara_vec = load_embedding(PARA_PATH)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:54:02.463047Z","iopub.execute_input":"2022-01-08T05:54:02.463438Z","iopub.status.idle":"2022-01-08T05:59:52.349729Z","shell.execute_reply.started":"2022-01-08T05:54:02.463405Z","shell.execute_reply":"2022-01-08T05:59:52.349023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"para_emb_matrix = embedding_matrix(para_vec, features, tokenizer.word_index)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T05:59:52.351494Z","iopub.execute_input":"2022-01-08T05:59:52.351914Z","iopub.status.idle":"2022-01-08T06:00:05.202411Z","shell.execute_reply.started":"2022-01-08T05:59:52.351867Z","shell.execute_reply":"2022-01-08T06:00:05.201447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# apply para\n# TPU\nwith strategy.scope():\n# B4: build model========================================================================\n    f1 = tfa.metrics.F1Score(num_classes=1, threshold=0.5)\n    print('B4: bulding model with glove embedding....')\n    para_model = build_Model_LSTM(features, EMBEDDING_DIM, learning_rate, para_emb_matrix)\n\n# B5: train model========================================================================\n    print('B5: start tranning....')\n    para_model.fit(train_X_seq, train_Y, batch_size=batch_size, epochs=num_epochs, \n              validation_data=(val_X_seq, val_Y), callbacks=callbacks)\n# predict by trained model===============================================================\n    para_threshold, para_f1_score, para_val_pred, para_test_pred = predict_by(para_model)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:00:05.242989Z","iopub.execute_input":"2022-01-08T06:00:05.244996Z","iopub.status.idle":"2022-01-08T06:08:10.122353Z","shell.execute_reply.started":"2022-01-08T06:00:05.244943Z","shell.execute_reply":"2022-01-08T06:08:10.121381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# giảm tải cho bộ nhớ\ndel para_vec\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:08:10.123526Z","iopub.execute_input":"2022-01-08T06:08:10.12373Z","iopub.status.idle":"2022-01-08T06:08:12.275962Z","shell.execute_reply.started":"2022-01-08T06:08:10.123704Z","shell.execute_reply":"2022-01-08T06:08:12.275029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6. Submission\nKết hợp các kết quả từ 3 mô hình. f1_score ở cả 3 không có sự chênh lệch quá lớn và đều cải thiện độ chính xác hơn so với không sử dụng nên ta lấy trung bình 3 kết quả.","metadata":{}},{"cell_type":"code","source":"val = np.zeros((len(val_X),), dtype=np.float32)\n\nval += 1/3 * np.squeeze(glove_val_pred)\nval += 1/3 * np.squeeze(para_val_pred)\nval += 1/3 *np.squeeze(wiki_val_pred)\nthreshold_global, f1_global = best_threshold(val_Y, val)\nprint(metrics.classification_report(val_Y,(val>threshold_global).astype(int)))\n\npred = np.zeros((len(test_X),), dtype=np.float32)\npred += 1/3 * np.squeeze(glove_test_pred)\npred += 1/3 * np.squeeze(para_test_pred)\npred += 1/3 * np.squeeze(wiki_test_pred)\ntest_pred=((pred>threshold_global).astype(int))\n","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:11:18.619216Z","iopub.execute_input":"2022-01-08T06:11:18.619855Z","iopub.status.idle":"2022-01-08T06:11:25.595448Z","shell.execute_reply.started":"2022-01-08T06:11:18.619809Z","shell.execute_reply":"2022-01-08T06:11:25.594484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Sau khi kết hợp cả 3 embedding ta thấy f1-score có tăng lên một chút so với chạy riêng lẻ với từng embedding.","metadata":{}},{"cell_type":"code","source":"#test_pred = (test_pred>threshold).astype(int)\n\nsubmit = pd.DataFrame({\"qid\":test_df[\"qid\"].values})\nsubmit['prediction'] = test_pred\nsubmit.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T06:11:33.427138Z","iopub.execute_input":"2022-01-08T06:11:33.428227Z","iopub.status.idle":"2022-01-08T06:11:34.429158Z","shell.execute_reply.started":"2022-01-08T06:11:33.428133Z","shell.execute_reply":"2022-01-08T06:11:34.428488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Reference\n- clean data: https://www.exxactcorp.com/blog/Deep-Learning/text-preprocessing-methods-for-deep-learning\n- model with embeddings: https://www.kaggle.com/sbongo/do-pretrained-embeddings-give-you-the-extra-edge","metadata":{}}]}