Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sujitpal/0c5547ae7464eaacf1f09ed711adf693 to your computer and use it in GitHub Desktop.
Save sujitpal/0c5547ae7464eaacf1f09ed711adf693 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## BoW and SIF (w/GloVe) comparison\n",
"\n",
"The paper [A SIMPLE BUT TOUGH-TO-BEAT BASELINE FOR SENTENCE EMBEDDINGS](https://openreview.net/pdf?id=SyK00v5xx) by Arora, Liang and Ma, introduces a simple unsupervised embedding scheme (Smooth Inverse Frequency, or SIF) which appears to work better than bag of word vectors on several tasks evaluated in the paper. Abstract of article follows:\n",
"\n",
"> The success of neural network methods for computing word embeddings has motivated methods for generating semantic embeddings of longer pieces of text, such as sentences and paragraphs. Surprisingly, Wieting et al (ICLR’16) showed that such complicated methods are outperformed, especially in out-of-domain (transfer learning) settings, by simpler methods involving mild retraining of word embeddings and basic linear regression. The method of Wieting et al. requires retraining with a substantial labeled dataset such as Paraphrase Database (Ganitkevitch et al., 2013). \n",
">\n",
"> The current paper goes further, showing that the following completely unsupervised sentence embedding is a formidable baseline: Use word embeddings computed using one of the popular methods on unlabeled corpus like Wikipedia, represent the sentence by a weighted average of the word vectors, and then modify them a bit using PCA/SVD. This weighting improves performance by about 10% to 30% in textual similarity tasks, and beats sophisticated supervised methods including RNN’s and LSTM’s. It even improves Wieting et al.’s embeddings. This simple method should be used as the baseline to beat in future, especially when labeled training data is scarce or nonexistent. \n",
"> \n",
"> The paper also gives a theoretical explanation of the success of the above unsupervised method using a latent variable generative model for sentences, which is a simple extension of the model in Arora et al. (TACL’16) with new “smoothing” terms that allow for words occurring out of context, as well as high probabilities for words like and, not in all contex\n",
"\n",
"An implementation of the paper using Python, Scikit-Learn, Theano and Lasagne is available on the [YingyuLiang/SIF](https://github.com/YingyuLiang/SIF) github repository.\n",
"\n",
"Here, we apply the SIF embedding to generate embeddings from text for a binary classification task, and compare it with BoW embeddings. Our observation is that the SIF embedding does not perform significantly any differently from BoW embedding."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from __future__ import division, print_function\n",
"from sklearn.decomposition import TruncatedSVD\n",
"from sklearn.feature_extraction.text import CountVectorizer\n",
"from sklearn.metrics import accuracy_score, confusion_matrix, classification_report\n",
"from sklearn.model_selection import KFold\n",
"import collections\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import operator\n",
"import os\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"DATA_DIR = \"../../data\"\n",
"GLOVE_EMBEDDINGS = os.path.join(DATA_DIR, \"glove.6B.300d.txt\")\n",
"TRAIN_CAPTIONS = os.path.join(DATA_DIR, \"CompoundFigureDetectionTraining2016-Captions.csv\")\n",
"TRAIN_LABELS = os.path.join(DATA_DIR, \"CompoundFigureDetectionTraining2016-GT.csv\")\n",
"TEST_CAPTIONS = os.path.join(DATA_DIR, \"CompoundFigureDetectionTest2016-Captions.csv\")\n",
"TEST_LABELS = os.path.join(DATA_DIR, \"CompoundFigureDetectionTest2016GT.csv\")\n",
"LABEL2ID = {\"COMP\": 0, \"NOCOMP\": 1}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Parse Text"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"21000 21000 3456 3456\n"
]
}
],
"source": [
"def parse_caption_and_label(caption_file, label_file, sep=\" \"):\n",
" filename2label = {}\n",
" flabel = open(label_file, \"rb\")\n",
" for line in flabel:\n",
" filename, label = line.strip().split(sep)\n",
" filename2label[filename] = LABEL2ID[label]\n",
" flabel.close()\n",
" fcaption = open(caption_file, \"rb\")\n",
" captions, labels = [], []\n",
" for line in fcaption:\n",
" filename, caption = line.strip().split(\"\\t\")\n",
" captions.append(caption)\n",
" labels.append(filename2label[filename])\n",
" fcaption.close()\n",
" return captions, labels\n",
"\n",
"captions_train, labels_train = parse_caption_and_label(\n",
" TRAIN_CAPTIONS, TRAIN_LABELS, \",\")\n",
"captions_test, labels_test = parse_caption_and_label(\n",
" TEST_CAPTIONS, TEST_LABELS, \" \")\n",
"print(len(captions_train), len(labels_train), len(captions_test), \n",
" len(labels_test))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Estimate vocabulary size"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(24456, 64170)\n"
]
}
],
"source": [
"counter = CountVectorizer(strip_accents=unicode, \n",
" stop_words=\"english\")\n",
"caption_texts = captions_train + captions_test\n",
"X = counter.fit_transform(caption_texts)\n",
"print(X.shape)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.text.Text at 0x11421a850>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\nk4qZmRXm/wMLSzidBjReGAAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x112fb1390>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"counts = np.sum(X, axis=0).tolist()\n",
"counts = sorted(counts[0], reverse=True)\n",
"plt.plot(np.arange(len(counts)), counts)\n",
"plt.title(\"word count distribution in corpus\")\n",
"plt.ylabel(\"counts\")\n",
"plt.xlabel(\"words\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Compute Baseline Embedding (BoW)\n",
"\n",
"<a href=\"https://www.codecogs.com/eqnedit.php?latex=v_s&space;=&space;\\frac{1}{\\left&space;\\|&space;S&space;\\right&space;\\|}&space;\\sum_{w&space;\\in&space;S}&space;v_w\" target=\"_blank\"><img src=\"https://latex.codecogs.com/gif.latex?v_s&space;=&space;\\frac{1}{\\left&space;\\|&space;S&space;\\right&space;\\|}&space;\\sum_{w&space;\\in&space;S}&space;v_w\" title=\"v_s = \\frac{1}{\\left \\| S \\right \\|} \\sum_{w \\in S} v_w\" /></a>"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(24456, 10000)\n"
]
}
],
"source": [
"VOCAB_SIZE = 10000\n",
"# VOCAB_SIZE = X.shape[1]\n",
"counter = CountVectorizer(strip_accents=unicode, \n",
" stop_words=\"english\",\n",
" max_features=VOCAB_SIZE)\n",
"caption_texts = captions_train + captions_test\n",
"Xc = counter.fit_transform(caption_texts).todense().astype(\"float\")\n",
"print(Xc.shape)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(24456, 1)\n"
]
}
],
"source": [
"sent_lens = np.sum(Xc, axis=1).astype(\"float\")\n",
"sent_lens[sent_lens == 0] = 1e-14\n",
"print(sent_lens.shape)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(10000, 300)\n"
]
}
],
"source": [
"E = np.zeros((VOCAB_SIZE, 300))\n",
"fglove = open(GLOVE_EMBEDDINGS, \"rb\")\n",
"for line in fglove:\n",
" cols = line.strip().split(\" \")\n",
" word = cols[0]\n",
" try:\n",
" i = counter.vocabulary_[word]\n",
" E[i] = np.array([float(x) for x in cols[1:]])\n",
" except KeyError:\n",
" pass\n",
"fglove.close()\n",
"print(E.shape)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(24456, 300)\n"
]
}
],
"source": [
"Xb = np.divide(np.dot(Xc, E), sent_lens)\n",
"print(Xb.shape)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(21000, 300) (21000,) (3456, 300) (3456,)\n"
]
}
],
"source": [
"Xtrain, Xtest = Xb[0:len(captions_train)], Xb[-len(captions_test):]\n",
"ytrain, ytest = np.array(labels_train), np.array(labels_test)\n",
"print(Xtrain.shape, ytrain.shape, Xtest.shape, ytest.shape)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def cross_val(Xtrain, ytrain, clf):\n",
" best_clf = None\n",
" best_score = 0.0\n",
" num_folds = 0\n",
" cv_scores = []\n",
" kfold = KFold(n_splits=10)\n",
" for train, val in kfold.split(Xtrain):\n",
" Xctrain, Xctest, yctrain, yctest = Xtrain[train], Xtrain[val], ytrain[train], ytrain[val]\n",
" clf.fit(Xctrain, yctrain)\n",
" score = clf.score(Xctest, yctest)\n",
" if score > best_score:\n",
" best_score = score\n",
" best_clf = clf\n",
" print(\"fold {:d}, score: {:.3f}\".format(num_folds, score))\n",
" cv_scores.append(score)\n",
" num_folds += 1\n",
" return best_clf, cv_scores\n",
"\n",
"def test_eval(Xtest, ytest, clf):\n",
" print(\"===\")\n",
" print(\"Test set results\")\n",
" ytest_ = clf.predict(Xtest)\n",
" accuracy = accuracy_score(ytest, ytest_)\n",
" print(\"Accuracy: {:.3f}\".format(accuracy))\n",
" print(\"---\")\n",
" print(\"Confusion Matrix\")\n",
" cm = confusion_matrix(ytest, ytest_)\n",
" print(cm)\n",
" print(\"---\")\n",
" print(\"Classification Report\")\n",
" cr = classification_report(ytest, ytest_)\n",
" print(cr)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fold 0, score: 0.909\n",
"fold 1, score: 0.951\n",
"fold 2, score: 0.861\n",
"fold 3, score: 0.794\n",
"fold 4, score: 0.833\n",
"fold 5, score: 0.719\n",
"fold 6, score: 0.361\n",
"fold 7, score: 0.686\n",
"fold 8, score: 0.707\n",
"fold 9, score: 0.752\n",
"===\n",
"Test set results\n",
"Accuracy: 0.781\n",
"---\n",
"Confusion Matrix\n",
"[[1500 306]\n",
" [ 450 1200]]\n",
"---\n",
"Classification Report\n",
" precision recall f1-score support\n",
"\n",
" 0 0.77 0.83 0.80 1806\n",
" 1 0.80 0.73 0.76 1650\n",
"\n",
"avg / total 0.78 0.78 0.78 3456\n",
"\n"
]
}
],
"source": [
"from sklearn.naive_bayes import GaussianNB\n",
"\n",
"clf = GaussianNB()\n",
"best_clf, scores_nb = cross_val(Xtrain, ytrain, clf)\n",
"test_eval(Xtest, ytest, best_clf)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fold 0, score: 0.843\n",
"fold 1, score: 0.891\n",
"fold 2, score: 0.842\n",
"fold 3, score: 0.765\n",
"fold 4, score: 0.768\n",
"fold 5, score: 0.655\n",
"fold 6, score: 0.278\n",
"fold 7, score: 0.511\n",
"fold 8, score: 0.546\n",
"fold 9, score: 0.560\n",
"===\n",
"Test set results\n",
"Accuracy: 0.727\n",
"---\n",
"Confusion Matrix\n",
"[[1635 171]\n",
" [ 771 879]]\n",
"---\n",
"Classification Report\n",
" precision recall f1-score support\n",
"\n",
" 0 0.68 0.91 0.78 1806\n",
" 1 0.84 0.53 0.65 1650\n",
"\n",
"avg / total 0.75 0.73 0.72 3456\n",
"\n"
]
}
],
"source": [
"from sklearn.svm import LinearSVC\n",
"\n",
"clf = LinearSVC()\n",
"best_clf, scores_svc = cross_val(Xtrain, ytrain, clf)\n",
"test_eval(Xtest, ytest, best_clf)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Smooth Inverse Frequency (SIF) Embedding\n",
"\n",
"<a href=\"https://www.codecogs.com/eqnedit.php?latex=v_s&space;=&space;\\frac{1}{\\left&space;\\|&space;S&space;\\right&space;\\|}&space;\\sum_{w&space;\\in&space;S}&space;\\frac{\\alpha}{\\alpha&space;&plus;&space;p_w}&space;v_w\" target=\"_blank\"><img src=\"https://latex.codecogs.com/gif.latex?v_s&space;=&space;\\frac{1}{\\left&space;\\|&space;S&space;\\right&space;\\|}&space;\\sum_{w&space;\\in&space;S}&space;\\frac{\\alpha}{\\alpha&space;&plus;&space;p_w}&space;v_w\" title=\"v_s = \\frac{1}{\\left \\| S \\right \\|} \\sum_{w \\in S} \\frac{\\alpha}{\\alpha + p_w} v_w\" /></a>"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# from paper\n",
"ALPHA = 1e-3"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# compute word probabilities from external source\n",
"freqs = np.zeros((1, VOCAB_SIZE), dtype=\"float\")\n",
"WIKIPEDIA_WORD_PROBS = os.path.join(DATA_DIR, \"enwiki_vocab_min200.txt\")\n",
"fprobs = open(WIKIPEDIA_WORD_PROBS, \"rb\")\n",
"for ix, line in enumerate(fprobs):\n",
" word, count = line.strip().split(\" \")\n",
" if counter.vocabulary_.has_key(word):\n",
" idx = counter.vocabulary_[word]\n",
" freqs[0, idx] = count\n",
"fprobs.close()\n",
"probs = freqs / np.sum(freqs)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# # compute word probabilities from corpus\n",
"# freqs = np.sum(Xc, axis=0).astype(\"float\")\n",
"# probs = freqs / np.sum(freqs)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# compute multiplier ALPHA / (ALPHA + probs)\n",
"coeff = ALPHA / (ALPHA + probs)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# compute weighted counts\n",
"Xw = np.multiply(Xc, coeff)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(24456, 10000) (1, 10000) (24456, 300) (10000, 300)\n"
]
}
],
"source": [
"# convert to SIF embeddings\n",
"Xs = np.divide(np.dot(Xw, E), sent_lens)\n",
"\n",
"print(Xc.shape, coeff.shape, Xs.shape, E.shape)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(1, 300) [ 0.02595112]\n"
]
}
],
"source": [
"# compute 1st principal component\n",
"svd = TruncatedSVD(n_components=1, n_iter=20, random_state=0)\n",
"svd.fit(Xs)\n",
"pc = svd.components_\n",
"print(pc.shape, svd.explained_variance_ratio_)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(24456, 300)\n"
]
}
],
"source": [
"# remove it from the weighted counts\n",
"Xr = Xs - Xs.dot(pc.T).dot(pc)\n",
"print(Xr.shape)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(21000, 300) (21000,) (3456, 300) (3456,)\n"
]
}
],
"source": [
"Xtrain, Xtest = Xr[0:len(captions_train)], Xr[-len(captions_test):]\n",
"ytrain, ytest = np.array(labels_train), np.array(labels_test)\n",
"print(Xtrain.shape, ytrain.shape, Xtest.shape, ytest.shape)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fold 0, score: 0.917\n",
"fold 1, score: 0.948\n",
"fold 2, score: 0.863\n",
"fold 3, score: 0.796\n",
"fold 4, score: 0.834\n",
"fold 5, score: 0.701\n",
"fold 6, score: 0.336\n",
"fold 7, score: 0.648\n",
"fold 8, score: 0.691\n",
"fold 9, score: 0.753\n",
"===\n",
"Test set results\n",
"Accuracy: 0.772\n",
"---\n",
"Confusion Matrix\n",
"[[1502 304]\n",
" [ 483 1167]]\n",
"---\n",
"Classification Report\n",
" precision recall f1-score support\n",
"\n",
" 0 0.76 0.83 0.79 1806\n",
" 1 0.79 0.71 0.75 1650\n",
"\n",
"avg / total 0.77 0.77 0.77 3456\n",
"\n"
]
}
],
"source": [
"from sklearn.naive_bayes import GaussianNB\n",
"\n",
"clf = GaussianNB()\n",
"best_clf, scores_nb = cross_val(Xtrain, ytrain, clf)\n",
"test_eval(Xtest, ytest, best_clf)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fold 0, score: 0.847\n",
"fold 1, score: 0.883\n",
"fold 2, score: 0.841\n",
"fold 3, score: 0.762\n",
"fold 4, score: 0.765\n",
"fold 5, score: 0.655\n",
"fold 6, score: 0.274\n",
"fold 7, score: 0.509\n",
"fold 8, score: 0.550\n",
"fold 9, score: 0.556\n",
"===\n",
"Test set results\n",
"Accuracy: 0.727\n",
"---\n",
"Confusion Matrix\n",
"[[1628 178]\n",
" [ 767 883]]\n",
"---\n",
"Classification Report\n",
" precision recall f1-score support\n",
"\n",
" 0 0.68 0.90 0.78 1806\n",
" 1 0.83 0.54 0.65 1650\n",
"\n",
"avg / total 0.75 0.73 0.72 3456\n",
"\n"
]
}
],
"source": [
"from sklearn.svm import LinearSVC\n",
"\n",
"clf = LinearSVC()\n",
"best_clf, scores_svc = cross_val(Xtrain, ytrain, clf)\n",
"test_eval(Xtest, ytest, best_clf)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## Results\n",
"\n",
"Above code was run for different values of VOCABULARY_SIZE, smoothed with implicit word probabilities (same corpus) and with external word probabilities from Wikipedia. Results are shown below for Naive Bayes and Support Vector Machine binary classifiers."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nfV+LY/EjhnXZTQjnrpgXwjmGddntG4E8QbdumvA0cSJ07+41RTFsGISEXDkvJMRLlSr27FElHRio\nHszrrvPCQVOgTBn4/HOtJnL77ZrQecMN8PHHWs4oKyECO3bAqFE8+2NrXs8TwdQFxeg2qAhy6jT0\n6AE//ggnTsC4cT78EWQhMmpVZ6XJeo59T2pd5w4cEJkyReSZZ0QqVrz8MBsSoo11hg4VWb5ci/77\nM1FR6hSKb+1ap47mnVhPclJaTGkhof3zSVz+fBrMnY3Aeo4zpYsnPbdcQgP3iSFWQgP3yaTnlqdp\nuyxFXJxIr16qKAYM8NphfdIB9NAhkRtu0GSN337zwgEzwKpV6mUF7bAxZYpXvfrp5vBhlfHJJ69s\nbuMkqb58/zYB7cORhBzSBjYzetjnytIbkzWOfYur5Ni8edUQfuop1Znx8wsUELn7bpE33lBddeGC\nr6XPGNHROrxVpoyeV61amhBojeTLjNs4TohAfi2BthXNRljj2OriNBEXp0oQREaO9LU0nuH4cS0R\nFBIisnKlr6VJmbg49WZUr67fSY0aIj/84B+K+9w5zTrv1euyfKAPHG3a6A3nr78uyRoXp/dY0Ptp\nTsQax1Yh+zUpJccWLqxl0d5+W2T9em3Nnp04f17ks8/UERGva2fO9G+HhLc4cvaIBAwOkEFPlBUp\nWTJbtXu1xrHVxWnm4kWRhx5SBfHpp76Wxr2cPStSt67Gui5Y4Gtp0k5srLYcL1tWv5fGjb1fluji\nRZE1a0SGDdPj584tl+KGmzTR+WvX6nop7KJdO93sk0+8KLufYI1jq5D9lri4y8lziSdjco6RGBMj\nMmGCSPnyeu5VqohMm5aiXssRNPy8oVR/y3lymDDB1+K4DWscW12cLs6fF2neXJXi9Om+lsY9REdr\nTFxAgHoEsiLnz2uc3NVXq45q3Vpk2zbPHCsuTmTHDq3J3KbN5Xqh8V6V3r1Ffvwx3TWhL1wQufde\n/WlNmeIZ0f2VzOhhm5Bn8QhxcTBnDtxyS/K5JmXKZMuW9y4JCtLqTdu3azOi2Fho107bUU+erE2J\nciKtK7bmt6hd/FO7AowcaTMYLTmT3Llh5kytPdmxI8yf72uJMsfFi/DII5qVPG4ctGnja4kyRu7c\nmjz5998wZIgmElapAp07w759md9/ZKS2Zu3cGcqWhQoV4PnntQPdAw9obbYjR7QN9ogR2gYvcTJd\n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\n/QAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x113a08190>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"xlabels = [\"10k\", \"20k\", \"30k\", \"40k\", \"50k\", \"all\", \"all+stop\"]\n",
"# xs = [10000, 20000, 30000, 40000, 50000, 64170, 64450]\n",
"# we have changed the actual numbers to evenly space the points\n",
"xs = [10000, 20000, 30000, 40000, 50000, 60000, 70000]\n",
"\n",
"ylabels = [\"BoW/NB\", \"BoW/SVM\", \"SIF/NB\", \"SIF/SVM\", \n",
" \"SIF+EP/NB\", \"SIF+EP/SVM\"]\n",
"ys = np.array(\n",
" [[0.782, 0.784, 0.784, 0.785, 0.784, 0.782, 0.773],\n",
" [0.727, 0.728, 0.724, 0.728, 0.726, 0.727, 0.728],\n",
" [0.782, 0.787, 0.786, 0.786, 0.784, 0.782, 0.769],\n",
" [0.712, 0.710, 0.710, 0.711, 0.709, 0.712, 0.714],\n",
" [0.772, 0.779, 0.781, 0.782, 0.780, 0.777, 0.762],\n",
" [0.727, 0.729, 0.727, 0.732, 0.730, 0.726, 0.723]])\n",
"ids_nb = [i for i, y in enumerate(ylabels) if y.endswith(\"/NB\")]\n",
"labels_nb = [y.split(\"/\")[0] for y in ylabels if y.endswith(\"/NB\")]\n",
"ids_svm = [i for i, y in enumerate(ylabels) if y.endswith(\"/SVM\")]\n",
"labels_svm = [y.split(\"/\")[0] for y in ylabels if y.endswith(\"/SVM\")]\n",
"colors = [\"r\", \"g\", \"b\"]\n",
"\n",
"plt.figure(figsize=(10, 5))\n",
"\n",
"plt.subplot(121)\n",
"curr_row = 0\n",
"for row in ids_nb:\n",
" plt.plot(xs, ys[row, :], marker=\"o\", \n",
" color=colors[curr_row], label=labels_nb[curr_row])\n",
" curr_row += 1\n",
"plt.xticks(xs, xlabels)\n",
"plt.title(\"Naive Bayes\")\n",
"plt.ylabel(\"classification accuracy\")\n",
"plt.xlabel(\"vocab size\")\n",
"plt.legend(loc=\"best\")\n",
"\n",
"plt.subplot(122)\n",
"curr_row = 0\n",
"for row in ids_svm:\n",
" plt.plot(xs, ys[row, :], marker=\"o\", \n",
" color=colors[curr_row], label=labels_svm[curr_row])\n",
" curr_row += 1\n",
"plt.xticks(xs, xlabels)\n",
"plt.title(\"Support Vector Machine\")\n",
"plt.ylabel(\"classification accuracy\")\n",
"plt.xlabel(\"vocab size\")\n",
"plt.legend(loc=\"best\")\n",
"\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
@prakhar21
Copy link

Hi, nice implementation. But, I have a doubt, the cell corresponding to In[15], where you are calculating the word probabilities from external corpus. Should we not calculate the word probabilities from the existing vocabulary itself ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment