{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-06T11:56:39.58435Z","iopub.execute_input":"2022-01-06T11:56:39.584686Z","iopub.status.idle":"2022-01-06T11:56:39.59613Z","shell.execute_reply.started":"2022-01-06T11:56:39.584654Z","shell.execute_reply":"2022-01-06T11:56:39.595423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# BÁO CÁO BÀI TẬP LỚN MÔN HỌC MÁY\n\n**Giảng viên:** Trần Quốc Long\n\n**Lớp môn học:** 2122I_INT3405_1\n\n**Sinh viên:** Đào Anh Tuấn\n\n**MSSV:** 18021372","metadata":{}},{"cell_type":"markdown","source":"# 1. Giới thiệu bài toán:\n## Quora Insincere Questions Classification\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* Quora là nền tảng để mọi người có thể học hỏi lẫn nhau bằng cách đặt câu hỏi và trả lời để chia sẻ kiến thức. Mục đích của bài toán này là để phân loại các câu hỏi đặt ra là thuộc loại câu hỏi chân thành hay không chân thành.\n* Những câu hỏi không chân thành thường là những câu đưa ra tuyên bố quan điểm của mình hơn là để tìm những câu trả lời có ích: không trung lập, khiêu khích hoặc chê bai, không có căn cứ thực tế hoặc chứa nội dung khiêu dâm.\n* Input: Câu hỏi dạng text.\n* Output: 0/1 (Sincere/ Insincere). \n","metadata":{}},{"cell_type":"markdown","source":"# 2. Import các thư viện và các file dữ liệu cần thiết","metadata":{}},{"cell_type":"markdown","source":"**Import thư viện:**","metadata":{}},{"cell_type":"code","source":"# import os\nimport json\nimport string\nimport numpy as np\nimport pandas as pd\nfrom pandas.io.json import json_normalize\nimport matplotlib.pyplot as plt\nimport seaborn as sns\ncolor = sns.color_palette()\n\n%matplotlib inline\n\nfrom plotly import tools\nimport plotly.offline as py\npy.init_notebook_mode(connected=True)\nimport plotly.graph_objs as go\n\nfrom sklearn import model_selection, preprocessing, metrics, ensemble, naive_bayes, linear_model\nfrom sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer\nfrom sklearn.decomposition import TruncatedSVD\nimport lightgbm as lgb\n\npd.options.mode.chained_assignment = None\npd.options.display.max_columns = 999","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:39.597843Z","iopub.execute_input":"2022-01-06T11:56:39.598436Z","iopub.status.idle":"2022-01-06T11:56:42.645103Z","shell.execute_reply.started":"2022-01-06T11:56:39.598395Z","shell.execute_reply":"2022-01-06T11:56:42.644417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Đọc các dữ liệu file train và file test**","metadata":{}},{"cell_type":"code","source":"#Đọc file train và file test\ntrain_df = pd.read_csv(\"../input/quora-insincere-questions-classification/train.csv\")\ntest_df = pd.read_csv(\"../input/quora-insincere-questions-classification/test.csv\")\nprint(\"Train shape : \", train_df.shape)\nprint(\"Test shape : \", test_df.shape)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:42.646436Z","iopub.execute_input":"2022-01-06T11:56:42.646686Z","iopub.status.idle":"2022-01-06T11:56:47.858443Z","shell.execute_reply.started":"2022-01-06T11:56:42.646653Z","shell.execute_reply":"2022-01-06T11:56:47.85764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:47.861595Z","iopub.execute_input":"2022-01-06T11:56:47.862402Z","iopub.status.idle":"2022-01-06T11:56:48.147832Z","shell.execute_reply.started":"2022-01-06T11:56:47.862344Z","shell.execute_reply":"2022-01-06T11:56:48.147056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét:** Dữ liệu file train không có giá trị null.","metadata":{}},{"cell_type":"code","source":"test_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:48.14903Z","iopub.execute_input":"2022-01-06T11:56:48.149311Z","iopub.status.idle":"2022-01-06T11:56:48.234837Z","shell.execute_reply.started":"2022-01-06T11:56:48.149271Z","shell.execute_reply":"2022-01-06T11:56:48.23374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét:** Dữ liệu file test không có giá trị null.","metadata":{}},{"cell_type":"markdown","source":"**Tiếp theo , vẽ biều đồ thể hiện sự phân bố dữ liệu trong tập train**","metadata":{}},{"cell_type":"code","source":"cnt_srs = train_df['target'].value_counts()\ntrace = go.Bar(\n    x=cnt_srs.index,\n    y=cnt_srs.values,\n    marker=dict(\n        color=cnt_srs.values,\n        colorscale = 'Picnic',\n        reversescale = True\n    ),\n)\n\nlayout = go.Layout(\n    title='Target Count',\n    font=dict(size=18)\n)\n\ndata = [trace]\nfig = go.Figure(data=data, layout=layout)\npy.iplot(fig, filename=\"TargetCount\")\n","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:48.236991Z","iopub.execute_input":"2022-01-06T11:56:48.237309Z","iopub.status.idle":"2022-01-06T11:56:48.969813Z","shell.execute_reply.started":"2022-01-06T11:56:48.237265Z","shell.execute_reply":"2022-01-06T11:56:48.969043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét:** Nhìn vào biểu đồ ta thấy , dữ liệu đang bị mất cân bằng , số lượng câu hỏi có label = 0  chiếm đa số, trong khi số lượng các  câu hỏi có label = 1 lại rất ít. Điều này sẽ gây ảnh hưởng đến kết quả nếu đưa luôn dữ liệu vào để train, vì thể chúng ta cần phải có bước tiền xử lý dữ liệu trước khi đưa vào mô hình huấn luyện.","metadata":{}},{"cell_type":"code","source":"print(\"Tỉ lệ phần trăm số câu hỏi Insincere là:\", (len(train_df.loc[train_df.target==1])) / (len(train_df.loc[train_df.target == 0])) * 100)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:48.97099Z","iopub.execute_input":"2022-01-06T11:56:48.971306Z","iopub.status.idle":"2022-01-06T11:56:49.082806Z","shell.execute_reply.started":"2022-01-06T11:56:48.971268Z","shell.execute_reply":"2022-01-06T11:56:49.082048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét:** Số câu hỏi \"insincere\" chỉ chiếm khoảng 6-7% trong tổng số câu hỏi. Dữ liệu bị mất cân bằng khá lớn, do đó độ đo F1 sẽ thích hợp cho những trường hợp như này","metadata":{}},{"cell_type":"markdown","source":" **PHÂN TÍCH TỪNG CÂU HỎI**","metadata":{}},{"cell_type":"markdown","source":"**Số lượng từ trong câu**","metadata":{}},{"cell_type":"code","source":"words = train_df['question_text'].apply(lambda x: len(x) - len(''.join(x.split())) + 1)\ntrain_df['words'] = words\nwords = train_df.loc[train_df['words']<200]['words']\nsns.distplot(words, color='g')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:49.08388Z","iopub.execute_input":"2022-01-06T11:56:49.084128Z","iopub.status.idle":"2022-01-06T11:56:56.015984Z","shell.execute_reply.started":"2022-01-06T11:56:49.084091Z","shell.execute_reply":"2022-01-06T11:56:56.015239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Số từ trung bình của các câu hỏi trong dữ liệu file train là {0:.0f}.'.format(np.mean(train_df['question_text'].apply(lambda x: len(x.split())))))\nprint('Số từ trung bình của các câu hỏi trong dữ liệu file test là {0:.0f}.'.format(np.mean(test_df['question_text'].apply(lambda x: len(x.split())))))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:56.01713Z","iopub.execute_input":"2022-01-06T11:56:56.017661Z","iopub.status.idle":"2022-01-06T11:56:58.091759Z","shell.execute_reply.started":"2022-01-06T11:56:56.017622Z","shell.execute_reply":"2022-01-06T11:56:58.09092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Số từ lớn nhất của các câu hỏi trong dữ liệu file train là {0:.0f}.'.format(np.max(train_df['question_text'].apply(lambda x: len(x.split())))))\nprint('Số từ lớn nhất của các câu hỏi trong dữ liệu file test là {0:.0f}.'.format(np.max(test_df['question_text'].apply(lambda x: len(x.split())))))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:56:58.094947Z","iopub.execute_input":"2022-01-06T11:56:58.095683Z","iopub.status.idle":"2022-01-06T11:57:00.195236Z","shell.execute_reply.started":"2022-01-06T11:56:58.095644Z","shell.execute_reply":"2022-01-06T11:57:00.194452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Số ký tự trung bình của các câu hỏi trong dữ liệu file train là {0:.0f}.'.format(np.mean(train_df['question_text'].apply(lambda x: len(x)))))\nprint('Số ký tự trung bình của các câu hỏi trong dữ liệu file test là {0:.0f}.'.format(np.mean(test_df['question_text'].apply(lambda x: len(x)))))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:57:00.196599Z","iopub.execute_input":"2022-01-06T11:57:00.197032Z","iopub.status.idle":"2022-01-06T11:57:01.560768Z","shell.execute_reply.started":"2022-01-06T11:57:00.196991Z","shell.execute_reply":"2022-01-06T11:57:01.559207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét:** Có thể thấy độ dài trung bình của các câu hỏi trong tập dữ liệu file train và file test là giống nhau, tuy nhiên có những câu hỏi khá dài trong tập dữ liệu huấn luyện.","metadata":{}},{"cell_type":"markdown","source":"# 3.Phân tích dữ liệu","metadata":{}},{"cell_type":"markdown","source":"Tính tần số xuất hiện của từ trong tập dữ liệu bằng cách tạo một '***word cloud***' trên cột '***question_text***'","metadata":{"execution":{"iopub.status.busy":"2022-01-06T09:16:52.94615Z","iopub.execute_input":"2022-01-06T09:16:52.94666Z","iopub.status.idle":"2022-01-06T09:16:52.951245Z","shell.execute_reply.started":"2022-01-06T09:16:52.946622Z","shell.execute_reply":"2022-01-06T09:16:52.950253Z"}}},{"cell_type":"code","source":"from wordcloud import WordCloud, STOPWORDS\n\n# Thanks : https://www.kaggle.com/aashita/word-clouds-of-various-shapes ##\ndef plot_wordcloud(text, mask=None, max_words=200, max_font_size=100, figure_size=(24.0,16.0), \n                   title = None, title_size=40, image_color=False):\n    stopwords = set(STOPWORDS)\n    more_stopwords = {'one', 'br', 'Po', 'th', 'sayi', 'fo', 'Unknown'}\n    stopwords = stopwords.union(more_stopwords)\n\n    wordcloud = WordCloud(background_color='black',\n                    stopwords = stopwords,\n                    max_words = max_words,\n                    max_font_size = max_font_size, \n                    random_state = 42,\n                    width=800, \n                    height=400,\n                    mask = mask)\n    wordcloud.generate(str(text))\n    \n    plt.figure(figsize=figure_size)\n    if image_color:\n        image_colors = ImageColorGenerator(mask);\n        plt.imshow(wordcloud.recolor(color_func=image_colors), interpolation=\"bilinear\");\n        plt.title(title, fontdict={'size': title_size,  \n                                  'verticalalignment': 'bottom'})\n    else:\n        plt.imshow(wordcloud);\n        plt.title(title, fontdict={'size': title_size, 'color': 'black', \n                                  'verticalalignment': 'bottom'})\n    plt.axis('off');\n    plt.tight_layout()  \n    \nplot_wordcloud(train_df[\"question_text\"], title=\"Word Cloud of Questions\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:57:01.56467Z","iopub.execute_input":"2022-01-06T11:57:01.56529Z","iopub.status.idle":"2022-01-06T11:57:02.722099Z","shell.execute_reply.started":"2022-01-06T11:57:01.565245Z","shell.execute_reply":"2022-01-06T11:57:02.721348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Tính các từ xuất hiện nhiều trong các câu hỏi chân thành và không chân thành","metadata":{}},{"cell_type":"code","source":"from collections import defaultdict\ntrain1_df = train_df[train_df[\"target\"]==1]\ntrain0_df = train_df[train_df[\"target\"]==0]\n\n## custom function for ngram generation ##\ndef generate_ngrams(text, n_gram=1):\n    token = [token for token in text.lower().split(\" \") if token != \"\" if token not in STOPWORDS]\n    ngrams = zip(*[token[i:] for i in range(n_gram)])\n    return [\" \".join(ngram) for ngram in ngrams]\n\n## custom function for horizontal bar chart ##\ndef horizontal_bar_chart(df, color):\n    trace = go.Bar(\n        y=df[\"word\"].values[::-1],\n        x=df[\"wordcount\"].values[::-1],\n        showlegend=False,\n        orientation = 'h',\n        marker=dict(\n            color=color,\n        ),\n    )\n    return trace\n\n## Get the bar chart from sincere questions ##\nfreq_dict = defaultdict(int)\nfor sent in train0_df[\"question_text\"]:\n    for word in generate_ngrams(sent):\n        freq_dict[word] += 1\nfd_sorted = pd.DataFrame(sorted(freq_dict.items(), key=lambda x: x[1])[::-1])\nfd_sorted.columns = [\"word\", \"wordcount\"]\ntrace0 = horizontal_bar_chart(fd_sorted.head(50), 'blue')\n\n## Get the bar chart from insincere questions ##\nfreq_dict = defaultdict(int)\nfor sent in train1_df[\"question_text\"]:\n    for word in generate_ngrams(sent):\n        freq_dict[word] += 1\nfd_sorted = pd.DataFrame(sorted(freq_dict.items(), key=lambda x: x[1])[::-1])\nfd_sorted.columns = [\"word\", \"wordcount\"]\ntrace1 = horizontal_bar_chart(fd_sorted.head(50), 'blue')\n\n# Creating two subplots\nfig = tools.make_subplots(rows=1, cols=2, vertical_spacing=0.04,\n                          subplot_titles=[\"top các từ có nhiều trong câu hỏi chân thành\", \n                                          \"top các từ có nhiều trong câu hỏi ko chân thành\"])\nfig.append_trace(trace0, 1, 1)\nfig.append_trace(trace1, 1, 2)\nfig['layout'].update(height=1200, width=900, paper_bgcolor='rgb(233,233,233)', title=\"Word Count Plots\")\npy.iplot(fig, filename='word-plots')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:57:02.723155Z","iopub.execute_input":"2022-01-06T11:57:02.723379Z","iopub.status.idle":"2022-01-06T11:57:12.736768Z","shell.execute_reply.started":"2022-01-06T11:57:02.723335Z","shell.execute_reply":"2022-01-06T11:57:12.736014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**NHẬN XÉT:**\n* Một vài từ xuất hiện nhiều ở cả hai lớp như people, think, many...\n* NHững top words xuất hiện nhiều nhất ở lớp câu hỏi chân thành là : best, will, people...\n* NHững top words xuất hiện nhiều nhất ở lớp câu hỏi ko chân thành là : people, women, will...","metadata":{}},{"cell_type":"markdown","source":"# 4. Tiền xử lý dữ liệu\n\n**Đầu tiên ta sẽ xử lý data:** Bỏ các từ không mang nghĩa và dấu (stopword, punctual), đổi chữ hoa thành chữ thường, lemmatize (đưa tất cả các chữ về một dạng thống nhất)","metadata":{}},{"cell_type":"code","source":"from gensim.utils import simple_preprocess \nfrom nltk.corpus import stopwords\nfrom nltk.stem import WordNetLemmatizer\n\nstop_words = set(stopwords.words('english')) \nwordnet_lemmatizer = WordNetLemmatizer()\ndef preprocessing(corpus):\n    res = []\n    for doc in corpus:\n        words = []\n        for word in simple_preprocess(doc):\n            if word not in stop_words:\n                word1 = wordnet_lemmatizer.lemmatize(word, pos = \"n\")\n                word2 = wordnet_lemmatizer.lemmatize(word1,pos = \"v\")\n                word3 = wordnet_lemmatizer.lemmatize(word2, pos = (\"a\"))\n                words.append(word3)\n                pass\n            pass\n        res.append(' '.join(words))        \n        pass\n    return res","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:57:12.740895Z","iopub.execute_input":"2022-01-06T11:57:12.742859Z","iopub.status.idle":"2022-01-06T11:57:13.388673Z","shell.execute_reply.started":"2022-01-06T11:57:12.742817Z","shell.execute_reply":"2022-01-06T11:57:13.387891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Đọc lại file train.csv và test.csv đưa về dạng tệp 'train' và 'test'**","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv(\"../input/quora-insincere-questions-classification/train.csv\")\ntest = pd.read_csv(\"../input/quora-insincere-questions-classification/test.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:57:13.38985Z","iopub.execute_input":"2022-01-06T11:57:13.390093Z","iopub.status.idle":"2022-01-06T11:57:16.335657Z","shell.execute_reply.started":"2022-01-06T11:57:13.390059Z","shell.execute_reply":"2022-01-06T11:57:16.334866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# áp dụng cho tập train và test \ntrain['question_text'] = preprocessing(train['question_text'])\ntest['question_text'] = preprocessing(test['question_text'])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T11:57:16.337033Z","iopub.execute_input":"2022-01-06T11:57:16.33729Z","iopub.status.idle":"2022-01-06T12:00:23.661184Z","shell.execute_reply.started":"2022-01-06T11:57:16.337255Z","shell.execute_reply":"2022-01-06T12:00:23.660409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Tích xuất đặc trưng\n\nLựa chọn **TF-IDF** làm đặc trưng:\n\n**TF-IDF là gì?**\n\n**TF-IDF** (Term Frequency – Inverse Document Frequency) là 1 kĩ thuật sử dụng trong khai phá dữ liệu văn bản. Trọng số này được sử dụng để đánh giá tầm quan trọng của một từ trong một văn bản. Giá trị cao thể hiện độ quan trọng cao và nó phụ thuộc vào số lần từ xuất hiện trong văn bản nhưng bù lại bởi tần suất của từ đó trong tập dữ liệu. Một vài biến thể của **TF-IDF** thường được sử dụng trong các hệ thống tìm kiếm như một công cụ chính để đánh giá và sắp xếp văn bản dựa vào truy vấn của người dùng. **TF-IDF** cũng được sử dụng để lọc những từ stopwords trong các bài toán như tóm tắt văn bản và phân loại văn bản.\n\n**TF là gì?**\n**TF**: Term Frequency(Tần suất xuất hiện của từ) là số lần từ xuất hiện trong văn bản. Vì các văn bản có thể có độ dài ngắn khác nhau nên một số từ có thể xuất hiện nhiều lần trong một văn bản dài hơn là một văn bản ngắn. Như vậy, term frequency thường được chia cho độ dài văn bản( tổng số từ trong một văn bản).\n\n![image.png](attachment:aaaff1a8-fd14-414f-8b90-6748c32c69e1.png)\n\nTrong đó:\n\n> tf(t, d): tần suất xuất hiện của từ t trong văn bản d\n\n> f(t, d): Số lần xuất hiện của từ t trong văn bản d\n\n> max({f(w, d) : w ∈ d}): Số lần xuất hiện của từ có số lần xuất hiện nhiều nhất trong văn bản d\n\n**IDF là gì?**\n\n**IDF**: Inverse Document Frequency(Nghịch đảo tần suất của văn bản), giúp đánh giá tầm quan trọng của một từ . Khi tính toán TF , tất cả các từ được coi như có độ quan trọng bằng nhau. Nhưng  một số từ như “is”, “of” và “that” thường xuất hiện rất nhiều lần nhưng độ quan trọng là không cao. Như thế chúng ta cần giảm độ quan trọng của những từ này xuống.\n\n![image.png](attachment:b77d3007-95af-4ee4-9311-3261bef33b3a.png)\n\nTrong đó:\n\n> idf(t, D): giá trị idf của từ t trong tập văn bản\n\n> |D|: Tổng số văn bản trong tập D\n\n> |{d ∈ D : t ∈ d}|: thể hiện số văn bản trong tập D có chứa từ t.\n\nCơ số logarit trong công thức này không thay đổi giá trị idf của từ mà chỉ thu hẹp khoảng giá trị của từ đó. Vì thay đổi cơ số sẽ dẫn đến việc giá trị của các từ thay đổi bởi một số nhất định và tỷ lệ giữa các trọng lượng với nhau sẽ không thay đổi. (nói cách khác, thay đổi cơ số sẽ không ảnh hưởng đến tỷ lệ giữa các giá trị **IDF**). Việc sử dụng logarit nhằm giúp giá trị **tf-idf** của một từ nhỏ hơn, do chúng ta có công thức tính tf-idf của một từ trong 1 văn bản là tích của **tf** và **idf** của từ đó.\n\n**Cụ thể, chúng ta có công thức tính TF-IDF hoàn chỉnh như sau:** \n\n> tfidf(t, d, D) = tf(t, d) x idf(t, D)\n\nKhi đó:\n\nNhững từ có giá trị **TF-IDF** cao là những từ xuất hiện nhiều trong văn bản này, và xuất hiện ít trong các văn bản khác. Việc này giúp lọc ra những từ phổ biến và giữ lại những từ có giá trị cao (từ khoá của văn bản đó).","metadata":{},"attachments":{"aaaff1a8-fd14-414f-8b90-6748c32c69e1.png":{"image/png":"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"},"b77d3007-95af-4ee4-9311-3261bef33b3a.png":{"image/png":"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"}}},{"cell_type":"code","source":"vector = TfidfVectorizer( ngram_range = (1,2))\ntrain_feature_matrics = vector.fit_transform(train['question_text'].values.astype('U'))\ntest_feature_matrics = vector.transform(test['question_text'].values.astype('U'))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:00:23.662643Z","iopub.execute_input":"2022-01-06T12:00:23.662888Z","iopub.status.idle":"2022-01-06T12:01:19.991415Z","shell.execute_reply.started":"2022-01-06T12:00:23.662855Z","shell.execute_reply":"2022-01-06T12:01:19.990701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_feature_matrics","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:01:19.992894Z","iopub.execute_input":"2022-01-06T12:01:19.993155Z","iopub.status.idle":"2022-01-06T12:01:19.998625Z","shell.execute_reply.started":"2022-01-06T12:01:19.99312Z","shell.execute_reply":"2022-01-06T12:01:19.997804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Đã xong quá trình tiền xử lý , lúc này dữ liệu cơ bản đã được làm sạch , bây giờ ta sẽ chọn lựa model để thực hiện quá trình train","metadata":{}},{"cell_type":"markdown","source":"# 5.Lựa chọn model\nĐối với bài toán phân lớp này , với đặc điểm của bộ dữ liệu là bị chênh lệch quá lớn , vì vậy model phù hợp nhất được lựa chọn là **F1- score**. **F1- score** là cách đánh giá hỗ trợ rất tốt cho bài toán phân lớp có 2 lớp dữ liệu \n\n# a. Tìm hiểu về F1-score\n\n* Đầu tiên, **Precision** được định nghĩa là tỉ lệ số điểm **positive** mô hình dự đoán đúng trên tổng số điểm mô hình dự đoán là **Positive**. **Recall** được định nghĩa là tỉ lệ số điểm **positive** mô hình dự đoán đúng trên tổng số điểm thật sự là **Positive** (hay tổng số điểm được gán nhãn là **positive** ban đầu).\n\n* **Precision** càng cao, tức là số điểm mô hình dự đoán là **positive** đều là **positive** càng nhiều. **Precision** = 1, tức là tất cả số điểm mô hình dự doán là **Positive** đều đúng, hay không có điểm nào có nhãn là **Negative** mà mô hình dự đoán nhầm là **Positive**.\n\n* **Recall** càng cao, tức là số điểm là **positive** bị bỏ sót càng ít. **Recall** = 1, tức là tất cả số điểm có nhãn là **Positive** đều được mô hình nhận ra.\n\n* Chỉ dùng **Precision**, mô hình chỉ đưa ra dự đoán cho một điểm mà nó chắc chắn nhất. Khi đó **Precision** = 1, tuy nhiên ta không thể nói là mô hình này tốt.Chỉ dùng **Recall**, nếu mô hình dự đoán tất cả các điểm đều là **Positive**. Khi đó **Recall** = 1, tuy nhiên ta cũng không thể nói đây là mô hình tốt.\nKhi đó **F1-score** được sử dụng. **F1-score** là trung bình điều hòa (**harmonic mean**) của **Precision** và **Recall** (giả sử hai đại lượng này khác 0). **F1-score** được tinh theo công thức:\n\n> ![image.png](attachment:73ba45a9-aea9-4ed4-8977-2740c6b421b1.png)\n\n* **F1-score** có giá trị nằm trong nửa khoảng (0,1].**F1** càng cao, bộ phân lớp càng tốt. Khi cả **Recall** và **Precision** đều bằng 1 (tốt nhất có thể), **F1** = 1. Khi cả **Recall** và **Precision** đều thấp, ví dụ bằng 0.1, **F1** = 0.1.\n\n# b.Lựa chọn mô hình huấn luyện: mô hình Logistic Regression\n- Giới thiệu qua về Logistic Regression \n> **Logistic Regression** là 1 thuật toán phân loại được dùng để gán các đối tượng cho 1 tập hợp giá trị rời rạc (như 0, 1, 2, ...). Một ví dụ điển hình là phân loại Email, gồm có email công việc, email gia đình, email spam, ... Giao dịch trực tuyến có là an toàn hay không an toàn, khối u lành tính hay ác tình. Thuật toán trên dùng hàm sigmoid logistic để đưa ra đánh giá theo xác suất. \n\n- Học **tf-idf** đã **extract** ở trên bằng mô hình Logistic regression. Thử tunning tham số regularize C.","metadata":{},"attachments":{"73ba45a9-aea9-4ed4-8977-2740c6b421b1.png":{"image/png":"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"}}},{"cell_type":"code","source":"# Khai báo thêm các thư viện được sử dụng\nfrom sklearn.metrics import accuracy_score, confusion_matrix, f1_score\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.linear_model import LogisticRegression\ntrain_x, valid_x, train_y, valid_y = train_test_split(train_feature_matrics, train['target'], test_size=0.25, shuffle=False)\nC = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100, 300, 1000]","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:01:20.000158Z","iopub.execute_input":"2022-01-06T12:01:20.000716Z","iopub.status.idle":"2022-01-06T12:01:20.087079Z","shell.execute_reply.started":"2022-01-06T12:01:20.000679Z","shell.execute_reply":"2022-01-06T12:01:20.086346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* Bây giờ , bắt đầu đi vào quá trình huấn luyện","metadata":{}},{"cell_type":"code","source":"for c in C:\n    model = LogisticRegression(solver='liblinear', penalty='l2', C=c)\n    model.fit(train_x, train_y)\n    prediction = model.predict(valid_x)\n    f1 = f1_score(valid_y, prediction)\n    acc = accuracy_score(valid_y, prediction)\n    print(\"Regularization: \", c)\n    print(\"F1 score: \",f1)\n    print(\"Acc score: \",acc)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:01:20.088435Z","iopub.execute_input":"2022-01-06T12:01:20.088684Z","iopub.status.idle":"2022-01-06T12:12:11.9133Z","shell.execute_reply.started":"2022-01-06T12:01:20.088649Z","shell.execute_reply":"2022-01-06T12:12:11.911666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét**: Có thể thấy , giá trị Regularization tốt nhất là 30,  Vì hàm predict sẽ trả về một sample là sincere hay không bằng cách so sánh xác suất đầu ra với một giá trị mặc định threshold = 0.5 (decision bound = 0), ta sẽ thử thay đổi mức threshold này.","metadata":{}},{"cell_type":"code","source":"thresholds = [0.5, 0.1, 0.14, 0.15, 0.16, 0.17, 0.25, 0.3, 0.4, 0.55, 0.7]\nc = 30\nmodel = LogisticRegression(solver='liblinear', penalty='l2', C=c)\nmodel.fit(train_x, train_y)\npredict = model.predict_proba(valid_x)[:,1]\nfor t in thresholds:\n    predict_t = np.where(predict > t, 1, 0)\n    f1 = f1_score(valid_y, predict_t)\n    print(\"Threshold: \", t)\n    print(\"F1 score: \", f1)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:12:11.914731Z","iopub.execute_input":"2022-01-06T12:12:11.91497Z","iopub.status.idle":"2022-01-06T12:13:23.735241Z","shell.execute_reply.started":"2022-01-06T12:12:11.914937Z","shell.execute_reply":"2022-01-06T12:13:23.734533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét**: Tại Threshold = 0.15 , giá trị F1 score là tốt nhất cho tập val","metadata":{}},{"cell_type":"code","source":"t= 0.15\npredict = model.predict_proba(valid_x)[:,1]\npredict = np.where(predict > t, 1, 0)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:13:23.736468Z","iopub.execute_input":"2022-01-06T12:13:23.736796Z","iopub.status.idle":"2022-01-06T12:13:23.77416Z","shell.execute_reply.started":"2022-01-06T12:13:23.736758Z","shell.execute_reply":"2022-01-06T12:13:23.773422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix(valid_y, predict)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:13:23.775419Z","iopub.execute_input":"2022-01-06T12:13:23.775753Z","iopub.status.idle":"2022-01-06T12:13:24.168642Z","shell.execute_reply.started":"2022-01-06T12:13:23.775716Z","shell.execute_reply":"2022-01-06T12:13:24.167986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét**: Vì số sample có nhãn 1 chỉ chiếm 6% tổng số sample, ta thử sử dụng class **weight** để cải tiến model. Coi 1 sample có label 1 như 14 samples có label 0.","metadata":{}},{"cell_type":"code","source":"class_weight = {0: 1., 1: 14.}\nthresholds = [0.1, 0.25, 0.3, 0.35, 0.4, 0.55, 0.6, 0.7, 0.8, 0.85, 0.9]\nc = 30\nmodel = LogisticRegression(solver='liblinear', penalty='l2', C=c, class_weight = class_weight)\nmodel.fit(train_x, train_y)\npredict = model.predict_proba(valid_x)[:,1]\nfor t in thresholds:\n    predict_t = np.where(predict > t, 1, 0)\n    f1 = f1_score(valid_y, predict_t)\n    print(\"Threshold: \", t)\n    print(\"F1 score: \", f1)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:13:24.169827Z","iopub.execute_input":"2022-01-06T12:13:24.170062Z","iopub.status.idle":"2022-01-06T12:15:56.37978Z","shell.execute_reply.started":"2022-01-06T12:13:24.170028Z","shell.execute_reply":"2022-01-06T12:15:56.379085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Nhận xét**: Model này cho kết quả F1-score không tốt bằng model trước , vì vậy ta sẽ dùng kết quả của model trước để dự toán kết quả cho tập test ","metadata":{}},{"cell_type":"code","source":"# Kiểm tra dữ liệu có trong tập test\ntest.head(20)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:15:56.381186Z","iopub.execute_input":"2022-01-06T12:15:56.381536Z","iopub.status.idle":"2022-01-06T12:15:56.3962Z","shell.execute_reply.started":"2022-01-06T12:15:56.38149Z","shell.execute_reply":"2022-01-06T12:15:56.395266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = LogisticRegression(solver='liblinear', penalty='l2', C=30)\nmodel.fit(train_feature_matrics, train['target'])\npredict = model.predict_proba(test_feature_matrics)[:,1]\npredict = np.where(predict > 0.17, 1, 0)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:15:56.398092Z","iopub.execute_input":"2022-01-06T12:15:56.398775Z","iopub.status.idle":"2022-01-06T12:17:34.564393Z","shell.execute_reply.started":"2022-01-06T12:15:56.39874Z","shell.execute_reply":"2022-01-06T12:17:34.563652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['prediction'] = predict","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:17:34.565551Z","iopub.execute_input":"2022-01-06T12:17:34.567525Z","iopub.status.idle":"2022-01-06T12:17:34.572184Z","shell.execute_reply.started":"2022-01-06T12:17:34.567485Z","shell.execute_reply":"2022-01-06T12:17:34.571518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6. Kết quả dự đoán trong tập test","metadata":{}},{"cell_type":"code","source":"test.head(20)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:17:34.576155Z","iopub.execute_input":"2022-01-06T12:17:34.57672Z","iopub.status.idle":"2022-01-06T12:17:34.595764Z","shell.execute_reply.started":"2022-01-06T12:17:34.576686Z","shell.execute_reply":"2022-01-06T12:17:34.595015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Kết luận**: Mô hình thử nghiệm trên tập test đã cho ra kết quả phân biệt được đâu là câu hỏi chân thành (**prediction** = 0) và đâu là câu hỏi không trân thành (**prediction** = 1).\n\n","metadata":{}},{"cell_type":"markdown","source":"**Cuối cùng**: tạo file submission .csv chứa kết quả của mô hình. ","metadata":{}},{"cell_type":"code","source":"results = test[['qid', 'prediction']]\nresults.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T12:17:34.597072Z","iopub.execute_input":"2022-01-06T12:17:34.597672Z","iopub.status.idle":"2022-01-06T12:17:35.368026Z","shell.execute_reply.started":"2022-01-06T12:17:34.597612Z","shell.execute_reply":"2022-01-06T12:17:35.367314Z"},"trusted":true},"execution_count":null,"outputs":[]}]}