{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ktrain","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport string\nfrom nltk import word_tokenize\nfrom nltk.stem import SnowballStemmer\nimport matplotlib.pyplot as plt\nfrom wordcloud import WordCloud\nimport ktrain\nfrom ktrain import text\nfrom sklearn.model_selection import train_test_split\nimport csv\n\n# Input data files are available in the \"../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# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"data = pd.read_csv('/kaggle/input/jigsaw-multilingual-toxic-comment-classification/jigsaw-toxic-comment-train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def remove_punctuation(text):\n    return ''.join([char for char in text if char not in string.punctuation])\n    \ndef tokenize(text):\n    return word_tokenize(text)\n    \ndef to_lowercase(text):\n    return ''.join([char.lower() for char in text])\n    \ndef stemming(text):\n    snowball_stemmer = SnowballStemmer('english')\n    return ' '.join([snowball_stemmer.stem(word) for word in tokenize(text)])\n\ndef preprocess_text(dataframe_column):\n    dataframe_column = dataframe_column.map(lambda comment : remove_punctuation(comment))\n    dataframe_column = dataframe_column.map(lambda comment : to_lowercase(comment))\n    dataframe_column = dataframe_column.map(lambda comment : stemming(comment))\n    return dataframe_column","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['comment_text'] = preprocess_text(data['comment_text'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['comment_text']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['toxic']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We check percentage of values for each column including the ones having null entries."},{"metadata":{"trusted":true},"cell_type":"code","source":"data['toxic'].value_counts(dropna=False, normalize=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We check the null entries."},{"metadata":{"trusted":true},"cell_type":"code","source":"data.isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"No null entry!"},{"metadata":{},"cell_type":"markdown","source":"Getting stats for columns"},{"metadata":{"trusted":true},"cell_type":"code","source":"data['comment_text'].describe()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We observe that some comments are same."},{"metadata":{"trusted":true},"cell_type":"code","source":"data[data['comment_text'].duplicated()]['toxic']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We check the length of each comment. To do so, we use len() method offered by pandas."},{"metadata":{"trusted":true},"cell_type":"code","source":"data['comment_length'] = list(data[\"comment_text\"].str.len())\ndata['comment_length'].describe()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Mean length of comments is 338."},{"metadata":{},"cell_type":"markdown","source":"It would be good to have an idea of Most Common Words using a Wordcloud."},{"metadata":{},"cell_type":"markdown","source":"Collecting all the comments in a string to analyze."},{"metadata":{"trusted":true},"cell_type":"code","source":"wordcloud_text = ''.join([comment for comment in data['comment_text'][1:1000] if pd.notna(comment)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wordcloud_text","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wordcloud = WordCloud().generate(wordcloud_text)\nplt.imshow(wordcloud)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now we prepare train and test data and keep test size to 33 percent."},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\nx_train = df[\"comment_text\"].head(round((2/3) * len(df[\"comment_text\"])))\ny_train=  df[\"toxic\"].head(round((2/3) * len(df[\"comment_text\"]))).values.tolist()\nx_test = df[\"comment_text\"].tail(round((1/3) * len(df[\"comment_text\"])))\ny_test = df[\"toxic\"].head(round((1/3) * len(df[\"comment_text\"]))).values.tolist()\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train = data[\"comment_text\"].head(2000).values.tolist()\ny_train=  data[\"toxic\"].head(2000).values.tolist()\nx_test = data[\"comment_text\"].tail(660).values.tolist()\ny_test = data[\"toxic\"].tail(660).values.tolist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(x_train), len(y_train), len(x_test), len(y_test)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Our target feature toxic is binary in nature i.e. 1 and 0. A comment is labelled and classified either toxic or not."},{"metadata":{},"cell_type":"markdown","source":"We have used ktrain library to implement BERT (Bidirectional Encoder Representations from Transformers). BERT is a bidirectional training technique as discussed in the paper https://arxiv.org/abs/1810.04805"},{"metadata":{"trusted":true},"cell_type":"code","source":"(x_train,  y_train), (x_test, y_test), preproc = text.texts_from_array(x_train=x_train, y_train=y_train,\n                                                                       x_test=x_test, y_test=y_test,\n                                                                       class_names=['0','1'],\n                                                                       preprocess_mode='bert',\n                                                                       maxlen=338)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We have used maxlen as 338, the mean length of each comment."},{"metadata":{"trusted":true},"cell_type":"code","source":"model = text.text_classifier('bert', train_data=(x_train, y_train), preproc=preproc)\nlearner = ktrain.get_learner(model, train_data=(x_train, y_train), batch_size=3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"result = learner.fit_onecycle(2e-5, 2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validate = learner.validate(val_data=(x_test, y_test), class_names=['0', '1'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictor = ktrain.get_predictor(learner.model, preproc)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictor.get_classes()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"prediction = predictor.predict(data['comment_text'].tail(660).tolist())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"prediction","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(prediction)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Getting index backwords for 33 test data"},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_index = list(data.index[:-661:-1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_index.reverse()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_index[0], submission_index[-1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(submission_index), len(prediction)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_dataframe = pd.DataFrame({'id': submission_index, 'toxic': prediction})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\nsubmission_dataframe.to_csv('submission.csv', index=False)\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('submission.csv', mode='a+') as submission_csv:\n    submission_writer = csv.writer(submission_csv, delimiter=',')\n    submission_writer.writerow(['id', 'toxic'])\n    for index, row in submission_dataframe.iterrows():\n        submission_writer.writerow([row['id'], row['toxic']])","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}