{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Giải nén file dữ liệu word_embedđing có sẵn:\n\nimport zipfile\nzip_ref = zipfile.ZipFile('../input/quora-insincere-questions-classification/embeddings.zip', 'r')\nzip_ref.printdir()\nzip_ref.extract('wiki-news-300d-1M/wiki-news-300d-1M.vec')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Đọc dữ liệu từu tập csv sau đó chia thành 2 list\n+ 1 list chứa những câu insincere\n+ 1 list chứa những câu sincere\n\n(Trong dữ liệu ban đầu có tổng số hơn 2 triệu câu, trong đó 92% số câu hỏi được gán nhãn sincere và số còn lại được gán nhãn insicere. Do sự giới hạn của bộ nhớ, ta sẽ lấy 1 số câu với mỗi loại nhãn dán để thực hiện việc huấn luyện và test)","metadata":{}},{"cell_type":"code","source":"# ĐỌc dữ liệu và chia thành 2 nhóm sincere và insicere từ tập dữ liệu ban đầu:\n\ndf = pd.read_csv('../input/quora-insincere-questions-classification/train.csv')\ninsincere_questions = [df['question_text'][idx] for idx in range(len(df)) if df['target'].loc[idx] == 1]\nsincere_questions = [df['question_text'][idx] for idx in range(len(df)) if df['target'].loc[idx] == 0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import nltk\nfrom nltk.corpus import stopwords\nimport string","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Tạo tập chứa các stop words và các dấu câu (sử dụng trong việc clean dữ liệu)","metadata":{}},{"cell_type":"code","source":"stop_words = set(stopwords.words('english'))\npuncs = set(string.punctuation)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"CLean dữ liệu:\n- Xóa các stop words và các dấu câu trong 1 câu\n- Chuyển các từ sang kí tự thường\n\n- Chuyển các từ còn lại thành 1 list các từ ","metadata":{}},{"cell_type":"code","source":"# Tiến hành chuyển các câu hỉ thành 1 list gồm những từ còn lại sau khi xóa các stop_words và các dấu câu:\n\ndef clean(text_list):\n    for idx, text in enumerate(text_list):\n        text = text.lower().split()\n        word_list = [char for char in text if char not in puncs and char not in stop_words]\n        text_list[idx] = word_list\n    \n    return text_list","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"insincere_questions = clean(insincere_questions)\nsincere_questions = clean(sincere_questions)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Đọc tập embedding word từ file dữ liệu\n(Embedding words là file chứa những vector gồm 300 chiều mã hóa cho 1 từ tiếng anh vd: 'the': '-0.12 0.1678 0.3467 -0.899 ....')\n- Sau khi chuyển những từ còn lại trong câu hỏi thành 1 danh sách (đã bỏ những stop word và các dấu câu), ta chuyển những từ đó thành các vector 300 chiều dựa vào tập embedding word","metadata":{}},{"cell_type":"code","source":"# Đọc dữ liệu embedding word từ file wiki-news-300d-1M.vec\nf = open('./wiki-news-300d-1M/wiki-news-300d-1M.vec')\nlines = [line for line in f.readlines()]\nlines = lines[2:]\ntemp = lines[:80000]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Lấy 1 số những câu hỏi trong tập huấn luyện để thực hiện cho việc huấn luyện\n\nsample_insincere_questions = insincere_questions[:10000]\nsample_sincere_questions = sincere_questions[:10000]\ntest_insincere_questions = insincere_questions[10000:11000]\ntest_sincere_questions = sincere_questions[10000:11000]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Tạo 1 dictionary embedding_list có dạng 'word': array(300) từ file embedding trong đó array(300) là vector tượng trưng cho các words tương ứng\n\nembedding_list = {}\n\nfor val in temp:\n    val = val.replace('\\n', '').split()\n    key = val.pop(0)\n    key = key.lower()\n    if key in puncs or key in stop_words:\n        continue\n        \n    embedding_list[key] = np.array([float(x) for x in val])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* Viêc clean dữ liệu (xóa 1 số từ) sẽ dẫn đến việc các list từ còn lại có độ dài không giống nhau\n=> Khắc phục bằng cách thêm các vector 0 ([0, 0, 0, 0, ...., 0]) vào những từ còn thiếu, từ đó các list trong tập huấn luyện sẽ có cùng cùng độ dài với nhau mà không làm thay đổi ý nghĩa của các câu\n","metadata":{}},{"cell_type":"code","source":"# Tìm độ dài lớn nhất còn lại sau khi đã thực hiện clean dữ liệu \nmax_len = 0\nfor idx in range(len(sincere_questions)):\n    if idx < len(insincere_questions):\n        if max_len < max(len(sincere_questions[idx]), len(insincere_questions[idx])):\n            max_len = max(len(sincere_questions[idx]), len(insincere_questions[idx]))\n    else:\n        if max_len < len(sincere_questions[idx]):\n            max_len = len(sincere_questions[idx])\n\nmax_len","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Tạo vector 0\ndef generate_mt(key):\n    new_arr = np.zeros((key, 300))\n    return new_arr","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Chuyển các từ trong 1 list sang dạng vector đồng thời thực hiện đồng bọ về chiều dài của các list từ trong câu hỏi\n# 1 list từ trong dạng vector sẽ có dang: [max_len, 300]\n#     * max_len: là số từu có trong list (nếu trong list ban đầu không có đủ số từ, ta thay bằng các vecto 0)\n#     * 300: là số chiều vector tượng trưng cho từ đó trong tập word_embedding ở trên\n\n\ndef convert_to_vt(list_questions, max_len):\n    for idx in range(len(list_questions)):\n        if len(list_questions[idx]) == 0:\n            continue\n        for i, item in enumerate(list_questions[idx]):\n            if item not in embedding_list:\n                list_questions[idx][i] = np.zeros(300)\n            else:\n                list_questions[idx][i] = embedding_list[list_questions[idx][i]]\n        if len(list_questions[idx]) < max_len:\n            temp_arr = generate_mt(max_len - len(list_questions[idx]))\n            list_questions[idx] = np.concatenate((list_questions[idx], temp_arr), axis=0)\n            \n    return list_questions","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Chuyển sang vector đối với tập huấn luyện\n\nsample_insincere_questions = convert_to_vt(sample_insincere_questions, max_len)\nsample_sincere_questions = convert_to_vt(sample_sincere_questions, max_len)\nsample_insincere_questions = [item for item in sample_insincere_questions if type(item) is not list]\nsample_sincere_questions = [item for item in sample_sincere_questions if type(item) is not list]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Chuyển sang vector đối với tập test\n\ntest_insincere_questions = convert_to_vt(test_insincere_questions, max_len)\ntest_sincere_questions = convert_to_vt(test_sincere_questions, max_len)\ntest_insincere_questions = [item for item in test_insincere_questions if type(item) is not list]\ntest_sincere_questions = [item for item in test_sincere_questions if type(item) is not list]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a = np.array(sample_insincere_questions)\nb = np.array(sample_sincere_questions)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Sau khi chuyển dữ liệu sang dạng vector, ta nối 2 tập sincere và insincere để tạo thành tập huấn luyện cho mô hình\ntrain_set = np.concatenate((a,b), axis=0)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set = train_set.reshape(train_set.shape[0], -1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Tạo tập nhãn dán dựa trên số lượng các câu hỏi của tập huấn luyện\n# Tỉ lệ các câu sincere : insincere là 50:50\n\nlabel1 = np.ones((10000,))\nlabel2 = np.zeros((9999,))\nlabel = np.concatenate((label2, label1), axis=0)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Với tập test, ta làm tương tự như các bước đã thực hiện trong tập huấn luyện\n\na = np.array(test_insincere_questions)\nb = np.array(test_sincere_questions)\ntest_set = np.concatenate((a, b), axis=0)\ntest_set = test_set.reshape(test_set.shape[0], -1)\n\nlabel1 = np.ones((1000))\nlabel2 = np.zeros((1000,))\ntest_label = np.concatenate((label2, label1), axis=0)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sklearn\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn import datasets\nfrom sklearn import metrics\nimport matplotlib.pyplot as plt","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* Sử dụng mô hình LogisticRegression để phân lớp cho bộ dữ liệu có 2 nhãn (sincere:1 và insincere:0)","metadata":{}},{"cell_type":"code","source":"# Thực hiện khai báo mô hình và tiến hành huấn luyện (số lần train = 300)\n# Sau đó thực hiện đánh giá độ chính xác của tập huấn luyện\n\nclf = LogisticRegression(random_state=0, max_iter=300).fit(train_set, label)\n# clf.fit(train_set, label)\nclf.score(train_set, label)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Tiến hành dự đoán tập test bằng mô hình đã huấn luyện\npred = clf.predict(test_set)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Tính độ chính xác của việc dự đoán trên tập test \ncr = 0\nfor i in range(len(test_set)):\n    if pred[i] == test_label[i]:\n        cr += 1\n\nprint(cr / len(test_set))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import f1_score, accuracy_score, confusion_matrix\n\n# Điểm F1 của mô hình \nf1 = f1_score(test_label, pred)\nf1","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"accuracy_score(test_label, pred)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Báo cáo kết quả thực hiện:\n\nfrom sklearn.metrics import classification_report\nprint(classification_report(test_label, pred))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}