{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# New Term Topics Methods and Document Coloring" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "from gensim.corpora import Dictionary\n", "from gensim.models import ldamodel\n", "import numpy\n", "%matplotlib inline\n", "\n", "import logging\n", "logging.basicConfig(level=logging.INFO)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We're setting up our corpus now. We want to show off the new `get_term_topics` and `get_document_topics` functionalities, and a good way to do so is to play around with words which might have different meanings in different context.\n", "\n", "The word `bank` is a good candidate here, where it can mean either the financial institution or a river bank.\n", "In the toy corpus presented, there are 11 documents, 5 `river` related and 6 `finance` related. " ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "import gensim.downloader\n", "corpus = gensim.downloader.load(\"20-newsgroups\")" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:smart_open.smart_open_lib:this function is deprecated, use smart_open.open instead\n" ] } ], "source": [ "import collections\n", "from gensim.parsing.preprocessing import preprocess_string\n", "\n", "texts = [\n", " preprocess_string(text['data'])\n", " for text in corpus\n", " if text['topic'] in ('soc.religion.christian', 'talk.politics.guns')\n", "]" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:gensim.corpora.dictionary:adding document #0 to Dictionary(0 unique tokens: [])\n", "INFO:gensim.corpora.dictionary:built Dictionary(17455 unique tokens: ['accept', 'action', 'adulter', 'adulteri', 'adventur']...) from 1907 documents (total 318505 corpus positions)\n", "INFO:gensim.corpora.dictionary:discarding 14137 tokens: [('accept', 259), ('adventur', 6), ('annia', 3), ('believ', 649), ('bibl', 280), ('calvinist', 5), ('cannanit', 4), ('case', 317), ('chastis', 4), ('christian', 527)]...\n", "INFO:gensim.corpora.dictionary:keeping 3318 tokens which were in no less than 10 and no more than 190 (=10.0%) documents\n", "INFO:gensim.corpora.dictionary:resulting dictionary: Dictionary(3318 unique tokens: ['action', 'adulter', 'adulteri', 'affect', 'andi']...)\n" ] } ], "source": [ "dictionary = Dictionary(texts)\n", "dictionary.filter_extremes(no_above=0.1, no_below=10)\n", "corpus = [dictionary.doc2bow(text) for text in texts]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We set up the LDA model in the corpus. We set the number of topics to be 2, and expect to see one which is to do with river banks, and one to do with financial banks. " ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:gensim.models.ldamodel:using asymmetric alpha [0.63060194, 0.36939806]\n", "INFO:gensim.models.ldamodel:using symmetric eta at 0.5\n", "INFO:gensim.models.ldamodel:using serial LDA version on this node\n", "INFO:gensim.models.ldamodel:running online (single-pass) LDA training, 2 topics, 1 passes over the supplied corpus of 1907 documents, updating model once every 1907 documents, evaluating perplexity every 1907 documents, iterating 50x with a convergence threshold of 0.001000\n", "WARNING:gensim.models.ldamodel:too few updates, training might not converge; consider increasing the number of passes or iterations to improve accuracy\n", "INFO:gensim.models.ldamodel:-8.511 per-word bound, 364.7 perplexity estimate based on a held-out corpus of 1907 documents with 180557 words\n", "INFO:gensim.models.ldamodel:PROGRESS: pass 0, at document #1907/1907\n", "INFO:gensim.models.ldamodel:topic #0 (0.631): 0.004*\"homosexu\" + 0.004*\"hell\" + 0.003*\"paul\" + 0.002*\"firearm\" + 0.002*\"batf\" + 0.002*\"cathol\" + 0.002*\"natur\" + 0.002*\"crime\" + 0.002*\"lord\" + 0.002*\"shall\"\n", "INFO:gensim.models.ldamodel:topic #1 (0.369): 0.004*\"firearm\" + 0.004*\"homosexu\" + 0.003*\"file\" + 0.003*\"author\" + 0.003*\"paul\" + 0.003*\"scriptur\" + 0.002*\"stratu\" + 0.002*\"amend\" + 0.002*\"koresh\" + 0.002*\"crimin\"\n", "INFO:gensim.models.ldamodel:topic diff=0.737151, rho=1.000000\n" ] } ], "source": [ "numpy.random.seed(1) # setting random seed to get the same results each time.\n", "model = ldamodel.LdaModel(corpus, id2word=dictionary, num_topics=2, alpha='asymmetric', minimum_probability=1e-8)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0,\n", " '0.004*\"homosexu\" + 0.004*\"hell\" + 0.003*\"paul\" + 0.002*\"firearm\" + 0.002*\"batf\" + 0.002*\"cathol\" + 0.002*\"natur\" + 0.002*\"crime\" + 0.002*\"lord\" + 0.002*\"shall\"'),\n", " (1,\n", " '0.004*\"firearm\" + 0.004*\"homosexu\" + 0.003*\"file\" + 0.003*\"author\" + 0.003*\"paul\" + 0.003*\"scriptur\" + 0.002*\"stratu\" + 0.002*\"amend\" + 0.002*\"koresh\" + 0.002*\"crimin\"')]" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.show_topics()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And like we expected, the LDA model has given us near perfect results. Bank is the most influential word in both the topics, as we can see. The other words help define what kind of bank we are talking about. Let's now see where our new methods fit in." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### get_term_topics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function `get_term_topics` returns the odds of that particular word belonging to a particular topic. \n", "A few examples:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 0.0035053839), (1, 0.0011557308)]" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.get_term_topics('hell')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Makes sense, the value for it belonging to `topic_0` is a lot more." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 0.002482554), (1, 0.0036967357)]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.get_term_topics('firearm')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This also works out well, the word finance is more likely to be in topic_1 to do with financial banks." ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 0.000701838), (1, 0.0006635987)]" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.get_term_topics('car')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And this is particularly interesting. Since the word bank is likely to be in both the topics, the values returned are also very similar." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### get_document_topics and Document Word-Topic Coloring" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`get_document_topics` is an already existing gensim functionality which uses the `inference` function to get the sufficient statistics and figure out the topic distribution of the document.\n", "\n", "The addition to this is the ability for us to now know the topic distribution for each word in the document. \n", "Let us test this with two different documents which have the word bank in it, one in the finance context and one in the river context.\n", "\n", "The `get_document_topics` method returns (along with the standard document topic proprtion) the word_type followed by a list sorted with the most likely topic ids, when `per_word_topics` is set as true." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "bow_water = ['bank','water','bank']\n", "bow_finance = ['bank','finance','bank']" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, [0, 1]), (3, [0, 1])]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bow = model.id2word.doc2bow(bow_water) # convert to bag of words format first\n", "doc_topics, word_topics, phi_values = model.get_document_topics(bow, per_word_topics=True)\n", "\n", "word_topics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now what does that output mean? It means that like `word_type 1`, our `word_type` `3`, which is the word `bank`, is more likely to be in `topic_0` than `topic_1`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You must have noticed that while we unpacked into `doc_topics` and `word_topics`, there is another variable - `phi_values`. Like the name suggests, phi_values contains the phi values for each topic for that particular word, scaled by feature length. Phi is essentially the probability of that word in that document belonging to a particular topic. The next few lines should illustrate this. " ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, [(0, 1.8300905), (1, 0.16990812)]),\n", " (3, [(0, 0.8581231), (1, 0.14187533)])]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phi_values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This means that `word_type` 0 has the following phi_values for each of the topics. \n", "What is intresting to note is `word_type` 3 - because it has 2 occurences (i.e, the word `bank` appears twice in the bow), we can see that the scaling by feature length is very evident. The sum of the phi_values is 2, and not 1." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we know exactly what `get_document_topics` does, let us now do the same with our second document, `bow_finance`." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, [0, 1]), (10, [0, 1])]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bow = model.id2word.doc2bow(bow_finance) # convert to bag of words format first\n", "doc_topics, word_topics, phi_values = model.get_document_topics(bow, per_word_topics=True)\n", "\n", "word_topics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And lo and behold, because the word bank is now used in the financial context, it immedietly swaps to being more likely associated with `topic_1`.\n", "\n", "We've seen quite clearly that based on the context, the most likely topic associated with a word can change. \n", "This differs from our previous method, `get_term_topics`, where it is a 'static' topic distribution. \n", "\n", "It must also be noted that because the gensim implementation of LDA uses Variational Bayes sampling, a `word_type` in a document is only given one topic distribution. For example, the sentence 'the bank by the river bank' is likely to be assigned to `topic_0`, and each of the bank word instances have the same distribution." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### get_document_topics for entire corpus\n", "\n", "You can get `doc_topics`, `word_topics` and `phi_values` for all the documents in the corpus in the following manner :" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "New Document \n", "\n", "Document topics: [(0, 0.73633265), (1, 0.26366737)]\n", "Word topics: [(0, [0, 1]), (1, [0, 1]), (2, [0, 1]), (3, [0, 1])]\n", "Phi values: [(0, [(0, 0.8527051), (1, 0.14729421)]), (1, [(0, 0.795473), (1, 0.20452519)]), (2, [(0, 0.7709577), (1, 0.2290356)]), (3, [(0, 0.76475203), (1, 0.23524645)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.7539386), (1, 0.2460614)]\n", "Word topics: [(1, [0, 1]), (3, [0, 1]), (4, [0, 1]), (5, [0, 1]), (6, [0, 1])]\n", "Phi values: [(1, [(0, 0.80670816), (1, 0.19329017)]), (3, [(0, 0.77720207), (1, 0.22279654)]), (4, [(0, 0.90712374), (1, 0.092870995)]), (5, [(0, 0.7294175), (1, 0.27057865)]), (6, [(0, 0.805549), (1, 0.19444753)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.17039819), (1, 0.82960176)]\n", "Word topics: [(0, [1, 0]), (3, [1, 0]), (5, [1, 0]), (7, [1, 0])]\n", "Phi values: [(0, [(0, 0.15414648), (1, 0.8458525)]), (3, [(0, 0.09283445), (1, 0.90716416)]), (5, [(0, 0.073286586), (1, 0.92671037)]), (7, [(0, 0.031027067), (1, 0.96896887)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.8758601), (1, 0.124139935)]\n", "Word topics: [(0, [0, 1]), (1, [0, 1]), (3, [0, 1]), (8, [0, 1])]\n", "Phi values: [(0, [(0, 1.9142816), (1, 0.085716955)]), (1, [(0, 0.9375137), (1, 0.06248462)]), (3, [(0, 0.92614746), (1, 0.073851064)]), (8, [(0, 0.97765744), (1, 0.022337979)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.1712567), (1, 0.8287433)]\n", "Word topics: [(1, [1, 0]), (3, [1, 0]), (6, [1, 0]), (9, [1, 0])]\n", "Phi values: [(1, [(0, 0.11006477), (1, 0.8899334)]), (3, [(0, 0.09368856), (1, 0.9063102)]), (6, [(0, 0.109341085), (1, 0.8906553)]), (9, [(0, 0.04248068), (1, 0.9575148)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.16402602), (1, 0.8359739)]\n", "Word topics: [(0, [1, 0]), (10, [1, 0]), (11, [1, 0]), (12, [1, 0])]\n", "Phi values: [(0, [(0, 0.14435525), (1, 0.85564375)]), (10, [(0, 0.07960652), (1, 0.92039144)]), (11, [(0, 0.07176139), (1, 0.92823654)]), (12, [(0, 0.023786588), (1, 0.97620964)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.80524194), (1, 0.19475807)]\n", "Word topics: [(0, [0, 1]), (11, [0, 1]), (13, [0, 1])]\n", "Phi values: [(0, [(0, 0.9217699), (1, 0.07822937)]), (11, [(0, 0.84373295), (1, 0.1562643)]), (13, [(0, 0.95610404), (1, 0.043893255)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.65283513), (1, 0.3471648)]\n", "Word topics: [(0, [0, 1]), (10, [0, 1])]\n", "Phi values: [(0, [(0, 0.79454756), (1, 0.20545153)]), (10, [(0, 0.6647264), (1, 0.33527094)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.7917557), (1, 0.20824426)]\n", "Word topics: [(0, [0, 1]), (10, [0, 1]), (11, [0, 1]), (14, [0, 1])]\n", "Phi values: [(0, [(0, 0.9003985), (1, 0.099600814)]), (10, [(0, 0.8225217), (1, 0.17747577)]), (11, [(0, 0.80554056), (1, 0.19445676)]), (14, [(0, 0.9310509), (1, 0.0689471)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.80841804), (1, 0.19158193)]\n", "Word topics: [(13, [0, 1]), (14, [0, 1])]\n", "Phi values: [(13, [(0, 0.9664923), (1, 0.033504896)]), (14, [(0, 0.95886075), (1, 0.041137177)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topics: [(0, 0.84000635), (1, 0.15999362)]\n", "Word topics: [(0, [0, 1]), (14, [0, 1]), (15, [0, 1])]\n", "Phi values: [(0, [(0, 0.94806826), (1, 0.051930968)]), (14, [(0, 0.9646261), (1, 0.035372045)]), (15, [(0, 0.9475713), (1, 0.052422963)])]\n", " \n", "-------------- \n", "\n" ] } ], "source": [ "all_topics = model.get_document_topics(corpus, per_word_topics=True)\n", "\n", "for doc_topics, word_topics, phi_values in all_topics:\n", " print('New Document \\n')\n", " print('Document topics:', doc_topics)\n", " print('Word topics:', word_topics)\n", " print('Phi values:', phi_values)\n", " print(\" \")\n", " print('-------------- \\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In case you want to store `doc_topics`, `word_topics` and `phi_values` for all the documents in the corpus in a variable and later access details of a particular document using its index, it can be done in the following manner:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "topics = model.get_document_topics(corpus, per_word_topics=True)\n", "all_topics = [(doc_topics, word_topics, word_phis) for doc_topics, word_topics, word_phis in topics]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, I can access details of a particular document, say Document #3, as follows: " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Document topic: [(0, 0.84000635), (1, 0.15999362)] \n", "\n", "Word topic: [(0, [1, 0]), (3, [1, 0]), (5, [1, 0]), (7, [1, 0])] \n", "\n", "Phi value: [(0, [(0, 0.1540126), (1, 0.8459863)]), (3, [(0, 0.09274801), (1, 0.90725076)]), (5, [(0, 0.07321687), (1, 0.9267802)]), (7, [(0, 0.030996205), (1, 0.96899974)])]\n" ] } ], "source": [ "doc_topic, word_topics, phi_values = all_topics[2]\n", "print('Document topic:', doc_topics, \"\\n\")\n", "print('Word topic:', word_topics, \"\\n\")\n", "print('Phi value:', phi_values)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can print details for all the documents (as shown above), in the following manner:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "New Document \n", "\n", "Document topic: [(0, 0.7339641), (1, 0.26603588)]\n", "Word topic: [(0, [0, 1]), (1, [0, 1]), (2, [0, 1]), (3, [0, 1])]\n", "Phi value: [(0, [(0, 0.850583), (1, 0.14941624)]), (1, [(0, 0.7927268), (1, 0.20727131)]), (2, [(0, 0.7679785), (1, 0.23201483)]), (3, [(0, 0.76171696), (1, 0.23828152)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.7540561), (1, 0.24594393)]\n", "Word topic: [(1, [0, 1]), (3, [0, 1]), (4, [0, 1]), (5, [0, 1]), (6, [0, 1])]\n", "Phi value: [(1, [(0, 0.8068402), (1, 0.19315805)]), (3, [(0, 0.77734876), (1, 0.2226498)]), (4, [(0, 0.9071951), (1, 0.09279961)]), (5, [(0, 0.7295848), (1, 0.27041143)]), (6, [(0, 0.80568177), (1, 0.1943148)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.17031126), (1, 0.8296888)]\n", "Word topic: [(0, [1, 0]), (3, [1, 0]), (5, [1, 0]), (7, [1, 0])]\n", "Phi value: [(0, [(0, 0.1540126), (1, 0.8459863)]), (3, [(0, 0.09274801), (1, 0.90725076)]), (5, [(0, 0.07321687), (1, 0.9267802)]), (7, [(0, 0.030996205), (1, 0.96899974)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.87583715), (1, 0.12416287)]\n", "Word topic: [(0, [0, 1]), (1, [0, 1]), (3, [0, 1]), (8, [0, 1])]\n", "Phi value: [(0, [(0, 1.9142504), (1, 0.08574835)]), (1, [(0, 0.9374913), (1, 0.062507026)]), (3, [(0, 0.9261214), (1, 0.07387724)]), (8, [(0, 0.97764915), (1, 0.022346335)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.17121859), (1, 0.8287814)]\n", "Word topic: [(1, [1, 0]), (3, [1, 0]), (6, [1, 0]), (9, [1, 0])]\n", "Phi value: [(1, [(0, 0.11002095), (1, 0.8899771)]), (3, [(0, 0.093650565), (1, 0.906348)]), (6, [(0, 0.109297544), (1, 0.8906989)]), (9, [(0, 0.04246249), (1, 0.95753306)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.16401243), (1, 0.83598757)]\n", "Word topic: [(0, [1, 0]), (10, [1, 0]), (11, [1, 0]), (12, [1, 0])]\n", "Phi value: [(0, [(0, 0.14433442), (1, 0.85566455)]), (10, [(0, 0.07959415), (1, 0.92040366)]), (11, [(0, 0.07175015), (1, 0.9282477)]), (12, [(0, 0.023782672), (1, 0.9762135)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.8052399), (1, 0.19476008)]\n", "Word topic: [(0, [0, 1]), (11, [0, 1]), (13, [0, 1])]\n", "Phi value: [(0, [(0, 0.9217683), (1, 0.07823093)]), (11, [(0, 0.84373015), (1, 0.15626718)]), (13, [(0, 0.95610315), (1, 0.043894168)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.6528616), (1, 0.34713835)]\n", "Word topic: [(0, [0, 1]), (10, [0, 1])]\n", "Phi value: [(0, [(0, 0.7945762), (1, 0.20542288)]), (10, [(0, 0.6647654), (1, 0.3352318)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.79167444), (1, 0.20832555)]\n", "Word topic: [(0, [0, 1]), (10, [0, 1]), (11, [0, 1]), (14, [0, 1])]\n", "Phi value: [(0, [(0, 0.9003313), (1, 0.09966788)]), (10, [(0, 0.82241255), (1, 0.17758493)]), (11, [(0, 0.80542344), (1, 0.19457388)]), (14, [(0, 0.931003), (1, 0.06899511)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.8083355), (1, 0.19166456)]\n", "Word topic: [(13, [0, 1]), (14, [0, 1])]\n", "Phi value: [(13, [(0, 0.9664568), (1, 0.033540305)]), (14, [(0, 0.9588177), (1, 0.04118031)])]\n", " \n", "-------------- \n", "\n", "New Document \n", "\n", "Document topic: [(0, 0.8399969), (1, 0.1600031)]\n", "Word topic: [(0, [0, 1]), (14, [0, 1]), (15, [0, 1])]\n", "Phi value: [(0, [(0, 0.9480616), (1, 0.051937718)]), (14, [(0, 0.9646214), (1, 0.03537672)]), (15, [(0, 0.9475646), (1, 0.052429777)])]\n", " \n", "-------------- \n", "\n" ] } ], "source": [ "for doc in all_topics:\n", " print('New Document \\n')\n", " print('Document topic:', doc[0])\n", " print('Word topic:', doc[1])\n", " print('Phi value:', doc[2])\n", " print(\" \")\n", " print('-------------- \\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Coloring topic-terms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These methods can come in handy when we want to color the words in a corpus or a document. If we wish to color the words in a corpus (i.e, color all the words in the dictionary of the corpus), then `get_term_topics` would be a better choice. If not, `get_document_topics` would do the trick." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll now attempt to color these words and plot it using `matplotlib`. \n", "This is just one way to go about plotting words - there are more and better ways.\n", "\n", "[WordCloud](https://github.com/amueller/word_cloud) is such a python package which also does this.\n", "\n", "For our simple illustration, let's keep `topic_1` as red, and `topic_0` as blue." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# this is a sample method to color words. Like mentioned before, there are many ways to do this.\n", "\n", "def color_words(model, doc):\n", " import matplotlib.pyplot as plt\n", " import matplotlib.patches as patches\n", " \n", " # make into bag of words\n", " doc = model.id2word.doc2bow(doc)\n", " # get word_topics\n", " doc_topics, word_topics, phi_values = model.get_document_topics(doc, per_word_topics=True)\n", "\n", " # color-topic matching\n", " topic_colors = { 1:'red', 0:'blue'}\n", " \n", " # set up fig to plot\n", " fig = plt.figure()\n", " ax = fig.add_axes([0,0,1,1])\n", "\n", " # a sort of hack to make sure the words are well spaced out.\n", " word_pos = 1/len(doc)\n", " \n", " # use matplotlib to plot words\n", " for word, topics in word_topics:\n", " ax.text(word_pos, 0.8, model.id2word[word],\n", " horizontalalignment='center',\n", " verticalalignment='center',\n", " fontsize=20, color=topic_colors[topics[0]], # choose just the most likely topic\n", " transform=ax.transAxes)\n", " word_pos += 0.2 # to move the word for the next iter\n", "\n", " ax.set_axis_off()\n", " plt.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us revisit our old examples to show some examples of document coloring" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "image/png": "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0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmoguADQRXQBoIroA0ER0AaCJ6AJAE9EFgCaiCwBNRBcAmvwf+urAJSil7roAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# our river bank document\n", "\n", "bow_water = ['bank','water','bank']\n", "color_words(model, bow_water)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "bow_finance = ['bank','finance','bank']\n", "color_words(model, bow_finance)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What is fun to note here is that while bank was colored blue in our first example, it is now red because of the financial context - something which the numbers proved to us before." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsgAAAFDCAYAAAAnNPjwAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAGZ1JREFUeJzt3Xm0LVV9J/DvD1DjQBhE1MQoihrHoCIhaqvPEDXaKmpnQG0bEo04tdJZSxOjJiTaascxYpxiEMel7RRRjEOApwERVNBOC4KtwTgrIigIgrj7j12Ht9955753H2+49/E+n7XOOvdU1alTtWtX1fec2rVvtdYCAAB0u6z0AgAAwGoiIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAYKcMyFXZryqtKset9LLMVGXNtExHr/SybGtVWVuVttLLAZtSlWdU5eyqXDbtn0et9DJx7bSork3Pa1d62WBHU5Ujpv3niLnh51fl/OXMY6cMyMD6ljqY7MyqcliSv0tyeZJXJfnrJJ/Zhp93rf6SvBp/mFgttnddAzZtt5VeAHZK/y3JDVZ6IWATHjZ7bi3fXtEl4dpuYV2ryh2T/HRlFgl2bgIy211r+Y+VXgZYhl9JEuGY7WBhXWstX16ZxQF2+iYWVblDVf6pKhdW5dKqnFKVB81Ns0dVnlWVk6ryzapcUZUfVOX4qtxrifm2qa3tPlV5Y1W+U5WfVeVLVfmjzVi+X6rKe6f5/X3V6t9m46XUqty+Ku+uyver8ovpMvJ6bZCrctg0/SuXmN/1qvKjqQx3mxv3mKqcXJWLqnJ5Vc6pyvOqcr0F85ltk5tV5U1V+VZVrlptzQqqcqOpjp06N/z60zq2qjx+btxTpuF/PL0+sCp/V5UvTnX78qp8pSovr8pec+9dm+TN08s3T/OZPfYbptutKk+tymeq8uOq/LQqZ1Xl6fP1clN1YKsV1jZQlaOn+vmA6fXV5TG9fmRV3l6V86ZjxqVV+Xz1NqQb7J9VuWlVXlaVc6dpL5r+Pq4qt5mmOS7JydNb/mpuG6zZLiu+DVVvNvLv08vD59bviBqal1TlN6tywlRv5+vgLarymqp8bTqe/rD6cfigJT532XV2JSyjrm3QBnn2nqnMfq8qZ0zrdWFV3lWVX13wOcs+HkzTX93kqioPqH7c/MlUhidU/2V70frcoCp/VpXPTdNfUv2Y/Oqq3HTBtM+pyhem/eKSqpxWlcdc8xJdbO54tH/1c+oPp2X8eFXuMk13k1p3vr68Kp+t6ttmbn57VOXF0358efXz08eq8jsLph3r9t2m8rto2mafrMq9l1jmZdXd6hmmVV19/Fg0r3+rypVVufk1K8FtqyqPqMqJtS4nfXsqm6fOTbf3VO7nVG+rf/H0vgctNe8tsbP/gnzrJKcl+bckb0hy8yR/mOSfq/LY1vLuabo7JvmfST6V5IQkP0pyyySPSPKQqjy8tXx0wfz3THJqkiuSvDfJ9ZL8fpJjq/KL1vKWjS3cdOA6Psl9kjyntbxkS1Z2Beyf5PQk5yV5R5LrJ/nxgun+KcnFSR5blWe1lp/PjT80vSxfPo6ryrFJ/ijJN5O8L8lFSX4ryQuSHFKVBy6Y197pbfsuSfL+JL9I8r0tWcmtrbVcUpUzkhxcld1by0+mUfdJrg7+hyR52/C2Q6bnE6fnP0nyqCSfTPIv6V+GD0zyp+l19uBhvsell92hST6Y5AvDfC9KkqpcJ8mHkjw4yblJ3pneXvIBSY5JcnCyfmifLLcOrCZrp+cjktwqvT3o6CXp9eb0JN9KskeS305vQ3pQhnKoyg3SjwH7J/lEehnWNN9D048LX0vfB5Lk8PRtNluGJMu7oWSVW5u+Dz8zyRezbn2TXt/2nP6+V5LnJDklybFJ9kk/fqYq90jy8fR9+GPp++8+SR6Z5JSqPKq1fGQ20y2os9vT2un5iCyuaxvz1PRz0PHpdebg9PPXAVW5W2v52TDt5hwPRg9Lr6f/nOT1Se6U5KFJDqrKnVrLBbMJp/PVyUkOSC/vY9O33f7px+n3ZzrWVmXPJCcluXuSM6dpd0nfVu+syp1by/M2oyyWa7/0/fac9OPefunlsrb6j10fTT8+vTu9nh2WngduP7vyOS37qVNZfDa9zfg+Sf4gycer8pTW8oYFn33PJM9OzxxvSs8Q/yXJidP2Onc24ebU3dby5SkcP2BazvPGD50C+F2SvK+1fOcaldo2VJUnpeev76av8wVJ9k3yG+n15rXTdLdK31/2S/Kv6dvqhul19KNVObK1/MNWXbjW2k73SNp+SWvT46Vz4+6ZtCuT9qOk/fI0bI+k7bNgPrdI2reTds6CcbP5vylpuw7D75S0nyft7Lnp10zTHz29vlXSzk7aFUl73EqX2RaU74sWjF+btDY37A3T9A9bMP0J07i7DsOOmIa9P2nXn5v+6GncM5fYJm9N2m4rXU6bKMO/mZb1Pw/DXjzVnROT9o1h+C5J+2HSvjoMu9VY74bhT5jm+2dzw2flecQSyzMr02Pm6vOuSfvHadyhy60DO8JjUT2dhu+/YNguSXvLtL4HD8MfPg175YL3XDdpuw+v1zsGXNseQ504bsG4NUN9OXLB+N2S9v+SdnnS7j837leS9q2kfSdp1xuGb1adXaV1rSVt7dyw2Xr9eDwmTuPeOY37g7nh1/R48POkHTI37sXTuGcv8dmvS9ouc+NulLQ9htfHLTGPX0raR5P2i6TdbRvUvZa0586Ne/40/MKkvX5c9qQ9fn7/zbpz1RuSVsPw2yXt4qT9LGn7LVG3j5j77COn4a9dYhsv93j7e9Owly1Y91lZP3Cl6/kS2+bzU5ntu2DcPsPfa6d6cdjcNHsm7QtJuyxpN11Qh+fL/Pyknb+sZVvpwlmhDTLbWS4aT1ALKtThy5jXq6dpbzk3vCXt0kwhe27cJ6fxNxqGXX1yTNrd0oP3xfMHpx3hMZTvdzOcsIbxiwLyvaf3vGdu+M2mg/SZc8PPSv8is+eC+e+atAuSdsaCbbJwR1xtj6Tdf1reVwzDzkja6Ul72jTu9tPwe0yv37iM+dZUr06aG75kQM66AP6dLPhiMR2gfpG0/73cOrAjPBbV001MP9sOfzkMmwXkTX5JiIDcknbWEu89dBr/0iXGP3Ma/9Dp9WbX2dVY16Z1Wjs3bBaeXrhg+gdM4zYISkt87qaOB29f8J5bT+PeOwzbN2lXTeetG27iM288HdM/u8T4A6b5/+02qHv/nrkvCkm75XC+3n1u3K7Teebk6fV1p+l+krS9F3zOCxYcA2Z1+5QF019nmv/nhmHX5Hi721T2F2T9L4l7Ju2n6V8ua35eq+GRHpAvTdpeG5lmVifes8T42fHhqQvq8BFz0y47IO/sTSzObIsvK61Nv9R596Q3g6jKfdIvD94r/ef/686951eTDW4++0prCy8nf2N63iv9Uv/oP6Vf9vpJkvu1li8ua01Wpy+29S/zLam1fLoq5yV5eFX2ai0/mkY9LsmuybquoabL1gekX4o5qmrhLH+WLGwnd35r+f6y12DlnJbkskxNJ6qyR5J7JPnb9EuTmcadl355P8Pw2SW6I9MvEd4pvRnA2OZyg3aKG3H79MuNX0nyvCXK+7IsLu9l14EdRVVunORZ6Zeab5N+mW80lu0n05th/PnUROAj6Zdnv9BartoOi7ujOWOJ4bN7PW5Vi7vBu930fMf0Mt6SOruj+NyCYeO55WpbcDxY7mccNM3vU63l0o0vdg5KP6Yv1aXhdabnbbFtFu13sxsjz5vPA63lqqp8L8ktpkG/nt4D06mt5cIF8z8pyfPSs8O8DcqytVw5zX8sy82uu63l51X5hyR/md5s453TqMenN2t7Y2ur9n8PvCPJy5OcXZV3pR8zT20tPximme3/eyxRZ24yPW/VOrOzB+Sl2p5+d3reI0mq8qj0toKXp7cj/GqSS9PbIa5Jcv9kw5vCMrXfXGDWLnbXBePunmT3JJ9Odvg7mL+76UnW85b0tt6HJXndNOzwJFdm3Q6f9INJpe8Uf7WNl2lFtJYrqnJKkt+pyk2S3Du9vpzYWs6pynfSA/LrpueWISCnt6F7VHr71g+mr/csqB6VxfV1KTeenm+XjZf3jRYM2yHKe7mm9oefTb9/4Ywkb01yYfo+PWtje3XZtpYfV+W30tuWPiK9TWGSXFCV1yZ5YWu5cvutwaq3VH2Z1cHf38T7Z3VwS+rsjmLR+WWpc8s1PR5s8BlTGJv/jFkb8m9taqGzbtscND2Wsi22zcXzA4b12WDc5OdZF9r3mJ6Xass7G77ngnEbywNjWV7TuvvGJM9N/yI0O18+Kb0d+Js3Mp8V1VpeUZUL0tvUPyO9PraqfDLJs1rL57KuTB44PZayVevMzh6Qb7rE8JtNz7Md5gXpleyereWcccKqvCE9IG8tr0n/hfrJSY6vyiNby2Vbcf7b0+Z+Y31belkfnuR1Vbl7krsm+WAbbgbJuu1yVmu5xzZeppV0UvrB4JD0gHx5cnXPFiel31xzvST3TfKl2S/jVbln+snwX5I8pK1/Y+Mu6TeKbI5ZeX+gtTx6M9+7I5X3cjwxPRz/dWvr/5Ix3eTzzPk3tJZvJnlCVSr917vfTvK09F97dkny/G28zDuSperLrA4e2lqOX8Z8tqTOXqtsg+PBIrPwt5wrU7Nt88rW8qdb4bO3p9my32yJ8Tefm25LPmOz6m5r+VZVjk/yqKrcIf1X6Lskeffcr7GrTmt5a5K3Tj9A3Du9vv5xko9N6zIrk2e2lldvr+Va8W5uVtg9qrL7guFrpuezpufbJjl7QTjeJb1JxNbUWstT0u+MfVCSE6o2uIR7rdRavpEe/A6uyq+nB+Uk6/f20VouSfKlJHeuyt7bdym3q1mPFIekh6pPt5bLh3F7J3lK+iX+E4f33XZ6Pr5t2IvHb6Zfcps3u+y46KrGlzP1EDJdqt2Zzcr2fQvGbfSL8tSs7Uut5Zis+xXkkcMkG9sG1wZbsn6z/yp332VOr86uc02OB5vrjPQrqvdbxvlqNu1yt+Vqcm76P245YApz82Zdwp25BZ+xJXX3tdPzkem/HidZ2KPGqtRaLmotH2ktf5LerHLvJPfL5u//W8XOHpD3SP8V52rTt+3HpX9j+cA0+Pwkt6vqnblP01WSo9N/EdrqWsv/SPLi9B3uY1X55W3xOavQcdPzE5I8Jr2d8YcXTPeK9Hbgxy46UFVlr6nN547szPR6eGiSO2f9EDxrTvGcudfJum7B1owzq8q+Sf5+ic/64fR8y/kR00n1mPRfR15dteEJtSo3r9o2+8Iqc/70vGYcOF3teM78xFW5c9XCK1WzYeN/SVtyG1xL/Cj9F+Jrsn4fTG/a9rSqPHTRBFW513R/gjq7vvOn5zXjwE0cDzbL9Avlu9LL+2W1Yb/oN5ruo8h0pesdSe5ZledXbfiFqXpfxbfeGsu2NbWWK9KXfff0q51Xq8r+6U0Ersz6XXBu7mdsSd09Mf2+lMPTu507t7Wl+0deDar3s72opfW+0/NPp2YW/5rk0TX19b9gPned6vRWs7M3sfhUkidW5eD0S9ezfpB3SXLkcIPdK9P7gDyrKu9L3wHukx6OP5Tk4dti4VrLX1Tl8vT2i5+oyu8ON69dW30gvR/Ko9LbfR2zqI1mazm2Kgemt1v6alU+ln6T5N7pl8Dvl97u6snba8G3tukGkbXpATkZAnJr+XpVvprex+hV6Tc2zHw2vT4/uiqfTu9T9qZJHpL+C8ii/wx3WnpYO2q6CW3WFvSY1nJx+snggPTyfHhVTkpvb7hvelu5+6S3fzt7C1d7tXtr+g16r6r+DwS+kr7+D0vv5/UP56Z/YJKXVuW09BPX99Nv+Dk0/Ve0lw7TnptepodV5cokX08PlG9rLV/fZmu0nbTev/fpSe5blXekl8dVyaabTEw3Mz06vf/jE6Z6/YX0Ovtr6W1Zb5N+DJ996VBnu2tyPLgmnp5+Sf/JSdZMx+Qr0o/HD05vg792mPZ2Sf4myeOn+y2+l/4fBe+Yvj0fk3X/XGY1+fP0XzKfXv0f1Jycdf0g757k6a1t8XJfo7rbWlpVXp/+A1LS2yWvdh9IcklVPpP+Za7Sy/egJJ9PbxqUJI9N/yHoH6vyjPT+rC9KP57+Rnrdu1eyFW/CX+kuPlaoW5H9pu4/jkvaHZP2wfR+j3+atFOT9uAF7zkiva+9S6euVD6QtLtmXZc7a+am36B7nmHccdP4/YZha6ZhRy+Y/lnTuDOzoD/m1fbIRrpzmsavTVrbyPvfNL2/Je3ATXzWw5L24aR9P73P6O+md4f2wqTdYbnbZLU+kvbfp+W+OBt2TzTrj/P0Be/bO2mvnbq0uTxpX03ai5J2g6W6uUna7ybttKRdMpT/WEcrvV/QE9P7DL0ivf/ZU5L2F0n7teXWgR3hsVQ9Te/L/Pipzl2a3k3RExet83R8eUXSPpe0H6R3M3h+0t6btHsvmPdBU/lenN6V0wbHlh35kbTbJu1D6d1YzdbviI0d/+bev2/SXpK0/zsdry9J2lem8vyvmesWa3Pq7Cqtaxvr5m2DerHUfre5x4Nsul/0hcfSpN0wac9N2v+Zts9P0vvzf1XmutdM7zLt6Un7dNb1H/wf07Y6Kmk33orlu6lz0sbO14vKZ8+k/a+p7v0svcvYTyTtQQvev9G6vWj+W1J3k7ZXepd7l23NMtyGdf/J6Xnqa1OduTC9G9dnZ8Nu93af1v3z075/WXrXfSck7UkZuhhcqg4vVd6LHtXfAADAjqz6v6Y/OcnbW1vx/xS5Q9vZ2yADAFxbzHolec2KLsW1wM7eBhkAYIdVlbum3wdxYHrb8g+3ltNXdql2fAIyAMCO68AkL0q/wf096Tevs4W0QQYAgIE2yAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgIGADAAAAwEZAAAGAjIAAAwEZAAAGAjIAAAwEJABAGAgIAMAwEBABgCAgYAMAAADARkAAAYCMgAADARkAAAYCMgAADAQkAEAYCAgAwDAQEAGAICBgAwAAAMBGQAABgIyAAAMBGQAABgIyAAAMBCQAQBgICADAMBAQAYAgMH/ByiQiCR8rK9UAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# sample doc with a somewhat even distribution of words among the likely topics\n", "\n", "doc = ['bank', 'water', 'bank', 'finance', 'money','sell','river','fast','tree']\n", "color_words(model, doc)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see that the document word coloring is done just the way we expected. :)\n", "\n", "## Word-coloring a dictionary\n", "\n", "We can do the same for the entire vocabulary, statically. The only difference would be in using `get_term_topics`, and iterating over the dictionary.\n", "\n", "We will use a modified version of the coloring code when passing an entire dictionary." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "def color_words_dict(model, dictionary):\n", " import matplotlib.pyplot as plt\n", " import matplotlib.patches as patches\n", "\n", " word_topics = []\n", " for word_id in dictionary:\n", " word = str(dictionary[word_id])\n", " # get_term_topics returns static topics, as mentioned before\n", " probs = model.get_term_topics(word)\n", " # we are creating word_topics which is similar to the one created by get_document_topics\n", " try:\n", " if probs[0][1] >= probs[1][1]:\n", " word_topics.append((word_id, [0, 1]))\n", " else:\n", " word_topics.append((word_id, [1, 0]))\n", " # this in the case only one topic is returned\n", " except IndexError:\n", " word_topics.append((word_id, [probs[0][0]]))\n", " \n", " # color-topic matching\n", " topic_colors = { 1:'red', 0:'blue'}\n", " \n", " # set up fig to plot\n", " fig = plt.figure()\n", " ax = fig.add_axes([0,0,1,1])\n", "\n", " # a sort of hack to make sure the words are well spaced out.\n", " word_pos = 1/len(doc)\n", " \n", " # use matplotlib to plot words\n", " for word, topics in word_topics:\n", " ax.text(word_pos, 0.8, model.id2word[word],\n", " horizontalalignment='center',\n", " verticalalignment='center',\n", " fontsize=20, color=topic_colors[topics[0]], # choose just the most likely topic\n", " transform=ax.transAxes)\n", " word_pos += 0.2 # to move the word for the next iter\n", "\n", " ax.set_axis_off()\n", " plt.show()\n" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "image/png": "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AAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABicoBcAAAAAYHCCXgAAAACAwQl6AQAAAAAGJ+gFAAAAABjc/wMrZST1b0d05wAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "color_words_dict(model, dictionary)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, the red words are to do with finance, and the blue ones are to do with water. \n", "\n", "You can also notice that some words, like mud, shore and borrow seem to be incorrectly colored - however, they are correctly colored according to the LDA model used for coloring. A small corpus means that the LDA algorithm might not assign 'ideal' topic proportions to each word. Fine tuning the model and having a larger corpus would improve the model, and improve the results of the word coloring." ] } ], "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.7.1" } }, "nbformat": 4, "nbformat_minor": 1 }