{"cells":[{"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\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 5GB 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","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Loading the library","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport csv\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import Markdown, display\ndef printmd(string):\n    display(Markdown(string))\n#printmd('**bold**')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_path=\"/kaggle/input/jigsaw-multilingual-toxic-comment-classification/jigsaw-toxic-comment-train.csv\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_raw = pd.read_csv(data_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_raw.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of rows in data =\",data_raw.shape[0])\nprint(\"Number of columns in data =\",data_raw.shape[1])\nprint(\"\\n\")\nprintmd(\"**Sample data:**\")\ndata_raw.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Checking for missing values","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\nmissing_values_check = data_raw.isnull().sum()\nprint(missing_values_check)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Calculating number of comments under each label","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# Comments with no label are considered to be clean comments.\n# Creating seperate column in dataframe to identify clean comments.\n\n# We use axis=1 to count row-wise and axis=0 to count column wise\n\nrowSums = data_raw.iloc[:,2:].sum(axis=1)\nclean_comments_count = (rowSums==0).sum(axis=0)\n\nprint(\"Total number of comments = \",len(data_raw))\nprint(\"Number of clean comments = \",clean_comments_count)\nprint(\"Number of comments with labels =\",(len(data_raw)-clean_comments_count))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"categories = list(data_raw.columns.values)\ncategories = categories[2:]\nprint(categories)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Calculating number of comments in each category\n\ncounts = []\nfor category in categories:\n    counts.append((category, data_raw[category].sum()))\ndf_stats = pd.DataFrame(counts, columns=['category', 'number of comments'])\ndf_stats","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.set(font_scale = 2)\nplt.figure(figsize=(15,8))\n\nax= sns.barplot(categories, data_raw.iloc[:,2:].sum().values)\n\nplt.title(\"Comments in each category\", fontsize=24)\nplt.ylabel('Number of comments', fontsize=18)\nplt.xlabel('Comment Type ', fontsize=18)\n\n#adding the text labels\nrects = ax.patches\nlabels = data_raw.iloc[:,2:].sum().values\nfor rect, label in zip(rects, labels):\n    height = rect.get_height()\n    ax.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom', fontsize=18)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Calculating number of comments having multiple labels","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"rowSums = data_raw.iloc[:,2:].sum(axis=1)\nmultiLabel_counts = rowSums.value_counts()\nmultiLabel_counts = multiLabel_counts.iloc[1:]\n\nsns.set(font_scale = 2)\nplt.figure(figsize=(15,8))\n\nax = sns.barplot(multiLabel_counts.index, multiLabel_counts.values)\n\nplt.title(\"Comments having multiple labels \")\nplt.ylabel('Number of comments', fontsize=18)\nplt.xlabel('Number of labels', fontsize=18)\n\n#adding the text labels\nrects = ax.patches\nlabels = multiLabel_counts.values\nfor rect, label in zip(rects, labels):\n    height = rect.get_height()\n    ax.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom')\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":" ## WordCloud representation of most used words in each category of comments","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from wordcloud import WordCloud,STOPWORDS\n\nplt.figure(figsize=(40,25))\n\n# toxic\nsubset = data_raw[data_raw.toxic==1]\ntext = subset.comment_text.values\ncloud_toxic = WordCloud(\n                          stopwords=STOPWORDS,\n                          background_color='black',\n                          collocations=False,\n                          width=2500,\n                          height=1800\n                         ).generate(\" \".join(text))\n\nplt.subplot(2, 3, 1)\nplt.axis('off')\nplt.title(\"Toxic\",fontsize=40)\nplt.imshow(cloud_toxic)\n\n\n# severe_toxic\nsubset = data_raw[data_raw.severe_toxic==1]\ntext = subset.comment_text.values\ncloud_severe_toxic = WordCloud(\n                          stopwords=STOPWORDS,\n                          background_color='black',\n                          collocations=False,\n                          width=2500,\n                          height=1800\n                         ).generate(\" \".join(text))\n\nplt.subplot(2, 3, 2)\nplt.axis('off')\nplt.title(\"Severe Toxic\",fontsize=40)\nplt.imshow(cloud_severe_toxic)\n\n\n# obscene\nsubset = data_raw[data_raw.obscene==1]\ntext = subset.comment_text.values\ncloud_obscene = WordCloud(\n                          stopwords=STOPWORDS,\n                          background_color='black',\n                          collocations=False,\n                          width=2500,\n                          height=1800\n                         ).generate(\" \".join(text))\n\nplt.subplot(2, 3, 3)\nplt.axis('off')\nplt.title(\"Obscene\",fontsize=40)\nplt.imshow(cloud_obscene)\n\n\n# threat\nsubset = data_raw[data_raw.threat==1]\ntext = subset.comment_text.values\ncloud_threat = WordCloud(\n                          stopwords=STOPWORDS,\n                          background_color='black',\n                          collocations=False,\n                          width=2500,\n                          height=1800\n                         ).generate(\" \".join(text))\n\nplt.subplot(2, 3, 4)\nplt.axis('off')\nplt.title(\"Threat\",fontsize=40)\nplt.imshow(cloud_threat)\n\n\n# insult\nsubset = data_raw[data_raw.insult==1]\ntext = subset.comment_text.values\ncloud_insult = WordCloud(\n                          stopwords=STOPWORDS,\n                          background_color='black',\n                          collocations=False,\n                          width=2500,\n                          height=1800\n                         ).generate(\" \".join(text))\n\nplt.subplot(2, 3, 5)\nplt.axis('off')\nplt.title(\"Insult\",fontsize=40)\nplt.imshow(cloud_insult)\n\n\n# identity_hate\nsubset = data_raw[data_raw.identity_hate==1]\ntext = subset.comment_text.values\ncloud_identity_hate = WordCloud(\n                          stopwords=STOPWORDS,\n                          background_color='black',\n                          collocations=False,\n                          width=2500,\n                          height=1800\n                         ).generate(\" \".join(text))\n\nplt.subplot(2, 3, 6)\nplt.axis('off')\nplt.title(\"Identity Hate\",fontsize=40)\nplt.imshow(cloud_identity_hate)\n\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data Pre-Processing","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"data = data_raw\ndata = data_raw.loc[np.random.choice(data_raw.index, size=2000)]\ndata.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import nltk\nfrom nltk.corpus import stopwords\nfrom nltk.stem.snowball import SnowballStemmer\nimport re\n\nimport sys\nimport warnings\n\nif not sys.warnoptions:\n    warnings.simplefilter(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Cleaning Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def cleanHtml(sentence):\n    cleanr = re.compile('<.*?>')\n    cleantext = re.sub(cleanr, ' ', str(sentence))\n    return cleantext\n\n\ndef cleanPunc(sentence): #function to clean the word of any punctuation or special characters\n    cleaned = re.sub(r'[?|!|\\'|\"|#]',r'',sentence)\n    cleaned = re.sub(r'[.|,|)|(|\\|/]',r' ',cleaned)\n    cleaned = cleaned.strip()\n    cleaned = cleaned.replace(\"\\n\",\" \")\n    return cleaned\n\n\ndef keepAlpha(sentence):\n    alpha_sent = \"\"\n    for word in sentence.split():\n        alpha_word = re.sub('[^a-z A-Z]+', ' ', word)\n        alpha_sent += alpha_word\n        alpha_sent += \" \"\n    alpha_sent = alpha_sent.strip()\n    return alpha_sent","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['comment_text'] = data['comment_text'].str.lower()\ndata['comment_text'] = data['comment_text'].apply(cleanHtml)\ndata['comment_text'] = data['comment_text'].apply(cleanPunc)\ndata['comment_text'] = data['comment_text'].apply(keepAlpha)\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Removing Stop Words¶","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"stop_words = set(stopwords.words('english'))\nstop_words.update(['zero','one','two','three','four','five','six','seven','eight','nine','ten','may','also','across','among','beside','however','yet','within'])\nre_stop_words = re.compile(r\"\\b(\" + \"|\".join(stop_words) + \")\\\\W\", re.I)\ndef removeStopWords(sentence):\n    global re_stop_words\n    return re_stop_words.sub(\" \", sentence)\n\ndata['comment_text'] = data['comment_text'].apply(removeStopWords)\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Stemming","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\nstemmer = SnowballStemmer(\"english\")\ndef stemming(sentence):\n    stemSentence = \"\"\n    for word in sentence.split():\n        stem = stemmer.stem(word)\n        stemSentence += stem\n        stemSentence += \" \"\n    stemSentence = stemSentence.strip()\n    return stemSentence\n\ndata['comment_text'] = data['comment_text'].apply(stemming)\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train-Test Split","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ntrain, test = train_test_split(data, random_state=42, test_size=0.30, shuffle=True)\n\nprint(train.shape)\nprint(test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ntrain_text = train['comment_text']\ntest_text = test['comment_text']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## TF-IDF","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.feature_extraction.text import TfidfVectorizer\nvectorizer = TfidfVectorizer(strip_accents='unicode', analyzer='word', ngram_range=(1,3), norm='l2')\nvectorizer.fit(train_text)\nvectorizer.fit(test_text)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nx_train = vectorizer.transform(train_text)\ny_train = train.drop(labels = ['id','comment_text'], axis=1)\n\nx_test = vectorizer.transform(test_text)\ny_test = test.drop(labels = ['id','comment_text'], axis=1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Multi-Label Classification\n## Multiple Binary Classifications - (One Vs Rest Classifier)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.linear_model import LogisticRegression\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.multiclass import OneVsRestClassifier","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n%%time\n\n# Using pipeline for applying logistic regression and one vs rest classifier\nLogReg_pipeline = Pipeline([\n                ('clf', OneVsRestClassifier(LogisticRegression(solver='sag'), n_jobs=-1)),\n            ])\n\nfor category in categories:\n    printmd('**Processing {} comments...**'.format(category))\n    \n    # Training logistic regression model on train data\n    LogReg_pipeline.fit(x_train, train[category])\n    \n    # calculating test accuracy\n    prediction = LogReg_pipeline.predict(x_test)\n    print('Test accuracy is {}'.format(accuracy_score(test[category], prediction)))\n    print(\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Multiple Binary Classifications - (Binary Relevance)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\n# using binary relevance\nfrom skmultilearn.problem_transform import BinaryRelevance\nfrom sklearn.naive_bayes import GaussianNB\n\n# initialize binary relevance multi-label classifier\n# with a gaussian naive bayes base classifier\nclassifier = BinaryRelevance(GaussianNB())\n\n# train\nclassifier.fit(x_train, y_train)\n\n# predict\npredictions = classifier.predict(x_test)\n\n# accuracy\nprint(\"Accuracy = \",accuracy_score(y_test,predictions))\nprint(\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### **Classifier Chains**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# using classifier chains\nfrom skmultilearn.problem_transform import ClassifierChain\nfrom sklearn.linear_model import LogisticRegression","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\n# initialize classifier chains multi-label classifier\nclassifier = ClassifierChain(LogisticRegression())\n\n# Training logistic regression model on train data\nclassifier.fit(x_train, y_train)\n\n# predict\npredictions = classifier.predict(x_test)\n\n# accuracy\nprint(\"Accuracy = \",accuracy_score(y_test,predictions))\nprint(\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"##  Label Powerset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# using Label Powerset\nfrom skmultilearn.problem_transform import LabelPowerset","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n%%time\n\n# initialize label powerset multi-label classifier\nclassifier = LabelPowerset(LogisticRegression())\n\n# train\nclassifier.fit(x_train, y_train)\n\n# predict\npredictions = classifier.predict(x_test)\n\n# accuracy\nprint(\"Accuracy = \",accuracy_score(y_test,predictions))\nprint(\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Adapted Algorithm","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# http://scikit.ml/api/api/skmultilearn.adapt.html#skmultilearn.adapt.MLkNN\n\nfrom skmultilearn.adapt import MLkNN\nfrom scipy.sparse import csr_matrix, lil_matrix","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\nclassifier_new = MLkNN(k=10)\n\n# Note that this classifier can throw up errors when handling sparse matrices.\n\nx_train = lil_matrix(x_train).toarray()\ny_train = lil_matrix(y_train).toarray()\nx_test = lil_matrix(x_test).toarray()\n\n# train\nclassifier_new.fit(x_train, y_train)\n\n# predict\npredictions_new = classifier_new.predict(x_test)\n\n# accuracy\nprint(\"Accuracy = \",accuracy_score(y_test,predictions_new))\nprint(\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":" ","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}