{"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":"# Clickbait News Detection\n## Semi-supervised and transfer learning approaches to NLP, namely, to Text Classification\n\nWe are provided with labeled articles. Each article consists of label and body. The task is to predict the label (clickbait, news or other).<br>\nWith EDA we get insights to our dataset. We use Text Processing for this NLP project and visualize most frequent words in wordcloud. In the end we peform a Sentiment Analysis using TextBlob.\n\nFor more information about the dataset use the following Kaggle link:<br>\nhttps://www.kaggle.com/competitions/clickbait-news-detection/data","metadata":{}},{"cell_type":"markdown","source":"## Import libraries and load data","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom PIL import Image\n\nimport nltk\nfrom nltk.stem.porter import PorterStemmer\nfrom wordcloud import WordCloud\nfrom wordcloud import STOPWORDS\nfrom sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","scrolled":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-12-28T14:43:19.767072Z","iopub.execute_input":"2022-12-28T14:43:19.768224Z","iopub.status.idle":"2022-12-28T14:43:20.619837Z","shell.execute_reply.started":"2022-12-28T14:43:19.768137Z","shell.execute_reply":"2022-12-28T14:43:20.618880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## EDA - Exploratory Data Analysis","metadata":{}},{"cell_type":"code","source":"# load data, remove index column and rename label column to class\ndf = pd.read_csv('/kaggle/input/clickbait-news-detection/train.csv', skiprows=1, names=['title','text','class'])\ndf.head() # first 5 entries","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:20.625523Z","iopub.execute_input":"2022-12-28T14:43:20.625866Z","iopub.status.idle":"2022-12-28T14:43:21.696577Z","shell.execute_reply.started":"2022-12-28T14:43:20.625834Z","shell.execute_reply":"2022-12-28T14:43:21.695367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# with dictionary map all classes numbers\ndf[\"label\"]=df[\"class\"].map({\"news\":0,\"clickbait\":1,\"other\":2})\ndf.head() # lets see new dataframes first 5 entries","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:21.698037Z","iopub.execute_input":"2022-12-28T14:43:21.698445Z","iopub.status.idle":"2022-12-28T14:43:21.718875Z","shell.execute_reply.started":"2022-12-28T14:43:21.698409Z","shell.execute_reply":"2022-12-28T14:43:21.717613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.info() # infos about the samples, features and datatypes","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:21.722355Z","iopub.execute_input":"2022-12-28T14:43:21.722743Z","iopub.status.idle":"2022-12-28T14:43:21.746056Z","shell.execute_reply.started":"2022-12-28T14:43:21.722706Z","shell.execute_reply":"2022-12-28T14:43:21.744465Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.isnull().sum() # checking for missing values","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:21.747814Z","iopub.execute_input":"2022-12-28T14:43:21.748321Z","iopub.status.idle":"2022-12-28T14:43:21.765556Z","shell.execute_reply.started":"2022-12-28T14:43:21.748274Z","shell.execute_reply":"2022-12-28T14:43:21.764657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We have a total amount of 24871 samples with 4 features. Since we have some missing values in text and title, we are going to fill them with a stopword, so it doesn't disturb our process.","metadata":{}},{"cell_type":"code","source":"df.fillna(\"a\", inplace=True) # fill NaN values with a stopword","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:21.767854Z","iopub.execute_input":"2022-12-28T14:43:21.768384Z","iopub.status.idle":"2022-12-28T14:43:21.785285Z","shell.execute_reply.started":"2022-12-28T14:43:21.768338Z","shell.execute_reply":"2022-12-28T14:43:21.783857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(x=df[\"class\"]); # plot the classes","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:21.787590Z","iopub.execute_input":"2022-12-28T14:43:21.788139Z","iopub.status.idle":"2022-12-28T14:43:22.033177Z","shell.execute_reply.started":"2022-12-28T14:43:21.788055Z","shell.execute_reply":"2022-12-28T14:43:22.031760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Most of our texts are news, then of other type and least is clickbait. Let's proceed to text processing, one of the most important tasks in NLP Projects.","metadata":{}},{"cell_type":"code","source":"# example text before text processing\ndf.text[0]","metadata":{"scrolled":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-12-28T14:43:22.035090Z","iopub.execute_input":"2022-12-28T14:43:22.036437Z","iopub.status.idle":"2022-12-28T14:43:22.045221Z","shell.execute_reply.started":"2022-12-28T14:43:22.036380Z","shell.execute_reply":"2022-12-28T14:43:22.043903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Text Processing in NLP projects:\n* Convert all text to lowercase\n* Remove punctuation marks\n* Remove numbers\n* Remove line break and enter \\r \\n\n* Stop words (remove unnecessary words)\n* Tokenize the text\n* Remmove suffixes with Lemma and Stemma and find roots\n* Convert texts to numbers with Vectorize","metadata":{}},{"cell_type":"code","source":"# Text Processing\ndf[\"text\"]=df[\"text\"].str.lower() # convert to lowercase\ndf[\"text\"]=df[\"text\"].str.replace('[^\\w\\s]','') # remoove punctioation marks\ndf[\"text\"]=df[\"text\"].str.replace('\\d+','') # remove numbers\ndf[\"text\"]=df[\"text\"].str.replace('\\n',' ').replace('\\r',' ') # remove line break and enter \\r \\n","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:22.046943Z","iopub.execute_input":"2022-12-28T14:43:22.048163Z","iopub.status.idle":"2022-12-28T14:43:25.502344Z","shell.execute_reply.started":"2022-12-28T14:43:22.048104Z","shell.execute_reply":"2022-12-28T14:43:25.501098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.text[0]","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2022-12-28T14:43:25.504329Z","iopub.execute_input":"2022-12-28T14:43:25.504723Z","iopub.status.idle":"2022-12-28T14:43:25.512752Z","shell.execute_reply.started":"2022-12-28T14:43:25.504688Z","shell.execute_reply":"2022-12-28T14:43:25.511520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# example text after text processing\ndf.text[0]","metadata":{"scrolled":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-12-28T14:43:25.514842Z","iopub.execute_input":"2022-12-28T14:43:25.515336Z","iopub.status.idle":"2022-12-28T14:43:25.525820Z","shell.execute_reply.started":"2022-12-28T14:43:25.515291Z","shell.execute_reply":"2022-12-28T14:43:25.524510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Wordclouds\nWordclouds (WC) allow us the visual representations of the frequency and relative importance of words in a given body of text.<br>\nWe are going to generate 3 Wordcloud; for news, clickbait and other.","metadata":{}},{"cell_type":"code","source":"# Function to create a Wordcloud\ndef wc(data,bgcolor):\n    plt.figure(figsize=(10,10))\n    mask=np.array(Image.open(\"/kaggle/input/silhouette/news.png\"))\n    wc=WordCloud(background_color=bgcolor,stopwords=STOPWORDS,mask=mask) \n    wc.generate(' '.join(data)) \n    plt.imshow(wc) \n    plt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:29:14.319116Z","iopub.execute_input":"2022-12-28T15:29:14.319557Z","iopub.status.idle":"2022-12-28T15:29:14.328312Z","shell.execute_reply.started":"2022-12-28T15:29:14.319519Z","shell.execute_reply":"2022-12-28T15:29:14.326909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# seperate texts for each class\nnews=df[df[\"class\"]==\"news\"][\"text\"] # only news texts\nclickbait=df[df[\"class\"]==\"clickbait\"][\"text\"] # # only clickbait texts\nother=df[df[\"class\"]==\"other\"][\"text\"] # # only other texts","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:25.546494Z","iopub.execute_input":"2022-12-28T14:43:25.546910Z","iopub.status.idle":"2022-12-28T14:43:25.574467Z","shell.execute_reply.started":"2022-12-28T14:43:25.546874Z","shell.execute_reply":"2022-12-28T14:43:25.573169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"news.shape, clickbait.shape, other.shape # see the shape of the classes","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:43:25.576623Z","iopub.execute_input":"2022-12-28T14:43:25.576967Z","iopub.status.idle":"2022-12-28T14:43:25.584788Z","shell.execute_reply.started":"2022-12-28T14:43:25.576936Z","shell.execute_reply":"2022-12-28T14:43:25.583429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wc(news,'white') # WC for news","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:29:17.233802Z","iopub.execute_input":"2022-12-28T15:29:17.234233Z","iopub.status.idle":"2022-12-28T15:29:58.835205Z","shell.execute_reply.started":"2022-12-28T15:29:17.234198Z","shell.execute_reply":"2022-12-28T15:29:58.833970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wc(clickbait,'red') # WC for clickabit","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:28:29.505695Z","iopub.execute_input":"2022-12-28T15:28:29.506642Z","iopub.status.idle":"2022-12-28T15:28:44.020803Z","shell.execute_reply.started":"2022-12-28T15:28:29.506601Z","shell.execute_reply":"2022-12-28T15:28:44.019524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wc(other,'black') # WC for other","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:29:04.425884Z","iopub.execute_input":"2022-12-28T15:29:04.427128Z","iopub.status.idle":"2022-12-28T15:29:11.349723Z","shell.execute_reply.started":"2022-12-28T15:29:04.427081Z","shell.execute_reply":"2022-12-28T15:29:11.348872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It seems to me that all the wordclouds have almost the same words in it, or at least they are very similar.","metadata":{}},{"cell_type":"markdown","source":"## Modelling\nAfter assignin our X(features) and y (target), we use a Vectorizer to convert our text documents into a matrix, then we split our data to train and test sets and with various Classifiers we try to train our Model.","metadata":{}},{"cell_type":"code","source":"# assign x and y - features are texts and target is label\nx,y =df[\"text\"], df[\"label\"]","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:44:06.892134Z","iopub.execute_input":"2022-12-28T14:44:06.892826Z","iopub.status.idle":"2022-12-28T14:44:06.904018Z","shell.execute_reply.started":"2022-12-28T14:44:06.892787Z","shell.execute_reply":"2022-12-28T14:44:06.902598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The **CountVectorizer** is a tool from the scikit-learn library that can be used to convert a collection of text documents into a matrix of token counts. ","metadata":{}},{"cell_type":"code","source":"# Vectorize text data, ignoring stop words\nvect=CountVectorizer(stop_words=\"english\")\nx=vect.fit_transform(x)\n# split to train and test data\nx_train,x_test,y_train,y_test=train_test_split(x,y,random_state=42,test_size=.15)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:44:06.905992Z","iopub.execute_input":"2022-12-28T14:44:06.906538Z","iopub.status.idle":"2022-12-28T14:44:16.788714Z","shell.execute_reply.started":"2022-12-28T14:44:06.906496Z","shell.execute_reply":"2022-12-28T14:44:16.787388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#importing Classification libraries\nfrom sklearn.naive_bayes import MultinomialNB\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.ensemble import RandomForestClassifier\nfrom xgboost import XGBClassifier\n\n# create an instance of each classification algorithm\nmb=MultinomialNB()\nD=DecisionTreeClassifier()\nKN=KNeighborsClassifier() \nR=RandomForestClassifier()\nXGB=XGBClassifier()\n\nclassifiers = [mb, D, KN, R, XGB]\n\n# list of classifier names\nclassifier_names = ['MultinomialNB', 'DecisionTreeClassifier', 'KNeighborsClassifier', 'RandomForestClassifier', 'XGBClassifier']\n\n# create an empty dataframe\ndf = pd.DataFrame(columns=['classifier', 'accuracy'])\n\n# loop through classifiers and get predictions\nfor i, clf in enumerate(classifiers):\n    pred = clf.fit(x_train, y_train).predict(x_test)\n    score = accuracy_score(pred, y_test)\n    df.loc[i] = [classifier_names[i], score]","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:44:16.790116Z","iopub.execute_input":"2022-12-28T14:44:16.790471Z","iopub.status.idle":"2022-12-28T14:49:47.775097Z","shell.execute_reply.started":"2022-12-28T14:44:16.790439Z","shell.execute_reply":"2022-12-28T14:49:47.774098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sort the dataframe by the accuracy column in descending order\ndf.sort_values(by='accuracy', ascending=False, inplace=True)\ndf","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:49:47.776690Z","iopub.execute_input":"2022-12-28T14:49:47.781016Z","iopub.status.idle":"2022-12-28T14:49:47.799179Z","shell.execute_reply.started":"2022-12-28T14:49:47.780962Z","shell.execute_reply":"2022-12-28T14:49:47.797418Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can see that the best result shows the **XGBClassifier with an Accuracy of 84,96%,** followed by the RandomForestClassifier with similar accuracy.","metadata":{}},{"cell_type":"markdown","source":"## We could also show the titles in a Wordcloud","metadata":{}},{"cell_type":"code","source":"# load data, remove index column and rename label column to class\ndf = pd.read_csv('/kaggle/input/clickbait-news-detection/train.csv', skiprows=1, names=['title','text','class'])\ndf.fillna(\"a\", inplace=True) # fill NaN values with a stopword\ndf.head() # first 5 entries","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:49:47.801097Z","iopub.execute_input":"2022-12-28T14:49:47.801445Z","iopub.status.idle":"2022-12-28T14:49:48.768819Z","shell.execute_reply.started":"2022-12-28T14:49:47.801414Z","shell.execute_reply":"2022-12-28T14:49:48.767488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Text Processing\ndf[\"title\"]=df[\"title\"].str.lower() # convert to lowercase\ndf[\"title\"]=df[\"title\"].str.replace('[^\\w\\s]','') # remoove punctioation marks\ndf[\"title\"]=df[\"title\"].str.replace('\\d+','') # remove numbers\ndf[\"title\"]=df[\"title\"].str.replace('\\n',' ').replace('\\r',' ') # remove line break and enter \\r \\n","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:49:48.771240Z","iopub.execute_input":"2022-12-28T14:49:48.771730Z","iopub.status.idle":"2022-12-28T14:49:48.910569Z","shell.execute_reply.started":"2022-12-28T14:49:48.771684Z","shell.execute_reply":"2022-12-28T14:49:48.909184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.title[0] # example title after text processing","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:49:48.912398Z","iopub.execute_input":"2022-12-28T14:49:48.912877Z","iopub.status.idle":"2022-12-28T14:49:48.920763Z","shell.execute_reply.started":"2022-12-28T14:49:48.912822Z","shell.execute_reply":"2022-12-28T14:49:48.919568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wc(df.title,'white')","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:49:48.922816Z","iopub.execute_input":"2022-12-28T14:49:48.923307Z","iopub.status.idle":"2022-12-28T14:49:54.610755Z","shell.execute_reply.started":"2022-12-28T14:49:48.923262Z","shell.execute_reply":"2022-12-28T14:49:54.609507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Interesting to see that the word with most frequency in the titles include \"trump\". We can also see words like obama, russia, china and more.","metadata":{}},{"cell_type":"markdown","source":"## Sentiment Analysis - Using TextBlob\nSentiment analysis with TextBlob: TextBlob can perform sentiment analysis on a text, which involves determining the overall sentiment expressed in the text (e.g., positive, negative, neutral).","metadata":{}},{"cell_type":"code","source":"# import TextBlob\nfrom textblob import TextBlob","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:51:56.652031Z","iopub.execute_input":"2022-12-28T14:51:56.652510Z","iopub.status.idle":"2022-12-28T14:51:56.707588Z","shell.execute_reply.started":"2022-12-28T14:51:56.652470Z","shell.execute_reply":"2022-12-28T14:51:56.706324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# function for sentiment analysis\ndef detect_sentiment(text):\n    return TextBlob(text).sentiment.polarity","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:51:58.920796Z","iopub.execute_input":"2022-12-28T14:51:58.921222Z","iopub.status.idle":"2022-12-28T14:51:58.927623Z","shell.execute_reply.started":"2022-12-28T14:51:58.921186Z","shell.execute_reply":"2022-12-28T14:51:58.926198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define new dataframe\ndf_sent=df[[\"text\"]] \ndf_sent.head()","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:52:24.819131Z","iopub.execute_input":"2022-12-28T14:52:24.819543Z","iopub.status.idle":"2022-12-28T14:52:24.832616Z","shell.execute_reply.started":"2022-12-28T14:52:24.819509Z","shell.execute_reply":"2022-12-28T14:52:24.831407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# call sentiment function on our text and create new column with values\ndf_sent[\"sentiment\"]=df_sent[\"text\"].apply(detect_sentiment)\ndf_sent.head()","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:53:26.621294Z","iopub.execute_input":"2022-12-28T14:53:26.621687Z","iopub.status.idle":"2022-12-28T14:55:03.933403Z","shell.execute_reply.started":"2022-12-28T14:53:26.621657Z","shell.execute_reply":"2022-12-28T14:55:03.932075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sent.sentiment.value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:55:15.761453Z","iopub.execute_input":"2022-12-28T14:55:15.761865Z","iopub.status.idle":"2022-12-28T14:55:15.784283Z","shell.execute_reply.started":"2022-12-28T14:55:15.761832Z","shell.execute_reply":"2022-12-28T14:55:15.782708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wc(df_sent.text,'white')","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:55:43.067654Z","iopub.execute_input":"2022-12-28T14:55:43.068040Z","iopub.status.idle":"2022-12-28T14:56:36.510634Z","shell.execute_reply.started":"2022-12-28T14:55:43.068010Z","shell.execute_reply":"2022-12-28T14:56:36.509650Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Epsilon Neighborhood\nIn the context of sentiment analysis, epsilon neighborhoods can be used to identify reviews that express similar sentiments. For example, we might define an epsilon neighborhood around a review that is very positive, and then identify all other reviews that fall within that neighborhood as also being very positive.","metadata":{}},{"cell_type":"code","source":"# 1 positive\n# 2 negative\n# 0 neutral\ndef sentiment2(sent):\n    if sent<-0.02: #0.02:limit\n        return 2\n    elif sent>0.02:\n        return 1\n    else:\n        return 0","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:56:36.512199Z","iopub.execute_input":"2022-12-28T14:56:36.513087Z","iopub.status.idle":"2022-12-28T14:56:36.518435Z","shell.execute_reply.started":"2022-12-28T14:56:36.513029Z","shell.execute_reply":"2022-12-28T14:56:36.517335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# apply new sentiment function \ndf_sent[\"sent\"]=df_sent[\"sentiment\"].apply(sentiment2)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:56:36.519991Z","iopub.execute_input":"2022-12-28T14:56:36.520377Z","iopub.status.idle":"2022-12-28T14:56:36.546225Z","shell.execute_reply.started":"2022-12-28T14:56:36.520345Z","shell.execute_reply":"2022-12-28T14:56:36.541902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sent.head()","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:56:59.571643Z","iopub.execute_input":"2022-12-28T14:56:59.572023Z","iopub.status.idle":"2022-12-28T14:56:59.583896Z","shell.execute_reply.started":"2022-12-28T14:56:59.571994Z","shell.execute_reply":"2022-12-28T14:56:59.582552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(df_sent.sent); # plot the sentiment analysis","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:57:08.814494Z","iopub.execute_input":"2022-12-28T14:57:08.815097Z","iopub.status.idle":"2022-12-28T14:57:09.033159Z","shell.execute_reply.started":"2022-12-28T14:57:08.815013Z","shell.execute_reply":"2022-12-28T14:57:09.031801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sent.sent.value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:57:21.423890Z","iopub.execute_input":"2022-12-28T14:57:21.424746Z","iopub.status.idle":"2022-12-28T14:57:21.434607Z","shell.execute_reply.started":"2022-12-28T14:57:21.424696Z","shell.execute_reply":"2022-12-28T14:57:21.433138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We have 18837 positive, 2757 negative and 3277 neutral comments","metadata":{}},{"cell_type":"markdown","source":"## Modeling - Sentiment Analysis","metadata":{}},{"cell_type":"code","source":"# assign x and y\nx, y=df_sent.text, df_sent.sent","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:58:26.254873Z","iopub.execute_input":"2022-12-28T14:58:26.255298Z","iopub.status.idle":"2022-12-28T14:58:26.261039Z","shell.execute_reply.started":"2022-12-28T14:58:26.255263Z","shell.execute_reply":"2022-12-28T14:58:26.259767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Vectorize X\nvect=CountVectorizer(stop_words=\"english\")\nx=vect.fit_transform(x) ","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:58:36.484226Z","iopub.execute_input":"2022-12-28T14:58:36.484611Z","iopub.status.idle":"2022-12-28T14:58:46.289275Z","shell.execute_reply.started":"2022-12-28T14:58:36.484582Z","shell.execute_reply":"2022-12-28T14:58:46.287818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# split into train and test sets\nx_train,x_test,y_train,y_test=train_test_split(x,y,random_state=42,test_size=.15)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:58:53.931774Z","iopub.execute_input":"2022-12-28T14:58:53.932187Z","iopub.status.idle":"2022-12-28T14:58:53.955143Z","shell.execute_reply.started":"2022-12-28T14:58:53.932152Z","shell.execute_reply":"2022-12-28T14:58:53.954272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#importing Classification libraries\nfrom sklearn.naive_bayes import MultinomialNB\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.ensemble import RandomForestClassifier\nfrom xgboost import XGBClassifier\n\n# create an instance of each classification algorithm\nmb=MultinomialNB()\nD=DecisionTreeClassifier()\nKN=KNeighborsClassifier() \nR=RandomForestClassifier()\nXGB=XGBClassifier()\n\nclassifiers = [mb, D, KN, R, XGB]\n\n# list of classifier names\nclassifier_names = ['MultinomialNB', 'DecisionTreeClassifier', 'KNeighborsClassifier', 'RandomForestClassifier', 'XGBClassifier']\n\n# create an empty dataframe\ndf2 = pd.DataFrame(columns=['classifier', 'accuracy'])\n\n# loop through classifiers and get predictions\nfor i, clf in enumerate(classifiers):\n    pred = clf.fit(x_train, y_train).predict(x_test)\n    score = accuracy_score(pred, y_test)\n    df2.loc[i] = [classifier_names[i], score]","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:03:23.415685Z","iopub.execute_input":"2022-12-28T15:03:23.416116Z","iopub.status.idle":"2022-12-28T15:08:58.995221Z","shell.execute_reply.started":"2022-12-28T15:03:23.416054Z","shell.execute_reply":"2022-12-28T15:08:58.994243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sort the dataframe by the accuracy column in descending order\ndf2.sort_values(by='accuracy', ascending=False, inplace=True)\ndf2","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:08:58.997151Z","iopub.execute_input":"2022-12-28T15:08:58.998026Z","iopub.status.idle":"2022-12-28T15:08:59.011469Z","shell.execute_reply.started":"2022-12-28T15:08:58.997986Z","shell.execute_reply":"2022-12-28T15:08:59.010531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Afters using TextBlobs Sentiment function the best results are from the **RandomForestClassifier with an Accuracy of 79,28%.**","metadata":{}},{"cell_type":"code","source":"positive=df_sent[df_sent[\"sent\"]==1][\"text\"] # only positive\nneutral=df_sent[df_sent[\"sent\"]==0][\"text\"] # only neutral\nnegative=df_sent[df_sent[\"sent\"]==2][\"text\"] # only negative","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:13:21.978387Z","iopub.execute_input":"2022-12-28T15:13:21.978792Z","iopub.status.idle":"2022-12-28T15:13:21.990839Z","shell.execute_reply.started":"2022-12-28T15:13:21.978762Z","shell.execute_reply":"2022-12-28T15:13:21.989521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Wordclouds for Sentiment Analysis","metadata":{}},{"cell_type":"code","source":"wc(positive,'white') # WC for positive sentiment analysis","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:16:58.655161Z","iopub.execute_input":"2022-12-28T15:16:58.655641Z","iopub.status.idle":"2022-12-28T15:17:44.219739Z","shell.execute_reply.started":"2022-12-28T15:16:58.655601Z","shell.execute_reply":"2022-12-28T15:17:44.218477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wc(negative,'red') # WC for negative sentiment analysis","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:20:43.993707Z","iopub.execute_input":"2022-12-28T15:20:43.994124Z","iopub.status.idle":"2022-12-28T15:20:48.893884Z","shell.execute_reply.started":"2022-12-28T15:20:43.994080Z","shell.execute_reply":"2022-12-28T15:20:48.893036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wc(neutral,'black') # WC for neutral sentiment analysis","metadata":{"execution":{"iopub.status.busy":"2022-12-28T15:21:20.615636Z","iopub.execute_input":"2022-12-28T15:21:20.616020Z","iopub.status.idle":"2022-12-28T15:21:26.589268Z","shell.execute_reply.started":"2022-12-28T15:21:20.615991Z","shell.execute_reply":"2022-12-28T15:21:26.587880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}