{"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":"* Họ tên: Phạm Thị Linh \n* Mssv: 18020769 \n* Mã lớp: INT3405 1","metadata":{}},{"cell_type":"markdown","source":"# **1. Đặt vấn đề**\nQuora là một nền tảng cho phép mọi người học hỏi lẫn nhau. Trên Quora, mọi người có thể đặt câu hỏi và kết nối với những người khác, những người đóng góp thông tin chi tiết độc đáo và câu trả lời chất lượng. Một thách thức quan trọng là loại bỏ những câu hỏi thiếu chân thành - những câu hỏi được đặt ra 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\nTrong cuộc thi này, Kagglers sẽ phát triển các mô hình xác định và gắn cờ cho các câu hỏi không chân thành.\n\n**Mô tả bài toán**\n\n* Đầu vào : dữ liệu các câu hỏi dưới dạng text\n* Đầu ra : phân loại được câu hỏi là insincere hay sincere","metadata":{}},{"cell_type":"code","source":"%matplotlib inline\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nfrom subprocess import check_output\n\n%matplotlib inline\nimport plotly.offline as py\npy.init_notebook_mode(connected=True)\nimport plotly.graph_objs as go\nimport plotly.tools as tls\n\nimport os\nimport gc\nimport csv\nimport re\nimport string\n\nfrom tqdm import tqdm\nfrom collections import Counter\nfrom wordcloud import WordCloud, STOPWORDS\nfrom scipy.sparse import hstack\nfrom IPython.display import Image\nfrom tqdm import tqdm_notebook\ntqdm_notebook().pandas()\n\nfrom nltk.corpus import stopwords\nfrom nltk.stem import PorterStemmer, SnowballStemmer, WordNetLemmatizer\nfrom nltk.stem.lancaster import LancasterStemmer\nfrom nltk.util import ngrams","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:05:54.824564Z","iopub.execute_input":"2022-01-07T16:05:54.825123Z","iopub.status.idle":"2022-01-07T16:05:56.857283Z","shell.execute_reply.started":"2022-01-07T16:05:54.825000Z","shell.execute_reply":"2022-01-07T16:05:56.856550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import nltk\nnltk.download('wordnet')\nnltk.download('punkt')\nnltk.download('stopwords')","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:06:01.535676Z","iopub.execute_input":"2022-01-07T16:06:01.536101Z","iopub.status.idle":"2022-01-07T16:06:01.813263Z","shell.execute_reply.started":"2022-01-07T16:06:01.536070Z","shell.execute_reply":"2022-01-07T16:06:01.812356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **2. Đọc và phân tích dữ liệu**\n**2.1. Đọc dữ liệu**\n\nDữ liệu được cung cấp gồm 2 file train.csv và test.csv","metadata":{}},{"cell_type":"code","source":"#Đọc dữ liệu từ file data\ntrain = pd.read_csv(\"../input/quora-insincere-questions-classification/train.csv\")\n#Đọc dữ liệu từ file test \ntest=pd.read_csv(\"../input/quora-insincere-questions-classification/test.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:06:05.213003Z","iopub.execute_input":"2022-01-07T16:06:05.213302Z","iopub.status.idle":"2022-01-07T16:06:12.966895Z","shell.execute_reply.started":"2022-01-07T16:06:05.213270Z","shell.execute_reply":"2022-01-07T16:06:12.966278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**2.2. Phân tích dữ liệu**","metadata":{}},{"cell_type":"code","source":"train","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:20:16.478948Z","iopub.execute_input":"2022-01-07T16:20:16.479254Z","iopub.status.idle":"2022-01-07T16:20:16.494791Z","shell.execute_reply.started":"2022-01-07T16:20:16.479221Z","shell.execute_reply":"2022-01-07T16:20:16.493899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Dữ liệu:\n* 1306122 hàng × 3 cột\n* qid: id độc nhất của câu hỏi, qid chắc sẽ không tham gia vào bước phân lớp câu hỏi nên có thể bỏ được\n* question_text: dữ liệu câu hỏi, do trường này là duy nhất tác động trực tiếp vào phân lớp của câu hỏi nên cần phải thực hiện tiền xử lý\n* target: phân lớp của câu hỏi, target = 0 với câu hỏi sincere và target = 1 với câu hỏi incinsere","metadata":{}},{"cell_type":"code","source":"train.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:06:21.756247Z","iopub.execute_input":"2022-01-07T16:06:21.756552Z","iopub.status.idle":"2022-01-07T16:06:22.078398Z","shell.execute_reply.started":"2022-01-07T16:06:21.756522Z","shell.execute_reply":"2022-01-07T16:06:22.077701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:06:25.548065Z","iopub.execute_input":"2022-01-07T16:06:25.548867Z","iopub.status.idle":"2022-01-07T16:06:25.646412Z","shell.execute_reply.started":"2022-01-07T16:06:25.548798Z","shell.execute_reply":"2022-01-07T16:06:25.645646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Train shape :\", train.shape)\nprint(\"Test shape :\", test.shape)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:06:57.521537Z","iopub.execute_input":"2022-01-07T16:06:57.522436Z","iopub.status.idle":"2022-01-07T16:06:57.527647Z","shell.execute_reply.started":"2022-01-07T16:06:57.522379Z","shell.execute_reply":"2022-01-07T16:06:57.527061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Tập dữ liệu train có 1306122 câu hỏi và tập test chứa 375806 câu hỏi để đánh giá hiệu năng mô hình. Trong đó, không có dữ liệu nào bất thường (missing, null) trong cả hai tập.","metadata":{}},{"cell_type":"code","source":"train.groupby(\"target\")['qid'].count().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:24:53.866721Z","iopub.execute_input":"2022-01-07T16:24:53.867032Z","iopub.status.idle":"2022-01-07T16:24:54.385399Z","shell.execute_reply.started":"2022-01-07T16:24:53.866998Z","shell.execute_reply":"2022-01-07T16:24:54.384546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"toxic = train[train.target == 1]\nnon_toxic = train[train.target == 0]\nprint(toxic.shape, non_toxic.shape)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:30:31.626017Z","iopub.execute_input":"2022-01-07T16:30:31.626731Z","iopub.status.idle":"2022-01-07T16:30:31.736519Z","shell.execute_reply.started":"2022-01-07T16:30:31.626667Z","shell.execute_reply":"2022-01-07T16:30:31.735520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('%Insincere Questions : {}%'.format(round(train['target'].mean()*100, 2)))","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:45:21.032851Z","iopub.execute_input":"2022-01-07T16:45:21.033135Z","iopub.status.idle":"2022-01-07T16:45:21.040671Z","shell.execute_reply.started":"2022-01-07T16:45:21.033106Z","shell.execute_reply":"2022-01-07T16:45:21.039753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Nhận xét: số lượng câu hỏi sincerce-insincere có sự chênh lệch rất lớn:\n> \n> * Số lượng câu hỏi sincerce chiếm đến gần 94% tập dữ liệu (1225312 câu)\n> * Số lượng câu hỏi insincere chiếm 6.2% tập dữ liệu (80810 câu)\n> \n> -> Dữ liệu này mất cân bằng rất lớn\n> \n> -> Cần áp dụng các phương pháp cân bằng dữ liệu, chia lại tập dữ liệu sao cho câu hỏi toxic và không toxic trở nên cân bằng hơn.","metadata":{}},{"cell_type":"markdown","source":"**2.3. Xử lí mất cân bằng dữ liệu**\n\nHai cách tiếp cận để tạo ra một tập dữ liệu cân bằng trong một tập dữ liệu không cân bằng là under-sampling và oversampling.\n* Under-sampling: việc lấy mẫu làm cân bằng tập dữ liệu bằng cách giảm kích thước của lớp trội. Phương pháp này được sử dụng khi số lượng dữ liệu là đủ. Bằng cách giữ tất cả các mẫu trong lớp hiếm và chọn ngẫu nhiên một số trong lớp trội, một tập dữ liệu cân bằng mới có thể được lấy ra để lập mô hình tiếp theo.\n* Over-sampling: ngược lại, oversampling được sử dụng khi số lượng dữ liệu không đủ. Nó cố gắng cân bằng số liệu bằng cách tăng kích thước của các mẫu hiếm. Thay vì loại bỏ các mẫu phong phú, các mẫu hiếm mới được tạo ra.","metadata":{}},{"cell_type":"code","source":"from sklearn.utils import resample\nsincere = train[train.target == 0]\ninsincere = train[train.target == 1]\n# Tỉ lệ 4:1 cho kết quả tốt nhất\nx = pd.concat([resample(sincere,replace = True,n_samples = len(insincere)*4), insincere])","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:48:24.732446Z","iopub.execute_input":"2022-01-07T16:48:24.732766Z","iopub.status.idle":"2022-01-07T16:48:25.026353Z","shell.execute_reply.started":"2022-01-07T16:48:24.732733Z","shell.execute_reply":"2022-01-07T16:48:25.025399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y = x['target']\ny.value_counts().plot(kind='bar', rot=0)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:48:32.065004Z","iopub.execute_input":"2022-01-07T16:48:32.065267Z","iopub.status.idle":"2022-01-07T16:48:32.252986Z","shell.execute_reply.started":"2022-01-07T16:48:32.065239Z","shell.execute_reply":"2022-01-07T16:48:32.252128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* Sau khi chia lại dữ liệu ta thấy tập dữ liệu đã cân bằng hơn trước","metadata":{}},{"cell_type":"markdown","source":"# **3. Xử lý dữ liệu**\n**3.1. Chuẩn bị dữ liệu**\n\n* Word tokenization: phân tách các từ trong câu là bước cần thiết nhất để xử lý văn bản. Nó giúp tách các câu thành danh sách các từ được phân tách bằng dấu phẩy một cách hiệu quả.\n* Loại bỏ stopword (các từ thêm nghĩa cho câu như a, an, the,... ): do không có giá trị khai thác nên cần loại bỏđể không ảnh hưởng tới mô hình\n* Tìm từ gốc: từ gốc là từ cấu thành nên các từ khác. VD: Do là từ gốc tạo ra các từ do, does, doing,... Có 2 cách tiếp cận là dùng Lemmatization và Stemming.\n    * Lemmatization : là một phương pháp nhóm các từ thành một thuật ngữ duy nhất dựa trên sự biến đổi của chúng.\n    * Stemming : là phương pháp khác được sử dụng để liên kết các từ với các từ gốc. Đó là quá trình xác định các biến thể của các từ cơ sở.\n> Cả hai cách tiếp cận này đều hiệu quả trong project này nên chúng ta sẽ sử dụng cả hai.\n\n* Text Vectorization giúp chuyển đổi văn bản dữ liệu thành một chuỗi các số để xử lý. Hai cách tiếp cận phổ biến nhất là TF-IDF và Bag of Words.\n* Chia tập dữ liệu: tập dữ liệu sẽ được chia theo tỉ lệ 80:20, ứng với tập train và tập test\n* Modeling: mô hình được sử dụng cho bài toán này là Logistic Regression và Gradient Boosting","metadata":{}},{"cell_type":"code","source":"#loại bỏ các từ trong stopword\nstopword_list = nltk.corpus.stopwords.words('english')\ndef remove_stopwords(text, is_lower_case=True):\n    tokenizer = ToktokTokenizer()\n    tokens = tokenizer.tokenize(text)\n    tokens = [token.strip() for token in tokens]\n    if is_lower_case:\n        filtered_tokens = [token for token in tokens if token not in stopword_list]\n    else:\n        filtered_tokens = [token for token in tokens if token.lower() not in stopword_list]\n    filtered_text = ' '.join(filtered_tokens)\n    return filtered_text","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:27:24.260270Z","iopub.execute_input":"2022-01-07T17:27:24.260995Z","iopub.status.idle":"2022-01-07T17:27:24.270168Z","shell.execute_reply.started":"2022-01-07T17:27:24.260951Z","shell.execute_reply":"2022-01-07T17:27:24.269557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Stemming\nfrom nltk.stem import  SnowballStemmer\nfrom nltk.tokenize.toktok import ToktokTokenizer\ndef stem_text(text):\n    tokenizer = ToktokTokenizer()\n    stemmer = SnowballStemmer('english')\n    tokens = tokenizer.tokenize(text)\n    tokens = [token.strip() for token in tokens]\n    tokens = [stemmer.stem(token) for token in tokens]\n    return ' '.join(tokens)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:27:29.034270Z","iopub.execute_input":"2022-01-07T17:27:29.034648Z","iopub.status.idle":"2022-01-07T17:27:29.041858Z","shell.execute_reply.started":"2022-01-07T17:27:29.034609Z","shell.execute_reply":"2022-01-07T17:27:29.040784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Lemmatization\nfrom nltk.stem import WordNetLemmatizer\nfrom nltk.tokenize.toktok import ToktokTokenizer\nwordnet_lemmatizer = WordNetLemmatizer()\ndef lemma_text(text):\n    tokenizer = ToktokTokenizer()\n    tokens = tokenizer.tokenize(text)\n    tokens = [token.strip() for token in tokens]\n    tokens = [wordnet_lemmatizer.lemmatize(token) for token in tokens]\n    return ' '.join(tokens)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:27:31.929229Z","iopub.execute_input":"2022-01-07T17:27:31.930150Z","iopub.status.idle":"2022-01-07T17:27:31.937786Z","shell.execute_reply.started":"2022-01-07T17:27:31.930097Z","shell.execute_reply":"2022-01-07T17:27:31.936825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**3.2. Xử lí dữ liệu**\n\nQua phân tích ở trên ta thấy dữ liệu có có những tác nhân gây nhiễu hoặc không cần thiết , dư thừa để xác nhận xem câu hỏi có phải toxic hay không . Qua đó chúng ta sẽ tìm cách loại bỏ nó :\n* Loại bỏ những kí tự đặc biệt có trong câu\n* Loại bỏ dấu câu\n* Loại bỏ chữ số\n* Thay thế những từ sai chính tả\n* Thay thế các từ viết tắt\n* Loại bỏ những từ là stop word ( ví dụ \"a\" , \"an\", \"the\" ,...)\n* Biến đổi 1 từ về dạng gốc (được gọi là stem hoặc root form) bằng cách loại bỏ 1 số ký tự nằm ở cuối từ mà nó nghĩ rằng là biến thể của từ giống như trên nhưng xử lý bằng cách loại bỏ các ký tự cuối từ theo thuật toán heuristic (lemmatization)","metadata":{}},{"cell_type":"code","source":"puncts=[',', '.', '\"', ':', ')', '(', '-', '!', '?', '|', ';', \"'\", '$', '&', '/', '[', ']', '>', '%', '=', '#', '*', '+', '\\\\', \n        '•', '~', '@', '£', '·', '_', '{', '}', '©', '^', '®', '`', '<', '→', '°', '€', '™', '›', '♥', '←', '×', '§', '″', '′', \n        '█', '…', '“', '★', '”', '–', '●', '►', '−', '¢', '¬', '░', '¡', '¶', '↑', '±', '¿', '▾', '═', '¦', '║', '―', '¥', '▓', \n        '—', '‹', '─', '▒', '：', '⊕', '▼', '▪', '†', '■', '’', '▀', '¨', '▄', '♫', '☆', '¯', '♦', '¤', '▲', '¸', '⋅', '‘', '∞', \n        '∙', '）', '↓', '、', '│', '（', '»', '，', '♪', '╩', '╚', '・', '╦', '╣', '╔', '╗', '▬', '❤', '≤', '‡', '√', '◄', '━', \n        '⇒', '▶', '≥', '╝', '♡', '◊', '。', '✈', '≡', '☺', '✔', '↵', '≈', '✓', '♣', '☎', '℃', '◦', '└', '‟', '～', '！', '○', \n        '◆', '№', '♠', '▌', '✿', '▸', '⁄', '□', '❖', '✦', '．', '÷', '｜', '┃', '／', '￥', '╠', '↩', '✭', '▐', '☼', '☻', '┐', \n        '├', '«', '∼', '┌', '℉', '☮', '฿', '≦', '♬', '✧', '〉', '－', '⌂', '✖', '･', '◕', '※', '‖', '◀', '‰', '\\x97', '↺', \n        '∆', '┘', '┬', '╬', '،', '⌘', '⊂', '＞', '〈', '⎙', '？', '☠', '⇐', '▫', '∗', '∈', '≠', '♀', '♔', '˚', '℗', '┗', '＊', \n        '┼', '❀', '＆', '∩', '♂', '‿', '∑', '‣', '➜', '┛', '⇓', '☯', '⊖', '☀', '┳', '；', '∇', '⇑', '✰', '◇', '♯', '☞', '´', \n        '↔', '┏', '｡', '◘', '∂', '✌', '♭', '┣', '┴', '┓', '✨', '\\xa0', '˜', '❥', '┫', '℠', '✒', '［', '∫', '\\x93', '≧', '］', \n        '\\x94', '∀', '♛', '\\x96', '∨', '◎', '↻', '⇩', '＜', '≫', '✩', '✪', '♕', '؟', '₤', '☛', '╮', '␊', '＋', '┈', '％', \n        '╋', '▽', '⇨', '┻', '⊗', '￡', '।', '▂', '✯', '▇', '＿', '➤', '✞', '＝', '▷', '△', '◙', '▅', '✝', '∧', '␉', '☭', \n        '┊', '╯', '☾', '➔', '∴', '\\x92', '▃', '↳', '＾', '׳', '➢', '╭', '➡', '＠', '⊙', '☢', '˝', '∏', '„', '∥', '❝', '☐', \n        '▆', '╱', '⋙', '๏', '☁', '⇔', '▔', '\\x91', '➚', '◡', '╰', '\\x85', '♢', '˙', '۞', '✘', '✮', '☑', '⋆', 'ⓘ', '❒', \n        '☣', '✉', '⌊', '➠', '∣', '❑', '◢', 'ⓒ', '\\x80', '〒', '∕', '▮', '⦿', '✫', '✚', '⋯', '♩', '☂', '❞', '‗', '܂', '☜', \n        '‾', '✜', '╲', '∘', '⟩', '＼', '⟨', '·', '✗', '♚', '∅', 'ⓔ', '◣', '͡', '‛', '❦', '◠', '✄', '❄', '∃', '␣', '≪', '｢', \n        '≅', '◯', '☽', '∎', '｣', '❧', '̅', 'ⓐ', '↘', '⚓', '▣', '˘', '∪', '⇢', '✍', '⊥', '＃', '⎯', '↠', '۩', '☰', '◥', \n        '⊆', '✽', '⚡', '↪', '❁', '☹', '◼', '☃', '◤', '❏', 'ⓢ', '⊱', '➝', '̣', '✡', '∠', '｀', '▴', '┤', '∝', '♏', 'ⓐ', \n        '✎', ';', '␤', '＇', '❣', '✂', '✤', 'ⓞ', '☪', '✴', '⌒', '˛', '♒', '＄', '✶', '▻', 'ⓔ', '◌', '◈', '❚', '❂', '￦', \n        '◉', '╜', '̃', '✱', '╖', '❉', 'ⓡ', '↗', 'ⓣ', '♻', '➽', '׀', '✲', '✬', '☉', '▉', '≒', '☥', '⌐', '♨', '✕', 'ⓝ', \n        '⊰', '❘', '＂', '⇧', '̵', '➪', '▁', '▏', '⊃', 'ⓛ', '‚', '♰', '́', '✏', '⏑', '̶', 'ⓢ', '⩾', '￠', '❍', '≃', '⋰', '♋', \n        '､', '̂', '❋', '✳', 'ⓤ', '╤', '▕', '⌣', '✸', '℮', '⁺', '▨', '╨', 'ⓥ', '♈', '❃', '☝', '✻', '⊇', '≻', '♘', '♞', \n        '◂', '✟', '⌠', '✠', '☚', '✥', '❊', 'ⓒ', '⌈', '❅', 'ⓡ', '♧', 'ⓞ', '▭', '❱', 'ⓣ', '∟', '☕', '♺', '∵', '⍝', 'ⓑ', \n        '✵', '✣', '٭', '♆', 'ⓘ', '∶', '⚜', '◞', '்', '✹', '➥', '↕', '̳', '∷', '✋', '➧', '∋', '̿', 'ͧ', '┅', '⥤', '⬆', '⋱', \n        '☄', '↖', '⋮', '۔', '♌', 'ⓛ', '╕', '♓', '❯', '♍', '▋', '✺', '⭐', '✾', '♊', '➣', '▿', 'ⓑ', '♉', '⏠', '◾', '▹', \n        '⩽', '↦', '╥', '⍵', '⌋', '։', '➨', '∮', '⇥', 'ⓗ', 'ⓓ', '⁻', '⎝', '⌥', '⌉', '◔', '◑', '✼', '♎', '♐', '╪', '⊚', \n        '☒', '⇤', 'ⓜ', '⎠', '◐', '⚠', '╞', '◗', '⎕', 'ⓨ', '☟', 'ⓟ', '♟', '❈', '↬', 'ⓓ', '◻', '♮', '❙', '♤', '∉', '؛', \n        '⁂', 'ⓝ', '־', '♑', '╫', '╓', '╳', '⬅', '☔', '☸', '┄', '╧', '׃', '⎢', '❆', '⋄', '⚫', '̏', '☏', '➞', '͂', '␙', \n        'ⓤ', '◟', '̊', '⚐', '✙', '↙', '̾', '℘', '✷', '⍺', '❌', '⊢', '▵', '✅', 'ⓖ', '☨', '▰', '╡', 'ⓜ', '☤', '∽', '╘', \n        '˹', '↨', '♙', '⬇', '♱', '⌡', '⠀', '╛', '❕', '┉', 'ⓟ', '̀', '♖', 'ⓚ', '┆', '⎜', '◜', '⚾', '⤴', '✇', '╟', '⎛', \n        '☩', '➲', '➟', 'ⓥ', 'ⓗ', '⏝', '◃', '╢', '↯', '✆', '˃', '⍴', '❇', '⚽', '╒', '̸', '♜', '☓', '➳', '⇄', '☬', '⚑', \n        '✐', '⌃', '◅', '▢', '❐', '∊', '☈', '॥', '⎮', '▩', 'ு', '⊹', '‵', '␔', '☊', '➸', '̌', '☿', '⇉', '⊳', '╙', 'ⓦ', \n        '⇣', '｛', '̄', '↝', '⎟', '▍', '❗', '״', '΄', '▞', '◁', '⛄', '⇝', '⎪', '♁', '⇠', '☇', '✊', 'ி', '｝', '⭕', '➘', \n        '⁀', '☙', '❛', '❓', '⟲', '⇀', '≲', 'ⓕ', '⎥', '\\u06dd', 'ͤ', '₋', '̱', '̎', '♝', '≳', '▙', '➭', '܀', 'ⓖ', '⇛', '▊', \n        '⇗', '̷', '⇱', '℅', 'ⓧ', '⚛', '̐', '̕', '⇌', '␀', '≌', 'ⓦ', '⊤', '̓', '☦', 'ⓕ', '▜', '➙', 'ⓨ', '⌨', '◮', '☷', \n        '◍', 'ⓚ', '≔', '⏩', '⍳', '℞', '┋', '˻', '▚', '≺', 'ْ', '▟', '➻', '̪', '⏪', '̉', '⎞', '┇', '⍟', '⇪', '▎', '⇦', '␝', \n        '⤷', '≖', '⟶', '♗', '̴', '♄', 'ͨ', '̈', '❜', '̡', '▛', '✁', '➩', 'ா', '˂', '↥', '⏎', '⎷', '̲', '➖', '↲', '⩵', '̗', '❢', \n        '≎', '⚔', '⇇', '̑', '⊿', '̖', '☍', '➹', '⥊', '⁁', '✢']\n#loại bỏ kí tự đặc biệt\ndef clean_punct(text):\n    for punct in puncts:\n        if punct in text:\n            text = text.replace(punct, '{}' .format(punct))\n    return text","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:27:36.768122Z","iopub.execute_input":"2022-01-07T17:27:36.769019Z","iopub.status.idle":"2022-01-07T17:27:36.812191Z","shell.execute_reply.started":"2022-01-07T17:27:36.768954Z","shell.execute_reply":"2022-01-07T17:27:36.811436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#loại bỏ chữ số \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","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:27:39.912223Z","iopub.execute_input":"2022-01-07T17:27:39.912709Z","iopub.status.idle":"2022-01-07T17:27:39.919743Z","shell.execute_reply.started":"2022-01-07T17:27:39.912676Z","shell.execute_reply":"2022-01-07T17:27:39.918517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mispell_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', \n                'electroneum':'bitcoin','nanodegree':'degree','hotstar':'star','dream11':'dream','ftre':'fire','tensorflow':'framework','unocoin':'bitcoin',\n                'lnmiit':'limit','unacademy':'academy','altcoin':'bitcoin','altcoins':'bitcoin','litecoin':'bitcoin','coinbase':'bitcoin','cryptocurency':'cryptocurrency',\n                'simpliv':'simple','quoras':'quora','schizoids':'psychopath','remainers':'remainder','twinflame':'soulmate','quorans':'quora','brexit':'demonetized',\n                'iiest':'institute','dceu':'comics','pessat':'exam','uceed':'college','bhakts':'devotee','boruto':'anime',\n                'cryptocoin':'bitcoin','blockchains':'blockchain','fiancee':'fiance','redmi':'smartphone','oneplus':'smartphone','qoura':'quora','deepmind':'framework','ryzen':'cpu','whattsapp':'whatsapp',\n                'undertale':'adventure','zenfone':'smartphone','cryptocurencies':'cryptocurrencies','koinex':'bitcoin','zebpay':'bitcoin','binance':'bitcoin','whtsapp':'whatsapp',\n                'reactjs':'framework','bittrex':'bitcoin','bitconnect':'bitcoin','bitfinex':'bitcoin','yourquote':'your quote','whyis':'why is','jiophone':'smartphone',\n                'dogecoin':'bitcoin','onecoin':'bitcoin','poloniex':'bitcoin','7700k':'cpu','angular2':'framework','segwit2x':'bitcoin','hashflare':'bitcoin','940mx':'gpu',\n                'openai':'framework','hashflare':'bitcoin','1050ti':'gpu','nearbuy':'near buy','freebitco':'bitcoin','antminer':'bitcoin','filecoin':'bitcoin','whatapp':'whatsapp',\n                'empowr':'empower','1080ti':'gpu','crytocurrency':'cryptocurrency','8700k':'cpu','whatsaap':'whatsapp','g4560':'cpu','payymoney':'pay money',\n                'fuckboys':'fuck boys','intenship':'internship','zcash':'bitcoin','demonatisation':'demonetization','narcicist':'narcissist','mastuburation':'masturbation',\n                'trignometric':'trigonometric','cryptocurreny':'cryptocurrency','howdid':'how did','crytocurrencies':'cryptocurrencies','phycopath':'psychopath',\n                'bytecoin':'bitcoin','possesiveness':'possessiveness','scollege':'college','humanties':'humanities','altacoin':'bitcoin','demonitised':'demonetized',\n                'brasília':'brazilia','accolite':'accolyte','econimics':'economics','varrier':'warrier','quroa':'quora','statergy':'strategy','langague':'language',\n                'splatoon':'game','7600k':'cpu','gate2018':'gate 2018','in2018':'in 2018','narcassist':'narcissist','jiocoin':'bitcoin','hnlu':'hulu','7300hq':'cpu',\n                'weatern':'western','interledger':'blockchain','deplation':'deflation', 'cryptocurrencies':'cryptocurrency', 'bitcoin':'blockchain cryptocurrency',}\n#Thay thế các từ sai chính tả\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 replace_typical_misspell(text):\n    def replace(match):\n        return mispellings[match.group(0)]\n    return mispellings_re.sub(replace, text)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:27:47.714023Z","iopub.execute_input":"2022-01-07T17:27:47.714307Z","iopub.status.idle":"2022-01-07T17:27:47.741157Z","shell.execute_reply.started":"2022-01-07T17:27:47.714276Z","shell.execute_reply":"2022-01-07T17:27:47.740379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"contraction_dict = {\n \"ain't\": \"is not\", \"aren't\": \"are not\",\"can't\": \"cannot\", \"'cause\": \"because\", \n \"could've\": \"could have\", \"couldn't\": \"could not\", \"didn't\": \"did not\",  \"doesn't\": \"does not\", \n \"don't\": \"do not\", \"hadn't\": \"had not\", \"hasn't\": \"has not\", \"haven't\": \"have not\", \n \"he'd\": \"he would\",\"he'll\": \"he will\", \"he's\": \"he is\", \"how'd\": \"how did\", \n \"how'd'y\": \"how do you\", \"how'll\": \"how will\", \"how's\": \"how is\",  \"I'd\": \"I would\", \n \"I'd've\": \"I would have\", \"I'll\": \"I will\", \"I'll've\": \"I will have\",\"I'm\": \"I am\", \n \"I've\": \"I have\", \"i'd\": \"i would\", \"i'd've\": \"i would have\", \"i'll\": \"i will\",  \n \"i'll've\": \"i will have\",\"i'm\": \"i am\", \"i've\": \"i have\", \"isn't\": \"is not\", \"it'd\": \"it would\", \n \"it'd've\": \"it would have\", \"it'll\": \"it will\", \"it'll've\": \"it will have\",\"it's\": \"it is\", \"let's\": \"let us\", \n \"ma'am\": \"madam\", \"mayn't\": \"may not\", \"might've\": \"might have\",\"mightn't\": \"might not\",\n \"mightn't've\": \"might not have\", \"must've\": \"must have\", \"mustn't\": \"must not\", \"mustn't've\": \"must not have\", \n \"needn't\": \"need not\", \"needn't've\": \"need not have\",\"o'clock\": \"of the clock\", \"oughtn't\": \"ought not\", \n \"oughtn't've\": \"ought not have\", \"shan't\": \"shall not\", \"sha'n't\": \"shall not\", \"shan't've\": \"shall not have\", \n \"she'd\": \"she would\", \"she'd've\": \"she would have\", \"she'll\": \"she will\", \"she'll've\": \"she will have\", \n \"she's\": \"she is\", \"should've\": \"should have\", \"shouldn't\": \"should not\", \"shouldn't've\": \"should not have\", \n \"so've\": \"so have\",\"so's\": \"so as\", \"this's\": \"this is\",\"that'd\": \"that would\", \"that'd've\": \"that would have\", \n \"that's\": \"that is\", \"there'd\": \"there would\", \"there'd've\": \"there would have\", \"there's\": \"there is\", \n \"here's\": \"here is\",\"they'd\": \"they would\", \"they'd've\": \"they would have\", \"they'll\": \"they will\", \n \"they'll've\": \"they will have\", \"they're\": \"they are\", \"they've\": \"they have\", \"to've\": \"to have\", \n \"wasn't\": \"was not\", \"we'd\": \"we would\", \"we'd've\": \"we would have\", \"we'll\": \"we will\", \"we'll've\": \"we will have\", \n \"we're\": \"we are\", \"we've\": \"we have\", \"weren't\": \"were not\", \"what'll\": \"what will\", \"what'll've\": \"what will have\",\n \"what're\": \"what are\",  \"what's\": \"what is\", \"what've\": \"what have\", \"when's\": \"when is\", \"when've\": \"when have\", \n \"where'd\": \"where did\", \"where's\": \"where is\", \"where've\": \"where have\", \"who'll\": \"who will\", \"who'll've\": \"who will have\",\n \"who's\": \"who is\", \"who've\": \"who have\", \"why's\": \"why is\", \"why've\": \"why have\", \"will've\": \"will have\", \n \"won't\": \"will not\", \"won't've\": \"will not have\", \"would've\": \"would have\", \"wouldn't\": \"would not\", \n \"wouldn't've\": \"would not have\", \"y'all\": \"you all\", \"y'all'd\": \"you all would\",\"y'all'd've\": \"you all would have\",\n \"y'all're\": \"you all are\",\"y'all've\": \"you all have\",\"you'd\": \"you would\", \"you'd've\": \"you would have\", \n \"you'll\": \"you will\", \"you'll've\": \"you will have\", \"you're\": \"you are\", \"you've\": \"you have\"}\n#Thay thế các từ viết tắt\ndef _get_contractions(contraction_dict):\n    contraction_re = re.compile('(%s)' % '|'.join(contraction_dict.keys()))\n    return contraction_dict, contraction_re\n\ncontractions, contractions_re = _get_contractions(contraction_dict)\n\ndef replace_contractions(text):\n    def replace(match):\n        return contractions[match.group(0)]\n    return contractions_re.sub(replace, text)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:27:53.515638Z","iopub.execute_input":"2022-01-07T17:27:53.516126Z","iopub.status.idle":"2022-01-07T17:27:53.536256Z","shell.execute_reply.started":"2022-01-07T17:27:53.516081Z","shell.execute_reply":"2022-01-07T17:27:53.535382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def clean_sentence(x):\n    x = x.lower()\n    x = clean_punct(x)\n    x = clean_numbers(x)\n    x = replace_typical_misspell(x)\n#   x = remove_stopwords(x)\n    x = replace_contractions(x)\n    x = stem_text(x)\n    x = lemma_text(x)\n    x = x.replace(\"'\",\"\")\n    return x","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:27:57.849186Z","iopub.execute_input":"2022-01-07T17:27:57.849774Z","iopub.status.idle":"2022-01-07T17:27:57.855993Z","shell.execute_reply.started":"2022-01-07T17:27:57.849726Z","shell.execute_reply":"2022-01-07T17:27:57.855100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x['question_text'] = x['question_text'].apply(lambda x: clean_sentence(x))\ntest['question_text'] = test['question_text'].apply(lambda x: clean_sentence(x))","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:28:02.752239Z","iopub.execute_input":"2022-01-07T17:28:02.752523Z","iopub.status.idle":"2022-01-07T17:35:03.610748Z","shell.execute_reply.started":"2022-01-07T17:28:02.752492Z","shell.execute_reply":"2022-01-07T17:35:03.609829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**3.3. Phân tích các nhãn được trích xuất bằng word cloud**\n* Word Cloud là một kỹ thuật trực quan hóa dữ liệu được sử dụng để biểu diễn dữ liệu văn bản, trong đó kích thước của mỗi từ cho biết tần suất hoặc tầm quan trọng của nó. Tạo word cloud để thấy được các từ xuất hiện thường xuyên nhất trong những câu hỏi toxic hay không toxic.\n* Các từ có kích thước càng lớn thì tần suất xuất hiện càng nhiều","metadata":{}},{"cell_type":"code","source":"def cloud(text, title, size = (10,7)):\n    words_list = text.unique().tolist()\n    words = ' '.join(words_list)\n    \n    wordcloud = WordCloud(width=800, height=400,\n                          collocations=False\n                         ).generate(words)\n    \n    fig = plt.figure(figsize=size, dpi=80, facecolor='k',edgecolor='k')\n    plt.imshow(wordcloud,interpolation='bilinear')\n    plt.axis('off')\n    plt.title(title, fontsize=25,color='w')\n    plt.tight_layout(pad=0)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:35:18.356412Z","iopub.execute_input":"2022-01-07T17:35:18.356677Z","iopub.status.idle":"2022-01-07T17:35:18.363861Z","shell.execute_reply.started":"2022-01-07T17:35:18.356649Z","shell.execute_reply":"2022-01-07T17:35:18.363179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cloud(train[train['target']==0]['question_text'], 'Sincere Questions On Question_text')","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:35:41.111804Z","iopub.execute_input":"2022-01-07T17:35:41.112726Z","iopub.status.idle":"2022-01-07T17:36:05.690689Z","shell.execute_reply.started":"2022-01-07T17:35:41.112669Z","shell.execute_reply":"2022-01-07T17:36:05.678390Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cloud(x[x['target']==0]['question_text'], 'Sincere Questions On Question_text')","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:37:23.589651Z","iopub.execute_input":"2022-01-07T17:37:23.590521Z","iopub.status.idle":"2022-01-07T17:37:30.329913Z","shell.execute_reply.started":"2022-01-07T17:37:23.590478Z","shell.execute_reply":"2022-01-07T17:37:30.329300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cloud(train[train['target']==1]['question_text'], 'Insincere Questions On question_text')","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:37:35.366288Z","iopub.execute_input":"2022-01-07T17:37:35.367107Z","iopub.status.idle":"2022-01-07T17:37:38.812321Z","shell.execute_reply.started":"2022-01-07T17:37:35.367041Z","shell.execute_reply":"2022-01-07T17:37:38.811483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cloud(x[x['target']==1]['question_text'], 'Insincere Questions On question_text')","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:37:43.221720Z","iopub.execute_input":"2022-01-07T17:37:43.222000Z","iopub.status.idle":"2022-01-07T17:37:46.422605Z","shell.execute_reply.started":"2022-01-07T17:37:43.221967Z","shell.execute_reply":"2022-01-07T17:37:46.421636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Nhận xét :\n> * Các câu hỏi insincere thường có nhiều các từ mang nghĩa xấu\n> * Tuy nhiên một số các từ không mang nghĩa xấu có tần suất cao như people, will, many, much. Các từ này thuộc stopwords, tức là các từ cần thiết trong ngữ pháp nhưng không mang lại nhiều ý nghĩa khi xét từng từ riêng lẻ.","metadata":{}},{"cell_type":"markdown","source":"> Nhận xét :\n> * Các câu hỏi insincere thường có nhiều các từ mang nghĩa xấu; các từ về sắc tộc, tôn giáo , giới tính xuất hiện nhiều : white , black , muslim , islam , ....\n> * Tuy nhiên một số các từ không mang nghĩa xấu có tần suất cao như people, will, many, much. Các từ này thuộc stopwords, tức là các từ cần thiết trong ngữ pháp nhưng không mang lại nhiều ý nghĩa khi xét từng từ riêng lẻ.","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nfrom sklearn.metrics import accuracy_score, log_loss\nfrom sklearn.feature_extraction.text import CountVectorizer\nfrom sklearn.model_selection import train_test_split\nimport math\nfrom sklearn.metrics import normalized_mutual_info_score\nfrom sklearn.model_selection import cross_val_score\nfrom sklearn import model_selection\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import precision_recall_curve, auc, roc_curve\nfrom sklearn.metrics import f1_score","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:39:32.723499Z","iopub.execute_input":"2022-01-07T17:39:32.723761Z","iopub.status.idle":"2022-01-07T17:39:32.729802Z","shell.execute_reply.started":"2022-01-07T17:39:32.723735Z","shell.execute_reply":"2022-01-07T17:39:32.729163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* Chia tập dữ liệu train , test với test_size = 0.2","metadata":{}},{"cell_type":"code","source":"train_x, test_x,train_y, test_y = train_test_split(x['question_text'], x['target'], test_size=0.2, random_state=0)\nprint('x_train: ', train_x.shape, train_y.shape)\nprint('x_test: ',test_x.shape, test_y.shape)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T17:39:38.493199Z","iopub.execute_input":"2022-01-07T17:39:38.493468Z","iopub.status.idle":"2022-01-07T17:39:38.578945Z","shell.execute_reply.started":"2022-01-07T17:39:38.493440Z","shell.execute_reply":"2022-01-07T17:39:38.578009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* **Text Vectorization**","metadata":{}},{"cell_type":"markdown","source":"**CountVectorizer**\n\n* Các giải thuật Machine Learning chỉ làm việc được với số, nên sẽ convert text về định dạng số\n\n* Chia câu hỏi thành các từ (đơn vị cơ sở). Cần có một bộ tokenizer có kích thước bằng toàn bộ các từ xuất hiện trong văn bản hoặc bằng toàn bộ các từ có trong từ điển. Một câu văn sẽ được biểu diễn bằng một sparse vector mà mỗi một phần tử đại diện cho một từ, giá trị của nó bằng 0 hoặc 1 tương ứng với từ không xuất hiện hoặc có xuất hiện.\n\n* Sử dụng các túi từ (bags of words) để tạo ra một vector có độ dài bằng độ dài của tokenizer và mỗi phần tử của túi từ sẽ đếm số lần xuất hiện của một từ trong câu và sắp xếp chúng theo một vị trí phù hợp trong vector\n\n* Học trên tập từ vựng của toàn bộ tập train và test, vector đếm có thể phải mã hoá những từ có ở tập test và tập train\n\n* Hạn chế : Các biểu diễn theo túi từ có hạn chế đó là không phân biệt được 2 câu văn có cùng các từ bởi túi từ không phân biệt thứ tự trước sau của các từ trong một câu. Ví dụ như ‘you have no dog’ và ‘no, you have dog’ là 2 câu văn có biểu diễn giống nhau mặc dù có ý nghĩa trái ngược nhau\n\n**Evaluation**\n\n* Đối với dữ liệu mất cân bằng thì sự đánh giá sẽ không tập trung vào Accuracy, thay vào đó ta sẽ tập trung vào điểm F1 , Precision và Recall\n\n* Công thức tính điểm F1 : F1 = 2 (precision recall) / (precision + recall)\n\n* Bằng việc sử dụng sklearn.metrics ta sẽ tính được f1-score , accuracy_score","metadata":{}},{"cell_type":"code","source":"vectorizer = CountVectorizer()\nbow_train = vectorizer.fit_transform(train_x) \nprint(bow_train.shape)\nbow_test = vectorizer.transform(test_x)\nprint(bow_test.shape)\nprint(\"Done creating Bag-of-Words\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T18:09:02.040816Z","iopub.execute_input":"2022-01-07T18:09:02.041193Z","iopub.status.idle":"2022-01-07T18:09:10.727317Z","shell.execute_reply.started":"2022-01-07T18:09:02.041159Z","shell.execute_reply":"2022-01-07T18:09:10.726402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **4. Xây dựng mô hình**\n**4.1. Logistic Regression**\n\nLink notion: https://excessive-source-1c9.notion.site/18-09-2021-H-i-quy-Logistics-6c3eb44266e549169a0d01cc2d36cfa2\n\n* Mô hình đầu tiên được sử dụng là logistic regression , đây là một thuật toán trong học có giám sát nhằm mục đích phân loại dữ liệu và rất phổ biến cho bài toán phân loại tuyến tính\n\n* Hồi quy logistic là một phương pháp phân tích thống kê được sử dụng để dự đoán giá trị dữ liệu dựa trên các quan sát trước đó của tập dữ liệu.\n\n* Mục đích của hồi quy logistic là ước tính xác suất của các sự kiện, bao gồm xác định mối quan hệ giữa các tính năng từ đó đự đoán xác suất của các kết quả, nên đối với hồi quy logistic ta sẽ có:\n\n> Input: dữ liệu input (ta sẽ coi có hai nhãn là 0 và 1).\n> Output : Xác suất dữ liệu input rơi vào nhãn 0 hoặc nhãn 1.","metadata":{}},{"cell_type":"code","source":"print(f\"Results of logistic regression on full bag-of-words\")\nlogistic = LogisticRegression(penalty=\"l2\", C=1, solver='liblinear') \nlogistic.fit(bow_train, train_y) \ntrain_predictions = logistic.predict(bow_train)\ntrain_acc = accuracy_score(train_y, train_predictions)  \ntrain_f1 = f1_score(train_y, train_predictions) \nprint(f\"Training accuracy: {train_acc:.2%}, F1: {train_f1:.4f}\") \ntest_predictions = logistic.predict(bow_test)\ntest_acc = accuracy_score(test_y, test_predictions) \ntest_f1 = f1_score(test_y, test_predictions) \nprint(f\"Testing accuracy:  {test_acc:.2%}, F1: {test_f1:.4f}\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T18:09:23.464126Z","iopub.execute_input":"2022-01-07T18:09:23.464403Z","iopub.status.idle":"2022-01-07T18:09:57.014324Z","shell.execute_reply.started":"2022-01-07T18:09:23.464373Z","shell.execute_reply":"2022-01-07T18:09:57.013445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**4.2. Gradient Boosting**\n\nNotion: https://excessive-source-1c9.notion.site/11-11-2021-Ph-ng-ph-p-Boosting-714c287d19494eb88e8b13cc9d96650e\n\n* Ý tưởng cơ bản của thuật toán Gradient Boosting là lần lượt thêm các decision trees nối tiếp nhau. Tree thêm vào sau sẽ cố gắng giải quyết những sai sót của tree trước đó.\n\n* Xây dựng một lượng lớn các model (thường là cùng loại). Mỗi model sau sẽ học cách sửa những lỗi của model trước (dữ liệu mà model trước dự đoán sai) -> tạo thành một chuỗi các model mà model sau sẽ tốt hơn model trước bởi trọng số được update qua mỗi model (cụ thể ở đây là trọng số của những dữ liệu dự đoán đúng sẽ không đổi, còn trọng số của những dữ liệu dự đoán sai sẽ được tăng thêm) . Chúng ta sẽ lấy kết quả của model cuối cùng trong chuỗi model này làm kết quả trả về.","metadata":{}},{"cell_type":"code","source":"from sklearn.ensemble import GradientBoostingClassifier\nprint(f\"Results of gradient boosting on full bag-of-words\")\ngbc = GradientBoostingClassifier() \ngbc.fit(bow_train, train_y) \ntrain_predictions_gbc = gbc.predict(bow_train)\ntrain_acc_gbc = accuracy_score(train_y, train_predictions_gbc) \ntrain_f1_gbc = f1_score(train_y, train_predictions_gbc) \nprint(f\"Training accuracy: {train_acc_gbc:.2%}, F1: {train_f1_gbc:.4f}\") \ntest_predictions_gbc = gbc.predict(bow_test)\ntest_acc_gbc = accuracy_score(test_y, test_predictions_gbc) \ntest_f1_gbc = f1_score(test_y, test_predictions_gbc) \nprint(f\"Testing accuracy:  {test_acc_gbc:.2%}, F1: {test_f1_gbc:.4f}\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T18:12:31.230692Z","iopub.execute_input":"2022-01-07T18:12:31.230994Z","iopub.status.idle":"2022-01-07T18:13:57.530212Z","shell.execute_reply.started":"2022-01-07T18:12:31.230963Z","shell.execute_reply":"2022-01-07T18:13:57.529383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Nhận xét:\n> * F1-score thấp hơn so với Logistic Legression\n> * Tỉ lệ accuracy thấp\n> * Nhìn vào hiệu suất, ta có thể thấy Logistic Regression hiệu quả hơn trong bài toán này","metadata":{}},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"x_val = vectorizer.transform(test['question_text'])\nvalidation_predictions = logistic.predict(x_val)\nsubmission = pd.DataFrame({'qid':test['qid'], 'prediction':validation_predictions })\nsubmission.to_csv('submission.csv', index=False)\nsubmission","metadata":{"execution":{"iopub.status.busy":"2022-01-07T18:33:00.152762Z","iopub.execute_input":"2022-01-07T18:33:00.153042Z","iopub.status.idle":"2022-01-07T18:33:08.548101Z","shell.execute_reply.started":"2022-01-07T18:33:00.153014Z","shell.execute_reply":"2022-01-07T18:33:08.547277Z"},"trusted":true},"execution_count":null,"outputs":[]}]}