{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TextCL Tutorial\n",
    "\n",
    "1. [Introduction](#Introduction)\n",
    "2. [Preparation](#Preparation)\n",
    "3. [Filtering on language](#Filtering-on-language)\n",
    "4. [Filtering on Jaccard similarity](#Filtering-on-Jaccard-similarity)\n",
    "5. [Filtering on perplexity score](#Filtering-on-perplexity-score)\n",
    "6. [Outliers filtering](#Outliers-filtering)\n",
    "7. [Plots for outlier detection](#Plots-for-outlier-detection)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction\n",
    "\n",
    "This tutorial demonstrates how to preprocess text to clean it up for the modeling stage. Modeling can include classification models, NER (Named Entity Recognition) models, spell checking models, text summarization and generation, as well as prediction models. Usually, this analysis is performed manually and is very time-consuming. The TextCL package helps to identify and filter out (1) sentences in languages other than the target language, (2) linguistically unconnected and/or corrupted sentences, and (3) duplicate sentences.\n",
    "\n",
    "Another feature of the package is to identify and filter out outliers from the text scope. As outliers, we consider texts that don't contextually belong to the main topic of the text. It's important to be able to identify these anomalies without having labeled data, so we can have a general algorithm for unstructured texts and find out the scope blocks.\n",
    "\n",
    "In this tutorial, we will work with the [BBC data set](http://mlg.ucd.ie/files/datasets/bbc-fulltext.zip) and additional manually generated sentences to demonstrate the package's functionality. Overall, the package can be used with any text data set loaded as a [Pandas data frame](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html).\n",
    "\n",
    "The package contains the following functions for text cleaning:\n",
    "\n",
    "1. Filtering on language\n",
    "2. Filtering on Jaccard similarity\n",
    "3. Filtering on perplexity score\n",
    "4. Outliers filtering\n",
    "\n",
    "The first three functions work at the sentence level for each text in the scope. In turn, the outlier filtering function works at the level of the full text. The latter implements 3 different outlier detection algorithms: [TONMF](https://arxiv.org/pdf/1701.01325.pdf), [RPCA](https://github.com/dganguli/robust-pca), and [SVD](https://api.semanticscholar.org/CorpusID:123532178), with `l2` normalisation by default (can be changed to the `l1`, `l2`, or `max` via the `norm` parameter)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preparation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Load package and dependencies:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import textcl\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import random\n",
    "\n",
    "#set up seed for reproducibility\n",
    "seed = 1\n",
    "np.random.seed(seed)\n",
    "random.seed(seed)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's prepare the input data from the [modified BBC dataset](https://github.com/alinapetukhova/textcl/blob/master/examples/prepared_bbc_dataset.csv) bundled with TextCL. First, load the text data. The sample file is located in the `examples` folder, next to this tutorial."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Num texts in the data set: 21\n"
     ]
    }
   ],
   "source": [
    "SOURCE_FILE_PATH = 'prepared_bbc_dataset.csv'\n",
    "\n",
    "input_texts_df = pd.read_csv(SOURCE_FILE_PATH).reset_index()\n",
    "print(\"Num texts in the data set: {}\".format(len(input_texts_df)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this example we'll use a subset of the BBC News data set containing 5 topics (business, entertainment, politics, sport, tech) with manually inserted texts to demonstrate the capabilities of the package. Here's how the dataset looks like:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>topic_name</th>\n",
       "      <th>text</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>business</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>business</td>\n",
       "      <td>Profits slide at India's Dr Reddy  Profits at ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>business</td>\n",
       "      <td>Liberian economy starts to grow  The Liberian ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>business</td>\n",
       "      <td>Uluslararası Para Fonu (IMF), Liberya ekonomis...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>entertainment</td>\n",
       "      <td>Singer Ian Brown 'in gig arrest'  Former Stone...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5</td>\n",
       "      <td>entertainment</td>\n",
       "      <td>Blue beat U2 to top France honour  Irish band ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>6</td>\n",
       "      <td>entertainment</td>\n",
       "      <td>Housewives lift Channel 4 ratings  The debut o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>7</td>\n",
       "      <td>entertainment</td>\n",
       "      <td>Домохозяйки подняли рейтинги канала 4 Дебют ам...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>8</td>\n",
       "      <td>entertainment</td>\n",
       "      <td>Housewives Channel 4 reytinglerini yükseltti A...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>9</td>\n",
       "      <td>politics</td>\n",
       "      <td>Observers to monitor UK election  Ministers wi...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>10</td>\n",
       "      <td>politics</td>\n",
       "      <td>Lib Dems highlight problem debt  People vulner...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>11</td>\n",
       "      <td>politics</td>\n",
       "      <td>Minister defends hunting ban law  The law bann...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>12</td>\n",
       "      <td>sport</td>\n",
       "      <td>Legendary Dutch boss Michels dies  Legendary D...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>13</td>\n",
       "      <td>sport</td>\n",
       "      <td>Connors boost for British tennis  Former world...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>14</td>\n",
       "      <td>sport</td>\n",
       "      <td>Sociedad set to rescue Mladenovic  Rangers are...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>15</td>\n",
       "      <td>tech</td>\n",
       "      <td>Mobile games come of age  The BBC News website...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>16</td>\n",
       "      <td>tech</td>\n",
       "      <td>PlayStation 3 processor unveiled  The Cell pro...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>17</td>\n",
       "      <td>tech</td>\n",
       "      <td>PC photo printers challenge printed pictures c...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>18</td>\n",
       "      <td>tech</td>\n",
       "      <td>PC photo printers challenge pros  Home printed...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>19</td>\n",
       "      <td>tech</td>\n",
       "      <td>processor come pros 43 t6 43 Table data 342 5 ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>20</td>\n",
       "      <td>tech</td>\n",
       "      <td>Janice Dean currently serves as senior meteoro...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    index     topic_name                                               text\n",
       "0       0       business  WorldCom bosses' $54m payout  Ten former direc...\n",
       "1       1       business  Profits slide at India's Dr Reddy  Profits at ...\n",
       "2       2       business  Liberian economy starts to grow  The Liberian ...\n",
       "3       3       business  Uluslararası Para Fonu (IMF), Liberya ekonomis...\n",
       "4       4  entertainment  Singer Ian Brown 'in gig arrest'  Former Stone...\n",
       "5       5  entertainment  Blue beat U2 to top France honour  Irish band ...\n",
       "6       6  entertainment  Housewives lift Channel 4 ratings  The debut o...\n",
       "7       7  entertainment  Домохозяйки подняли рейтинги канала 4 Дебют ам...\n",
       "8       8  entertainment  Housewives Channel 4 reytinglerini yükseltti A...\n",
       "9       9       politics  Observers to monitor UK election  Ministers wi...\n",
       "10     10       politics  Lib Dems highlight problem debt  People vulner...\n",
       "11     11       politics  Minister defends hunting ban law  The law bann...\n",
       "12     12          sport  Legendary Dutch boss Michels dies  Legendary D...\n",
       "13     13          sport  Connors boost for British tennis  Former world...\n",
       "14     14          sport  Sociedad set to rescue Mladenovic  Rangers are...\n",
       "15     15           tech  Mobile games come of age  The BBC News website...\n",
       "16     16           tech  PlayStation 3 processor unveiled  The Cell pro...\n",
       "17     17           tech  PC photo printers challenge printed pictures c...\n",
       "18     18           tech  PC photo printers challenge pros  Home printed...\n",
       "19     19           tech  processor come pros 43 t6 43 Table data 342 5 ...\n",
       "20     20           tech  Janice Dean currently serves as senior meteoro..."
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "input_texts_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Split texts into sentences"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To be able to process/filter sentences from the data set separately, we first need to split our texts into sentences as rows in a Pandas data frame. The [`split_into_sentences()`](https://alinapetukhova.github.io/textcl/docs/preprocessing.html#textcl.preprocessing.split_into_sentences) function is used for this purpose.\n",
    "\n",
    "Notice the data loaded in the previous section has a column named `text`. By default, the `split_into_sentences()` function expects to find texts in this column. However, an alternative name for this column can be specified in the function's `text_col` parameter.\n",
    "\n",
    "Splitting the data set texts into sentences is done as follows, using the `split_into_sentences()` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Num sentences before filtering: 319\n"
     ]
    }
   ],
   "source": [
    "split_input_texts_df = textcl.split_into_sentences(input_texts_df)\n",
    "print(\"Num sentences before filtering: {}\".format(len(split_input_texts_df)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After splitting text data set into sentences, the number of rows increased from 21 to 319. Let's review them:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>topic_name</th>\n",
       "      <th>text</th>\n",
       "      <th>sentence</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>business</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>business</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "      <td>James Wareham, a lawyer representing one of t...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>business</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "      <td>The remaining $36m will be paid by the directo...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>business</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "      <td>But, a spokesman for the prosecutor, New York ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>business</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "      <td>Corporate governance experts said that if the...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   index topic_name                                               text  \\\n",
       "0      0   business  WorldCom bosses' $54m payout  Ten former direc...   \n",
       "1      0   business  WorldCom bosses' $54m payout  Ten former direc...   \n",
       "2      0   business  WorldCom bosses' $54m payout  Ten former direc...   \n",
       "3      0   business  WorldCom bosses' $54m payout  Ten former direc...   \n",
       "4      0   business  WorldCom bosses' $54m payout  Ten former direc...   \n",
       "\n",
       "                                            sentence  \n",
       "0  WorldCom bosses' $54m payout  Ten former direc...  \n",
       "1   James Wareham, a lawyer representing one of t...  \n",
       "2  The remaining $36m will be paid by the directo...  \n",
       "3  But, a spokesman for the prosecutor, New York ...  \n",
       "4   Corporate governance experts said that if the...  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "split_input_texts_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As shown in this example, the `split_into_sentences()` function places sentences in the `sentence` column by default. This can be changed using the function's `sentence_col` parameter."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Filtering on language"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's check how the language filtering function works with manually inserted texts in Russian and Turkish languages to the initial set.\n",
    "\n",
    "To do this we'll use the [`language_filtering()`](https://alinapetukhova.github.io/textcl/docs/preprocessing.html#textcl.preprocessing.language_filtering) function, which filters sentences by language. The input to this function should be a Pandas data frame (with `sentence` column), a threshold value, and a target language. Language score is the threshold used for filtering, with the default value of 0.99. The function makes use of the `detect_language` function from the [langdetect](https://pypi.org/project/langdetect/) package, which returns probabilities of a text belonging to a certain language. All sentences below this threshold will be filtered out."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Num sentences after language filtering: 281\n"
     ]
    }
   ],
   "source": [
    "split_input_texts_df = textcl.language_filtering(split_input_texts_df, threshold=0.99, language='en')\n",
    "print(\"Num sentences after language filtering: {}\".format(len(split_input_texts_df)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The number of rows with sentences was reduced from 319 to 281. Join sentences to the initial texts to review the results:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>sentence</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>Profits slide at India's Dr Reddy  Profits at ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>Liberian economy starts to grow  The Liberian ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>Singer Ian Brown 'in gig arrest'  Former Stone...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Blue beat U2 to top France honour  Irish band ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Housewives lift Channel 4 ratings  The debut o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>9</td>\n",
       "      <td>Observers to monitor UK election  Ministers wi...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>10</td>\n",
       "      <td>Lib Dems highlight problem debt  People vulner...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>11</td>\n",
       "      <td>Minister defends hunting ban law  The law bann...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>12</td>\n",
       "      <td>Legendary Dutch boss Michels dies  Legendary D...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>13</td>\n",
       "      <td>Connors boost for British tennis  Former world...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>14</td>\n",
       "      <td>Sociedad set to rescue Mladenovic  Rangers are...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>15</td>\n",
       "      <td>Mobile games come of age  The BBC News website...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>16</td>\n",
       "      <td>PlayStation 3 processor unveiled  The Cell pro...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>17</td>\n",
       "      <td>PC photo printers challenge printed pictures c...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>18</td>\n",
       "      <td>PC photo printers challenge pros  Home printed...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>19</td>\n",
       "      <td>data clear additional 78.0 long-term 43 those)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>20</td>\n",
       "      <td>Janice Dean currently serves as senior meteoro...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    index                                           sentence\n",
       "0       0  WorldCom bosses' $54m payout  Ten former direc...\n",
       "1       1  Profits slide at India's Dr Reddy  Profits at ...\n",
       "2       2  Liberian economy starts to grow  The Liberian ...\n",
       "3       4  Singer Ian Brown 'in gig arrest'  Former Stone...\n",
       "4       5  Blue beat U2 to top France honour  Irish band ...\n",
       "5       6  Housewives lift Channel 4 ratings  The debut o...\n",
       "6       9  Observers to monitor UK election  Ministers wi...\n",
       "7      10  Lib Dems highlight problem debt  People vulner...\n",
       "8      11  Minister defends hunting ban law  The law bann...\n",
       "9      12  Legendary Dutch boss Michels dies  Legendary D...\n",
       "10     13  Connors boost for British tennis  Former world...\n",
       "11     14  Sociedad set to rescue Mladenovic  Rangers are...\n",
       "12     15  Mobile games come of age  The BBC News website...\n",
       "13     16  PlayStation 3 processor unveiled  The Cell pro...\n",
       "14     17  PC photo printers challenge printed pictures c...\n",
       "15     18  PC photo printers challenge pros  Home printed...\n",
       "16     19     data clear additional 78.0 long-term 43 those)\n",
       "17     20  Janice Dean currently serves as senior meteoro..."
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "textcl.join_sentences_by_label(split_input_texts_df, label_col = 'index')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see, texts with index 3 (Turkish), 7 (Russian) and 8 (Turkish) were removed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Filtering on Jaccard similarity"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Function [`jaccard_sim_filtering()`](https://alinapetukhova.github.io/textcl/docs/preprocessing.html#textcl.preprocessing.jaccard_sim_filtering) is used to filter sentences by [Jaccard similarity](https://en.wikipedia.org/wiki/Jaccard_index). It represents each sentence as an array of tokens and finds the intersection between each pair of arrays / sentences. Using the intersection, the similarity score is calculated; if it's above the specified `threshold`, a sentence will be filtered out."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Num sentences after Jaccard sim filtering: 258\n"
     ]
    }
   ],
   "source": [
    "split_input_texts_df = textcl.jaccard_sim_filtering(split_input_texts_df, threshold=0.8)\n",
    "print(\"Num sentences after Jaccard sim filtering: {}\".format(len(split_input_texts_df)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The number of rows with sentences was reduced from 281 to 258. Join sentences to the initial texts to review the results:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>sentence</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>Profits slide at India's Dr Reddy  Profits at ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>Liberian economy starts to grow  The Liberian ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>Singer Ian Brown 'in gig arrest'  Former Stone...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Blue beat U2 to top France honour  Irish band ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Housewives lift Channel 4 ratings  The debut o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>9</td>\n",
       "      <td>Observers to monitor UK election  Ministers wi...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>10</td>\n",
       "      <td>Lib Dems highlight problem debt  People vulner...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>11</td>\n",
       "      <td>Minister defends hunting ban law  The law bann...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>12</td>\n",
       "      <td>Legendary Dutch boss Michels dies  Legendary D...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>13</td>\n",
       "      <td>Connors boost for British tennis  Former world...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>14</td>\n",
       "      <td>Sociedad set to rescue Mladenovic  Rangers are...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>15</td>\n",
       "      <td>Mobile games come of age  The BBC News website...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>16</td>\n",
       "      <td>PlayStation 3 processor unveiled  The Cell pro...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>18</td>\n",
       "      <td>PC photo printers challenge pros  Home printed...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>19</td>\n",
       "      <td>data clear additional 78.0 long-term 43 those)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>20</td>\n",
       "      <td>Janice Dean currently serves as senior meteoro...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    index                                           sentence\n",
       "0       0  WorldCom bosses' $54m payout  Ten former direc...\n",
       "1       1  Profits slide at India's Dr Reddy  Profits at ...\n",
       "2       2  Liberian economy starts to grow  The Liberian ...\n",
       "3       4  Singer Ian Brown 'in gig arrest'  Former Stone...\n",
       "4       5  Blue beat U2 to top France honour  Irish band ...\n",
       "5       6  Housewives lift Channel 4 ratings  The debut o...\n",
       "6       9  Observers to monitor UK election  Ministers wi...\n",
       "7      10  Lib Dems highlight problem debt  People vulner...\n",
       "8      11  Minister defends hunting ban law  The law bann...\n",
       "9      12  Legendary Dutch boss Michels dies  Legendary D...\n",
       "10     13  Connors boost for British tennis  Former world...\n",
       "11     14  Sociedad set to rescue Mladenovic  Rangers are...\n",
       "12     15  Mobile games come of age  The BBC News website...\n",
       "13     16  PlayStation 3 processor unveiled  The Cell pro...\n",
       "14     18  PC photo printers challenge pros  Home printed...\n",
       "15     19     data clear additional 78.0 long-term 43 those)\n",
       "16     20  Janice Dean currently serves as senior meteoro..."
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "textcl.join_sentences_by_label(split_input_texts_df, label_col = 'index')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Text with $id=17$ was removed as it was a partial duplicate of text with $id=18$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Filtering on perplexity score"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Function [`perplexity_filtering()`](https://alinapetukhova.github.io/textcl/docs/preprocessing.html#textcl.preprocessing.perplexity_filtering) is used to filter sentences by perplexity, i.e., when sentences are linguistically incorrect and/or unconnected with the remaining text. \n",
    "\n",
    "In general, **perplexity** is a measurement of how well a probability distribution or probability model predicts a sample. In the case of the text data, we will be checking the probability of the next word to be in the given sentence. A low perplexity indicates the probability distribution is good at predicting the word.\n",
    "\n",
    "The first step creates contextual tokens to capture latent syntactic-semantic information provided by the [pytorch_pretrained_bert](https://pypi.org/project/pytorch-pretrained-bert/) package with pretrained `openai-gpt` tokenizer and using GPT as a language model with `OpenAIGPTLMHeadModel`. Perplexity is calculated as `exp(loss)` (where **loss** is the language modeling loss of a particular token)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ftfy or spacy is not installed using BERT BasicTokenizer instead of SpaCy & ftfy.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Num sentences after perplexity filtering: 246\n"
     ]
    }
   ],
   "source": [
    "split_input_texts_df = textcl.perplexity_filtering(split_input_texts_df, threshold=1000)\n",
    "print(\"Num sentences after perplexity filtering: {}\".format(len(split_input_texts_df)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The number of rows with sentences was reduced from 258 to the 246. Join sentences to the initial texts to review the results:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>sentence</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>WorldCom bosses' $54m payout  Ten former direc...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>Profits slide at India's Dr Reddy  Profits at ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>Liberian economy starts to grow  The Liberian ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>Singer Ian Brown 'in gig arrest'  Former Stone...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Blue beat U2 to top France honour  Irish band ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Housewives lift Channel 4 ratings  The debut o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>9</td>\n",
       "      <td>Observers to monitor UK election  Ministers wi...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>10</td>\n",
       "      <td>Lib Dems highlight problem debt  People vulner...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>11</td>\n",
       "      <td>Minister defends hunting ban law  The law bann...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>12</td>\n",
       "      <td>Legendary Dutch boss Michels dies  Legendary D...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>13</td>\n",
       "      <td>Connors boost for British tennis  Former world...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>14</td>\n",
       "      <td>Sociedad set to rescue Mladenovic  Rangers are...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>15</td>\n",
       "      <td>Mobile games come of age  The BBC News website...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>16</td>\n",
       "      <td>PlayStation 3 processor unveiled  The Cell pro...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>18</td>\n",
       "      <td>PC photo printers challenge pros  Home printed...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>20</td>\n",
       "      <td>Janice Dean currently serves as senior meteoro...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    index                                           sentence\n",
       "0       0  WorldCom bosses' $54m payout  Ten former direc...\n",
       "1       1  Profits slide at India's Dr Reddy  Profits at ...\n",
       "2       2  Liberian economy starts to grow  The Liberian ...\n",
       "3       4  Singer Ian Brown 'in gig arrest'  Former Stone...\n",
       "4       5  Blue beat U2 to top France honour  Irish band ...\n",
       "5       6  Housewives lift Channel 4 ratings  The debut o...\n",
       "6       9  Observers to monitor UK election  Ministers wi...\n",
       "7      10  Lib Dems highlight problem debt  People vulner...\n",
       "8      11  Minister defends hunting ban law  The law bann...\n",
       "9      12  Legendary Dutch boss Michels dies  Legendary D...\n",
       "10     13  Connors boost for British tennis  Former world...\n",
       "11     14  Sociedad set to rescue Mladenovic  Rangers are...\n",
       "12     15  Mobile games come of age  The BBC News website...\n",
       "13     16  PlayStation 3 processor unveiled  The Cell pro...\n",
       "14     18  PC photo printers challenge pros  Home printed...\n",
       "15     20  Janice Dean currently serves as senior meteoro..."
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "textcl.join_sentences_by_label(split_input_texts_df, label_col = 'index')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Text with $id=19$ was removed because sentence *\"data clear additional 78.0 long-term 43 those)\"* is not linguistically correct."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Outliers filtering"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Text data is uniquely challenging to outlier detection because of its sparsity and high-dimensional nature. In this package we will use Non-Negative Matrix Factorization (NMF) to detect the text topics in an unsupervised fashion, so the model can be trained and be able to detect outliers without labeling of topics. \n",
    "\n",
    "The way it works is that NMF decomposes high-dimensional vectors into a lower-dimensional representation. These lower-dimensional vectors are non-negative, which also means their coefficients are non-negative. With this approach, we can see the fact that NMF is similar to probabilistic latent semantic indexing (pLSI) and latent Dirichlet allocation (LDA) generative models. From the original matrix, $A$, NMF yields two matrices, $W$ and $H$. The former represents the topics detected in the text data set, while the latter contains the weights for those topics. In other words, $A$ is the documents by words matrix, $H$ is the articles by topics matrix and $W$ is the topics by words matrix.\n",
    "\n",
    "The [`outlier_detection()`](https://alinapetukhova.github.io/textcl/docs/outliers_detection.html#textcl.outliers_detection.outlier_detection) function is used to detect outliers in a list of sentences based on the contextual information using unsupervised methods. Text embeddings are created as a bag of words as an input for the implemented algorithms. The main input parameters for this function are the Pandas data frame containing the texts, the method to use for outlier detection ([TONMF](https://arxiv.org/pdf/1701.01325.pdf) by default), and the type of norm (`l2` by default) to normalize the obtained matrix and detecting the unrelated texts.\n",
    "\n",
    "To test this, we'll first join sentences to the text after filtering and selecting the \"tech\" category. This category has a manually inserted outlier ($id=20$) with a person profile instead of text on the subject of \"tech\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>text</th>\n",
       "      <th>topic_name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>168</th>\n",
       "      <td>15</td>\n",
       "      <td>Mobile games come of age  The BBC News website...</td>\n",
       "      <td>tech</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>212</th>\n",
       "      <td>16</td>\n",
       "      <td>PlayStation 3 processor unveiled  The Cell pro...</td>\n",
       "      <td>tech</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>233</th>\n",
       "      <td>18</td>\n",
       "      <td>PC photo printers challenge pros  Home printed...</td>\n",
       "      <td>tech</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>253</th>\n",
       "      <td>20</td>\n",
       "      <td>Janice Dean currently serves as senior meteoro...</td>\n",
       "      <td>tech</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     index                                               text topic_name\n",
       "168     15  Mobile games come of age  The BBC News website...       tech\n",
       "212     16  PlayStation 3 processor unveiled  The Cell pro...       tech\n",
       "233     18  PC photo printers challenge pros  Home printed...       tech\n",
       "253     20  Janice Dean currently serves as senior meteoro...       tech"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "joined_texts = split_input_texts_df[[\"index\", \"text\", \"topic_name\"]].drop_duplicates()\n",
    "joined_texts = joined_texts[joined_texts.topic_name == 'tech']\n",
    "joined_texts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's run the `outlier_detection()` function with the [RPCA](https://github.com/dganguli/robust-pca) algorithm:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[nltk_data] Downloading package stopwords to /home/alina/nltk_data...\n",
      "[nltk_data]   Package stopwords is already up-to-date!\n"
     ]
    }
   ],
   "source": [
    "joined_texts, _ = textcl.outlier_detection(joined_texts, method='rpca', Z_threshold=1.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The contents of `joined_texts` are now as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>text</th>\n",
       "      <th>topic_name</th>\n",
       "      <th>words</th>\n",
       "      <th>Z_score</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>168</th>\n",
       "      <td>15</td>\n",
       "      <td>Mobile games come of age  The BBC News website...</td>\n",
       "      <td>tech</td>\n",
       "      <td>Mobile games come age BBC News website takes l...</td>\n",
       "      <td>0.954468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>212</th>\n",
       "      <td>16</td>\n",
       "      <td>PlayStation 3 processor unveiled  The Cell pro...</td>\n",
       "      <td>tech</td>\n",
       "      <td>PlayStation 3 processor unveiled Cell processo...</td>\n",
       "      <td>0.431154</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>233</th>\n",
       "      <td>18</td>\n",
       "      <td>PC photo printers challenge pros  Home printed...</td>\n",
       "      <td>tech</td>\n",
       "      <td>PC photo printers challenge pros Home printed ...</td>\n",
       "      <td>0.292867</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     index                                               text topic_name  \\\n",
       "168     15  Mobile games come of age  The BBC News website...       tech   \n",
       "212     16  PlayStation 3 processor unveiled  The Cell pro...       tech   \n",
       "233     18  PC photo printers challenge pros  Home printed...       tech   \n",
       "\n",
       "                                                 words   Z_score  \n",
       "168  Mobile games come age BBC News website takes l...  0.954468  \n",
       "212  PlayStation 3 processor unveiled Cell processo...  0.431154  \n",
       "233  PC photo printers challenge pros Home printed ...  0.292867  "
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "joined_texts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Text with $id=20$ was removed because it describes a person profile instead of tech news.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plots for outlier detection"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this section we'll visualize the outliers for the BBC data set obtained with the different algorithms. First load additional libraries required for results visualization:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "from sklearn.feature_extraction.text import CountVectorizer\n",
    "from nltk.corpus import stopwords\n",
    "from sklearn import preprocessing\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import metrics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll use the [NLTK](https://www.nltk.org/) library to filter stop words from the initial dataset. Let's import this library and download the stop words list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[nltk_data] Downloading package stopwords to /home/alina/nltk_data...\n",
      "[nltk_data]   Package stopwords is already up-to-date!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import nltk\n",
    "nltk.download('stopwords')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prepare input data from the BBC dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To demonstrate how the package handles outlier detection tasks, we present a simplified example from a real world data set to show how skewed the typical values of the corresponding column $z(x)$ may be in real scenarios. To build plots for the outlier detection functions we'll need to load the [full BBC dataset](http://mlg.ucd.ie/files/datasets/bbc-fulltext.zip) and apply initial basic text cleaning:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1872 entries, 0 to 1871\n",
      "Columns: 2 entries, class_name to text\n",
      "dtypes: object(2)\n",
      "memory usage: 29.4+ KB\n"
     ]
    }
   ],
   "source": [
    "# Download from http://mlg.ucd.ie/files/datasets/bbc-fulltext.zip and unpack to this folder:\n",
    "dataset_path = \"./datasets/bbc\"\n",
    "\n",
    "bbc_dataset = pd.DataFrame([], columns = ['class_name', 'text'])\n",
    "\n",
    "# Create a list of topics from the folder names based on the data set initial structure\n",
    "list_topic_folders = os.listdir(\"{}/\".format(dataset_path))\n",
    "\n",
    "# Get documents per each topic from the corresponding folder\n",
    "for topic_folder in list_topic_folders:\n",
    "    \n",
    "    # Skip ReadMe.txt file\n",
    "    if \"txt\" not in topic_folder.lower():\n",
    "        list_of_files = os.listdir(\"{}/{}\".format(dataset_path, topic_folder))\n",
    "        \n",
    "        # add to the Pandas data frame each text document in the folder\n",
    "        for file in list_of_files:\n",
    "            if file.find(\".txt\") != -1 and file.find(\"ipynb\") == -1:\n",
    "                with open(\"{}/{}/{}\".format(dataset_path, topic_folder, file), 'rb') as f:\n",
    "                    text = f.read()\n",
    "                text = text.decode('windows-1252').replace('\\n', ' ')\n",
    "                bbc_dataset = bbc_dataset.append(pd.DataFrame([[topic_folder, text]], columns = ['class_name', 'text']))\n",
    "\n",
    "# reset index in the final data frame to get identifier column for each document\n",
    "bbc_dataset = bbc_dataset.reset_index(drop=True)\n",
    "bbc_dataset.info(verbose=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Data set contains 2225 texts from the following categories:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "entertainment\n",
      "politics\n",
      "business\n",
      "sport\n",
      "tech\n"
     ]
    }
   ],
   "source": [
    "for cat in bbc_dataset['class_name'].unique():\n",
    "    print(cat)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get data for \"business\" and \"politics\" classes to form the core of the data set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "bus_and_pol = bbc_dataset[(bbc_dataset['class_name'] == \"business\") | (bbc_dataset['class_name'] == \"politics\")]\n",
    "df_bus_and_pol_texts = pd.DataFrame(list(bus_and_pol.text.values), columns=['text'])\n",
    "df_bus_and_pol_texts['y_true'] = 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get 50 random outliers documents from \"tech\" class:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "text_for_outliers = bbc_dataset[bbc_dataset['class_name'] == \"tech\"]\n",
    "\n",
    "text_for_outliers = text_for_outliers.iloc[random.sample(range(0, len(text_for_outliers)), 50)]\n",
    "df_outliers = pd.DataFrame(list(text_for_outliers.text.values), columns=['text'])\n",
    "df_outliers['y_true'] = 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Add outliers documents to the core data set and shuffle:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>text</th>\n",
       "      <th>y_true</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Security scares spark browser fix Microsoft wo...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Nigeria boost cocoa production The government ...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Businesses fail plan HIV Companies fail draw p...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Profile: David Blunkett Before resigned positi...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Tories unveil quango blitz plans Plans abolish...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>972</th>\n",
       "      <td>Winter freeze keeps oil $50 Oil prices carried...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>973</th>\n",
       "      <td>Commons hunt protest charges Eight protesters ...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>974</th>\n",
       "      <td>S Korea spending boost economy South Korea boo...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>975</th>\n",
       "      <td>'Super union' merger plan touted Two Britain's...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>976</th>\n",
       "      <td>More reforms ahead says Milburn Labour continu...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>977 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                  text  y_true\n",
       "0    Security scares spark browser fix Microsoft wo...       1\n",
       "1    Nigeria boost cocoa production The government ...       0\n",
       "2    Businesses fail plan HIV Companies fail draw p...       0\n",
       "3    Profile: David Blunkett Before resigned positi...       0\n",
       "4    Tories unveil quango blitz plans Plans abolish...       0\n",
       "..                                                 ...     ...\n",
       "972  Winter freeze keeps oil $50 Oil prices carried...       0\n",
       "973  Commons hunt protest charges Eight protesters ...       0\n",
       "974  S Korea spending boost economy South Korea boo...       0\n",
       "975  'Super union' merger plan touted Two Britain's...       0\n",
       "976  More reforms ahead says Milburn Labour continu...       0\n",
       "\n",
       "[977 rows x 2 columns]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_test = pd.concat([df_bus_and_pol_texts, df_outliers])\n",
    "df_test = df_test.sample(frac=1, random_state=seed).reset_index(drop=True)\n",
    "\n",
    "stop = stopwords.words('english')\n",
    "\n",
    "df_test['text'] = df_test['text'].apply(lambda x: ' '.join([word for word in x.split() if word not in (stop)]))\n",
    "df_test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Convert texts to a bag of words using sklearn's [`CountVectorizer`](https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html) class:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "vectorizer = CountVectorizer()\n",
    "bag_of_words = vectorizer.fit_transform(df_test['text']).todense()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that `CountVectorizer` is used as an example. We could have used another tokenizer or word embedding.\n",
    "\n",
    "In the following subsections we'll plot the outlier detection results using the three methods included with TextCL, namely [TONMF](https://arxiv.org/pdf/1701.01325.pdf), [RPCA](https://github.com/dganguli/robust-pca), and [SVD](https://api.semanticscholar.org/CorpusID:123532178)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### TONMF"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The [`tonmf()`](https://alinapetukhova.github.io/textcl/docs/outliers_detection.html#textcl.outliers_detection.tonmf) function uses the TONMF algorithm to obtain the outlier matrix. The solution is based on the non-negative matrix factorization with the extension of the block coordinate descent framework."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "outlier_matrix,_,_,_ = textcl.tonmf(bag_of_words, k=10, alpha=10, beta=0.05)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Normalize with l2-normalization:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "_, y_pred = preprocessing.normalize(outlier_matrix, axis = 1, norm = 'l2', return_norm = True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use ROC curve to plot the results of the algorithm:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'BBC dataset TONMF ROC-curve. K=3, alpha = 1, beta = 0.5')"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "f = plt.figure(figsize=(10, 8))\n",
    "fpr, tpr, thresholds = metrics.roc_curve(list(df_test['y_true'].values), y_pred, pos_label=1)\n",
    "plt.plot(fpr, tpr, label='ROC curve')\n",
    "plt.plot([0, 1], [0, 1])\n",
    "plt.xlabel('False Positive Rate')\n",
    "plt.ylabel('True Positive Rate')\n",
    "# f.savefig(\"BBC dataset TONMF ROC-curve. K=3, alpha = 1, beta = 0.5.pdf\", bbox_inches='tight')\n",
    "plt.title('BBC dataset TONMF ROC-curve. K=3, alpha = 1, beta = 0.5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Display ℓ2 norm of columns of $Z$ outlier matrix:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'Results of TONMF+L2 (outliers - red, non-outliers - blue)')"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "colors_array = np.array(list(df_test['y_true'].values)).astype('str')\n",
    "colors_array[colors_array == '1'] = 'r'\n",
    "colors_array[colors_array != 'r'] = 'b'\n",
    "\n",
    "f = plt.figure(figsize=(20, 6))\n",
    "index = range(0, len(y_pred))\n",
    "plt.bar(index, y_pred, color = colors_array)\n",
    "# f.savefig(\"Results of TONMF+L2 (outliers - red, non-outliers - blue).pdf\", bbox_inches='tight')\n",
    "plt.title(\"Results of TONMF+L2 (outliers - red, non-outliers - blue)\", size = 20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## RPCA"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The function [`rpca_implementation()`](https://alinapetukhova.github.io/textcl/docs/outliers_detection.html#textcl.outliers_detection.rpca_implementation) uses Robust Principal Component Analysis (RPCA) to obtain the outlier matrix. RPCA uses low-rank approximation and yields two matrices: low-rank matrix $L$ and a sparse matrix $S$. After normalization, the $S$ matrix represents the outlier score for the document."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "outlier_matrix = textcl.rpca_implementation(bag_of_words)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Normalize with l2-normalization:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'BBC dataset RPCA ROC-curve')"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "_, y_pred = preprocessing.normalize(outlier_matrix, axis = 1, norm = 'l2', return_norm = True)\n",
    "\n",
    "f = plt.figure(figsize=(10, 8))\n",
    "fpr, tpr, thresholds = metrics.roc_curve(list(df_test['y_true'].values), y_pred, pos_label=1)\n",
    "plt.plot(fpr, tpr, label='ROC curve')\n",
    "plt.plot([0, 1], [0, 1])\n",
    "plt.xlabel('False Positive Rate')\n",
    "plt.ylabel('True Positive Rate')\n",
    "# f.savefig(\"BBC dataset RPCA ROC-curve.pdf\", bbox_inches='tight')\n",
    "plt.title('BBC dataset RPCA ROC-curve')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Display ℓ2 norm of columns of Z outlier matrix:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'Results of RPCA+L2 (outliers - red, non-outliers - blue)')"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "colors_array = np.array(list(df_test['y_true'].values)).astype('str')\n",
    "colors_array[colors_array == '1'] = 'r'\n",
    "colors_array[colors_array != 'r'] = 'b'\n",
    "\n",
    "f = plt.figure(figsize=(20, 6))\n",
    "plt.ylim(0.001, 0.00175)\n",
    "index = range(0, len(y_pred))\n",
    "plt.bar(index, y_pred, color = colors_array)\n",
    "# f.savefig(\"Results of RPCA+L2 (outliers - red, non-outliers - blue).pdf\", bbox_inches='tight')\n",
    "plt.title(\"Results of RPCA+L2 (outliers - red, non-outliers - blue)\", size = 20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## SVD"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The function [`svd()`](https://alinapetukhova.github.io/textcl/docs/outliers_detection.html#textcl.outliers_detection.svd) uses singular value decomposition (SVD) to obtain the outlier matrix. SVD is performed with the `np.linalg` function from the **numpy** package. The outlier matrix is presented as the multiplication of square root of diagonal elements of the rectangular diagonal matrix $S$ and complex unitary matrix."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "outlier_matrix = textcl.svd(bag_of_words)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Normalize with l2-normalization:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/alina/.local/lib/python3.8/site-packages/sklearn/utils/validation.py:585: FutureWarning: np.matrix usage is deprecated in 1.0 and will raise a TypeError in 1.2. Please convert to a numpy array with np.asarray. For more information see: https://numpy.org/doc/stable/reference/generated/numpy.matrix.html\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'BBC dataset SVD ROC-curve')"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "_, y_pred = preprocessing.normalize(outlier_matrix, axis = 1, norm = 'l2', return_norm = True)\n",
    "\n",
    "f = plt.figure(figsize=(10, 8))\n",
    "fpr, tpr, thresholds = metrics.roc_curve(list(df_test['y_true'].values), y_pred, pos_label=1)\n",
    "plt.plot(fpr, tpr, label='ROC curve')\n",
    "plt.plot([0, 1], [0, 1])\n",
    "plt.xlabel('False Positive Rate')\n",
    "plt.ylabel('True Positive Rate')\n",
    "plt.title('BBC dataset SVD ROC-curve')\n",
    "# f.savefig(\"BBC dataset SVD ROC-curve.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Display ℓ2 norm of columns of Z outlier matrix:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'Results of SVD+L2 (outliers - red, non-outliers - blue)')"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "colors_array = np.array(list(df_test['y_true'].values)).astype('str')\n",
    "colors_array[colors_array == '1'] = 'r'\n",
    "colors_array[colors_array != 'r'] = 'b'\n",
    "\n",
    "f = plt.figure(figsize=(20, 6))\n",
    "# plt.ylim(0.001, 0.00175)\n",
    "index = range(0, len(y_pred))\n",
    "plt.bar(index, y_pred, color = colors_array)\n",
    "# f.savefig(\"Results of SVD+L2 (outliers - red, non-outliers - blue).pdf\", bbox_inches='tight')\n",
    "plt.title(\"Results of SVD+L2 (outliers - red, non-outliers - blue)\", size = 20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ROC-curve plot was used for the evaluation of the algorithm results. By analyzing obtained plots in these 3 examples we can see that with the current parameters for the BBC data set the **RPCA** method is offering the best results. In the plot \"Results of RPCA+L2 (outliers - red, non-outliers - blue)\" we can see the abnormal texts have higher values of the ℓ2 norm and can be segmented from the main distribution. AUC here represents the degree of separability between the main text group and outlied texts, the higher the AUC, the better the model is at distinguishing between different types of texts in the dataset."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  },
  "metadata": {
   "interpreter": {
    "hash": "ef6fb3f656d4ea79ca9f8b9c23b276d8478a1b3139acf0a655e7d2ebf2ef5905"
   }
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "metadata": {
     "collapsed": false
    },
    "source": []
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}