diff --git a/CHANGELOG.md b/CHANGELOG.md index 70e0f0e7ed..ec5d611a68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ Changes ======= +0.13.4, 2016-10-25 +* Passed all the params through the apply call in lda.get_document_topics(), test case to use the per_word_topics through the corpus in test_ldamodel (@parthoiiitm, [#978](https://github.com/RaRe-Technologies/gensim/pull/978)) + 0.13.3, 2016-10-20 * Add vocabulary expansion feature to word2vec. (@isohyt, [#900](https://github.com/RaRe-Technologies/gensim/pull/900)) diff --git a/docs/notebooks/topic_methods.ipynb b/docs/notebooks/topic_methods.ipynb index 2a7ba31185..53fabda694 100644 --- a/docs/notebooks/topic_methods.ipynb +++ b/docs/notebooks/topic_methods.ipynb @@ -11,9 +11,18 @@ "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": true + "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/partho/anaconda/lib/python2.7/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.\n", + " warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')\n" + ] + } + ], "source": [ "from gensim.corpora import Dictionary\n", "from gensim.models import ldamodel\n", @@ -85,9 +94,9 @@ "data": { "text/plain": [ "[(0,\n", - " u'0.164*bank + 0.142*water + 0.108*river + 0.076*flow + 0.067*borrow + 0.063*sell + 0.060*tree + 0.048*money + 0.046*fast + 0.044*rain'),\n", + " u'0.164*\"bank\" + 0.142*\"water\" + 0.108*\"river\" + 0.076*\"flow\" + 0.067*\"borrow\" + 0.063*\"sell\" + 0.060*\"tree\" + 0.048*\"money\" + 0.046*\"fast\" + 0.044*\"rain\"'),\n", " (1,\n", - " u'0.196*bank + 0.120*finance + 0.100*money + 0.082*sell + 0.067*river + 0.065*water + 0.056*transaction + 0.049*loan + 0.046*tree + 0.040*mud')]" + " u'0.196*\"bank\" + 0.120*\"finance\" + 0.100*\"money\" + 0.082*\"sell\" + 0.067*\"river\" + 0.065*\"water\" + 0.056*\"transaction\" + 0.049*\"loan\" + 0.046*\"tree\" + 0.040*\"mud\"')]" ] }, "execution_count": 4, @@ -353,6 +362,300 @@ "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": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New Document \n", + "\n", + "Document topics: [(0, 0.83270647275828491), (1, 0.16729352724171503)]\n", + "Word topics: [(0, [0, 1]), (1, [0, 1]), (2, [0, 1]), (3, [0, 1])]\n", + "Phi values: [(0, [(0, 0.96021858877561683), (1, 0.03978141122438307)]), (1, [(0, 0.87921979686273721), (1, 0.12078020313726268)]), (2, [(0, 0.94364164103826886), (1, 0.056358358961731088)]), (3, [(0, 0.88116401400740574), (1, 0.11883598599259435)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.90379559943992582), (1, 0.096204400560074232)]\n", + "Word topics: [(0, [0, 1]), (2, [0, 1]), (4, [0]), (5, [0, 1]), (6, [0])]\n", + "Phi values: [(0, [(0, 0.98551395531215846), (1, 0.014486044687841475)]), (2, [(0, 0.97924982750620215), (1, 0.020750172493797733)]), (4, [(0, 0.99280849901823975)]), (5, [(0, 0.97529774122781776), (1, 0.024702258772182187)]), (6, [(0, 0.99004205057244832)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.87507219282484316), (1, 0.12492780717515684)]\n", + "Word topics: [(0, [0, 1]), (3, [0, 1]), (4, [0, 1]), (7, [0, 1])]\n", + "Phi values: [(0, [(0, 0.97832342005836559), (1, 0.021676579941634404)]), (3, [(0, 0.93272653621872503), (1, 0.067273463781275078)]), (4, [(0, 0.98919912227661466), (1, 0.010800877723385373)]), (7, [(0, 0.97541896333079636), (1, 0.024581036669203651)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.87853819958920021), (1, 0.12146180041079968)]\n", + "Word topics: [(0, [0, 1]), (2, [0, 1]), (3, [0, 1]), (8, [0, 1])]\n", + "Phi values: [(0, [(0, 0.9759613424948147), (1, 0.024038657505185197)]), (2, [(0, 0.96571015226994938), (1, 0.034289847730050602)]), (3, [(0, 1.8515455755053762), (1, 0.14845442449462384)]), (8, [(0, 0.97848202469975276), (1, 0.021517975300247412)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.8564463740623548), (1, 0.14355362593764526)]\n", + "Word topics: [(0, [0, 1]), (2, [0, 1]), (5, [0, 1]), (9, [0, 1])]\n", + "Phi values: [(0, [(0, 0.97074863890671403), (1, 0.029251361093286004)]), (2, [(0, 0.95836933362205579), (1, 0.04163066637794411)]), (5, [(0, 0.95064079648593447), (1, 0.049359203514065572)]), (9, [(0, 0.90303582762229029), (1, 0.096964172377709767)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.11549963646117178), (1, 0.88450036353882822)]\n", + "Word topics: [(3, [1, 0]), (10, [1, 0]), (11, [1]), (12, [1])]\n", + "Phi values: [(3, [(0, 0.040062133454181532), (1, 0.95993786654581847)]), (10, [(0, 0.02010380646799674), (1, 0.97989619353200308)]), (11, [(1, 0.9910494032913304)]), (12, [(1, 0.99174412290358549)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.44388593146078087), (1, 0.55611406853921919)]\n", + "Word topics: [(3, [1, 0]), (10, [1, 0]), (13, [0, 1])]\n", + "Phi values: [(3, [(0, 0.38381806344612424), (1, 0.61618193655387588)]), (10, [(0, 0.23442811582700671), (1, 0.76557188417299327)]), (13, [(0, 0.6565173689986924), (1, 0.34348263100130755)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.20199255912939526), (1, 0.79800744087060471)]\n", + "Word topics: [(3, [1, 0]), (12, [1, 0])]\n", + "Phi values: [(3, [(0, 0.086998287940481173), (1, 0.91300171205951886)]), (12, [(0, 0.018652395463982244), (1, 0.98134760453601777)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.12505726157782684), (1, 0.87494273842217307)]\n", + "Word topics: [(3, [1, 0]), (10, [1, 0]), (12, [1]), (14, [1, 0])]\n", + "Phi values: [(3, [(0, 0.047837589620218307), (1, 0.95216241037978167)]), (10, [(0, 0.024102914052397426), (1, 0.97589708594760249)]), (12, [(1, 0.99007797561579514)]), (14, [(0, 0.043092845513997537), (1, 0.9569071544860025)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.72319610071601981), (1, 0.27680389928398014)]\n", + "Word topics: [(13, [0, 1]), (14, [0, 1])]\n", + "Phi values: [(13, [(0, 0.91396121153662724), (1, 0.086038788463372665)]), (14, [(0, 0.75627751890080153), (1, 0.24372248109919836)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topics: [(0, 0.16978578818257661), (1, 0.83021421181742339)]\n", + "Word topics: [(3, [1, 0]), (14, [1, 0]), (15, [1, 0])]\n", + "Phi values: [(3, [(0, 0.075528355267194022), (1, 0.92447164473280585)]), (14, [(0, 0.068233937712710677), (1, 0.93176606228728931)]), (15, [(0, 0.035035615878295893), (1, 0.96496438412170416)])]\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": { + "collapsed": true + }, + "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": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Document topic: [(0, 0.16977265560819235), (1, 0.83022734439180768)] \n", + "\n", + "Word topic: [(0, [0, 1]), (3, [0, 1]), (4, [0, 1]), (7, [0, 1])] \n", + "\n", + "Phi value: [(0, [(0, 0.97832871059713777), (1, 0.021671289402862077)]), (3, [(0, 0.93274219037812445), (1, 0.067257809621875594)]), (4, [(0, 0.98920178771276146), (1, 0.010798212287238566)]), (7, [(0, 0.97542494494492515), (1, 0.02457505505507479)])]\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": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New Document \n", + "\n", + "Document topic: [(0, 0.83271544885346704), (1, 0.16728455114653284)]\n", + "Word topic: [(0, [0, 1]), (1, [0, 1]), (2, [0, 1]), (3, [0, 1])]\n", + "Phi value: [(0, [(0, 0.96022273559375504), (1, 0.039777264406244892)]), (1, [(0, 0.87923132506871837), (1, 0.12076867493128163)]), (2, [(0, 0.94364741442849265), (1, 0.056352585571507421)]), (3, [(0, 0.88117538172166476), (1, 0.11882461827833525)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.90379650157173907), (1, 0.096203498428260883)]\n", + "Word topic: [(0, [0, 1]), (2, [0, 1]), (4, [0]), (5, [0, 1]), (6, [0])]\n", + "Phi value: [(0, [(0, 0.98551427047222717), (1, 0.014485729527772788)]), (2, [(0, 0.9792502760799594), (1, 0.020749723920040649)]), (4, [(0, 0.99280865663541784)]), (5, [(0, 0.97529827308199024), (1, 0.024701726918009776)]), (6, [(0, 0.99004226821414432)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.87508582200973162), (1, 0.12491417799026835)]\n", + "Word topic: [(0, [0, 1]), (3, [0, 1]), (4, [0, 1]), (7, [0, 1])]\n", + "Phi value: [(0, [(0, 0.97832871059713777), (1, 0.021671289402862077)]), (3, [(0, 0.93274219037812445), (1, 0.067257809621875594)]), (4, [(0, 0.98920178771276146), (1, 0.010798212287238566)]), (7, [(0, 0.97542494494492515), (1, 0.02457505505507479)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.87849699952437454), (1, 0.12150300047562547)]\n", + "Word topic: [(0, [0, 1]), (2, [0, 1]), (3, [0, 1]), (8, [0, 1])]\n", + "Phi value: [(0, [(0, 0.97594470848740367), (1, 0.024055291512596319)]), (2, [(0, 0.96568667415296994), (1, 0.034313325847029959)]), (3, [(0, 1.8514481357538262), (1, 0.14855186424617392)]), (8, [(0, 0.97846709644293861), (1, 0.021532903557061465)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.85642628246505537), (1, 0.14357371753494458)]\n", + "Word topic: [(0, [0, 1]), (2, [0, 1]), (5, [0, 1]), (9, [0, 1])]\n", + "Phi value: [(0, [(0, 0.97074011917537673), (1, 0.029259880824623285)]), (2, [(0, 0.95835736297327889), (1, 0.041642637026720976)]), (5, [(0, 0.95062671803078891), (1, 0.049373281969211057)]), (9, [(0, 0.9030095563876398), (1, 0.096990443612360172)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.11553980471363215), (1, 0.88446019528636788)]\n", + "Word topic: [(3, [1, 0]), (10, [1, 0]), (11, [1]), (12, [1])]\n", + "Phi value: [(3, [(0, 0.040094010013352027), (1, 0.95990598998664789)]), (10, [(0, 0.020120135475541381), (1, 0.97987986452445863)]), (11, [(1, 0.99104205049167049)]), (12, [(1, 0.99173733604900283)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.44387392752172772), (1, 0.55612607247827239)]\n", + "Word topic: [(3, [1, 0]), (10, [1, 0]), (13, [0, 1])]\n", + "Phi value: [(3, [(0, 0.38380312832253166), (1, 0.61619687167746828)]), (10, [(0, 0.2344167822754758), (1, 0.76558321772452431)]), (13, [(0, 0.65650312824652346), (1, 0.34349687175347654)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.20190467603529849), (1, 0.79809532396470151)]\n", + "Word topic: [(3, [1, 0]), (12, [1, 0])]\n", + "Phi value: [(3, [(0, 0.086912561161162444), (1, 0.91308743883883758)]), (12, [(0, 0.018632641254402973), (1, 0.98136735874559711)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.12500947583350869), (1, 0.87499052416649137)]\n", + "Word topic: [(3, [1, 0]), (10, [1, 0]), (12, [1]), (14, [1, 0])]\n", + "Phi value: [(3, [(0, 0.047797812955744749), (1, 0.95220218704425519)]), (10, [(0, 0.024082373476646421), (1, 0.97591762652335368)]), (12, [(1, 0.9900865539576843)]), (14, [(0, 0.043056835672030884), (1, 0.956943164327969)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.72327037334816735), (1, 0.27672962665183259)]\n", + "Word topic: [(13, [0, 1]), (14, [0, 1])]\n", + "Phi value: [(13, [(0, 0.91400946720135656), (1, 0.085990532798643396)]), (14, [(0, 0.75639064037568193), (1, 0.24360935962431809)])]\n", + " \n", + "-------------- \n", + "\n", + "New Document \n", + "\n", + "Document topic: [(0, 0.16977265560819235), (1, 0.83022734439180768)]\n", + "Word topic: [(3, [1, 0]), (14, [1, 0]), (15, [1, 0])]\n", + "Phi value: [(3, [(0, 0.075516159640739211), (1, 0.92448384035926079)]), (14, [(0, 0.068222833001707214), (1, 0.93177716699829283)]), (15, [(0, 0.035029710897900787), (1, 0.96497028910209925)])]\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": {}, @@ -381,7 +684,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 16, "metadata": { "collapsed": true }, @@ -430,7 +733,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 17, "metadata": { "collapsed": false }, @@ -439,7 +742,7 @@ "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeMAAAFBCAYAAABEo8fdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADBFJREFUeJzt3X+sJWddx/HPVwigrbS0BtuKJVGqrn8otkqrFRAXpVUr\nlOBPklZiDCIataQh/kKhhJBoIloTpTFIIiQqVavFGIEWlB8NEddqSinFGrBSqKFIgdql293HP565\n3Xvvnrt7b9rud9t9vZKTs3fmzJw5s8m+Z+aZc7fGGAEA+nxZ9wYAwPFOjAGgmRgDQDMxBoBmYgwA\nzcQYAJqJMQA0E2MAaCbGANBMjAGgmRgDQDMxBoBmYgwAzcQYAJqJMQA0E2MAaCbGANBMjAGgmRgD\nQDMxBoBmYgwAzcQYAJqJMQA0E2MAaCbGANBMjAGgmRgDQDMxBoBmYgwAzcQYAJqJMQA0E2MAaCbG\nANBMjAGgmRgDQDMxBoBmYgwAzcQYAJqJMQA0E2MAaCbGANBMjAGgmRgDQDMxBoBmYgwAzcQYAJqJ\nMQA0E2MAaCbGANBMjAGgmRgDQDMxBoBmYgwAzcQYAJqJMQA0E2MAaCbGANBMjAGgmRgDQDMxPpZU\nPTVVB1L1pu5NeUDVs5dtelX3pgA8Wh2bMa66dAnAJd2bAgAPt2MzxtPo3gAAOBqO1RhX9wYAwNFy\n5BhXnZCq+1L13k3Tn5Cqvcvl5BdvmveyZfpPLT+fnarfS9WNqborVfem6tZU/U6qTt607LuTrI2Z\nvnlZz4FU7U/Vmete95hU/VyqbkjV3am6J1V7UvXyVNWmdR4ci606K1V/nqo7l3U+a3u76iir+sZU\nXbPsry+m6r2p+r5Nr3liqi5P1XWpuj1VX0rV/6Tqb1J13hbrPZCq61N1aqquStUdy9/jTQ/8fW1v\n+x6fqquX9V35YD4qwPHusUd8xRj3pOqDSZ6RqhMyxj3LnPOTPC7zcvLuJG9dt9TuZfq7lp9/JskL\nkvxjkndmHgSck+SyJBek6tx16/2TJP+b5PlJrkly49qWJPlckqTqsUnenuT7k9yyvPfeJM9JcmWS\nZyS5dMWneVqSDyb5aJK3JPnyJJ8/4j44+r4uyQ1J/j3JHyU5PcmPJfn7VP1Exnjb8rpdSV6buV/f\nnrnfzkzyw0kuTNUPZYx3rFj/yUnen+RLSd6W5PFJfiTJm1K1P2P86WG3bh5AXZvkO5O8MmP89oP4\n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\nMQaAZmIMAM3EGACaiTEANBNjAGgmxgDQTIwBoJkYA0AzMQaAZmIMAM3EGACaiTEANBNjAGgmxgDQ\nTIwBoJkYA0AzMQaAZmIMAM3EGACaiTEANBNjAGgmxgDQTIwBoJkYA0AzMQaAZmIMAM3EGACaiTEA\nNBNjAGgmxgDQTIwBoJkYA0AzMQaAZmIMAM3EGACaiTEANBNjAGgmxgDQTIwBoJkYA0AzMQaAZmIM\nAM3EGACaiTEANBNjAGgmxgDQTIwBoJkYA0AzMQaAZmIMAM3EGACaiTEANBNjAGgmxgDQTIwBoJkY\nA0AzMQaAZmIMAM3EGACaiTEANBNjAGgmxgDQTIwBoJkYA0AzMQaAZmIMAM3EGACaiTEANBNjAGgm\nxgDQTIwBoJkYA0AzMQaAZmIMAM3EGACaiTEANBNjAGgmxgDQTIwBoJkYA0AzMQaAZmIMAM3EGACa\niTEANBNjAGgmxgDQTIwBoJkYA0AzMQaAZmIMAM3EGACaiTEANBNjAGgmxgDQTIwBoJkYA0AzMQaA\nZmIMAM3EGACaiTEANBNjAGgmxgDQTIwBoNn/A8+E5csToBBxAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -455,7 +758,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 18, "metadata": { "collapsed": false }, @@ -464,7 +767,7 @@ "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAd8AAAFBCAYAAAA2bKVrAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADDFJREFUeJzt3XuMpXddx/HPVwgEKBRLRCkqpmBka1KwF4sSevlDbcFy\nS1XQSCGGoEFFKU1j0lAUQkzEVCIJWoWQGC6RkiBFCahtRfAGFmJKVQwGU6liBVtK223L7s8/fs+0\np2dndmfs7nfW7uuVnJzM7zzzXM7Z5H2e22yNMQIA9Pmm3V4BADjWiC8ANBNfAGgmvgDQTHwBoJn4\nAkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgm\nvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCa\niS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWA\nZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGi2rfhW5SlV\n2V+Vdx7pFdquqpy9rNPrd3td1lXlF6vyuarcWZV9VXnNsq7X7Pa6AbD7Hr7bK/BQU5WXJPmtJNcn\nuSLJ3iR/k2QsDwCOceJ7+D0vM7LPGyNf3hisyp4kd+7aWgFw1BDfw+/EJFkN7/Lz53dndQA42uz4\ngquqfE9VPliVr1Tl61X5y6r80No0j6vKJVX586rcVJW7q/JfVfmjqjxri/nur8o1VXlCVa6sys1V\n2VuVG6ry8h2s3yOrctUyv9/e6fb9X1Xl8qrsT3JuklqWv78q+5bXDzjnW5U3LONnVeXCqvxtVe5Y\n3tv3Vs2Qr/3OqVV5a1U+u0x3V1U+X5W3VOXxm0x/0bKMl1Xl3KpcW5WvVeW2qny4Kk/fYnseVZVL\nq/KpZfrbq3Ljsuxv2WTaX6nKZ5Z/E7dX5a+WQ/AArNnpnu9JSf46yT8k+Z0kT0ryE0k+UpWXjpH3\nL9PtSfKmJH+R5MNJ/ifJdyZ5fpLzq/KjY+Rjm8z/8Uk+meTuJO9P8sgkP5bknVXZN0b+4GArt8Tn\n6iQ/kOTSMfIbO9y+B+PazMPNr8jc1jckqRz8PO/GeeBXJ7kgyYeSXJfkzMz39ZSqPHOM3LvyO69M\n8sLM9/ZPM79AnZbktUnOq8qZY+SOTZZzQZIXJPmTJG9PcnLmIfLTq3LyGPnqxsTL+3hdklOS/FOS\ndyS5J8lTk7w8yQeS3LJMe/yy7c/IPM/9jmWdfiTJe5Z5H3UXxQHsqjHGIR/JeEoy9idjXzJ+fe21\nU5NxTzK+kozjlrHHJuOETeZzYjK+lIzPbfLaxvx/Nxm1Mr4nGfcm44a16c9efuf1K+t4YzL2JuMl\n29muI/FIxrXJ2LfF9l2zNnb5Mn5rMk5ee+3dy/tx4dr4d6y+Pyvjr1jmdcna+EXL+D3JOGfttTcv\ny3jd2vh7lvG3bbKcRyfjsSs/v2uZ9uK16R6RjI8k4xvJOGW3Pg8PDw+Po/Gx08POtyV54wPjneuT\nvDtzr/VFy9jtY2VPamXam5NcleTpVfn2TeZ/Z5KLx7h/b3GM/GPm3vCeqjx6s5WqyjMy98iflOS8\nMfK+HW7XbnvrGLlxbez3Mvecv391cIzctPr+rHhXkq9l7nFu5r1j5Lq1sSvXl7EcUv7xJP+R5JL1\nmYyRO8fI7cu0JyT5qSSfHiO/uTbdPUkuzdwL/skt1gngmLTTw87XjwMPaSbzEOVFSb4vmYeGq/Ls\nJK9J8qwkT0zyiJXpR5InJ/n3tfn8yxj5+ibzv2l5/uYceMXwc5JcnBme54yRG7a7MUeJkeTvNxlf\n3eb7VOXhSX4287D0yUmOzwPP3T95i+VsdxlnLPP7+Bi566BrPqd9WJJRlcs3eX3jM99ziPkAHFN2\nGt8vbzH+n8vz8UlSlRdlnrO9K/O85BeS3JHcd0HSWZnnc9fdusX8v7E8P2yT156Z5LjMveN/Pvjq\nH7U22+6ttvkPM8/5fiHJBzPf+7uX1345m7+vY7NljJF9VQcsY+OirS9tY72fsDyfsTw2M5I8Zhvz\nAjhm7DS+37rF+Lctz7ctz2/MDMJpY+0Wm+UK3rN2uNyDeVvmnvXPJbm6Ki8cI3sP4/yPGlU5LTO8\nH0vy3DGyf+W1yjzM+2BtRHqrPehVG5/3FWPkdYdh2QDHhJ2e8z21atO9mHMz93CuX35+apIbNwlv\nZR4mPpzGGHl15l+V+uEkf7zVueGHgKctz1evhndxZpJHHYZl/F3mEYqzqg45v41pD/dnCvCQttP4\nHp888NxeVU7PvKDm1szDoEnyxSTfXXXfHvGGX80ROv83Rl6b5M2ZXwQ+WpXjjsRydtkXl+dzVger\n8sTMIwAP2hj57yTvy/xjIW9ZvjCtLusxVXncMu0tmRfbnV6Vy6oO/PdUlZOq8l2HY90AHip2etj5\n40l+pipnZp5jPTHzythK8qqVi6WuyLyX9LNV+UCSe5M8OzO8H8q85/SwGyOXVWVvkl9L8mdVOW+M\nLc8j/3/0qcz3/cVV+WSST2SeCjg/837cm7f4vdpifCs/n+R7My/sOrcqH828z/ekzKMLF2T+W9iY\n9mmZX6x+uiqfyLw24MTMz/v0JC/N/V8cAI55O9nzHUn+NckPJvlqklcluTDJp5OcP0auum/CkSsz\n/9jEzUlelrln/G+Zh0Y/c5D5H+oPUhzyd8bImzJvkTkjM8AnHGrDjoBtres257N629X+zPC9PfO2\nql/I/FJzZeYtRvceZNnbWsaynFszP+fLMqP7yswQ70ny+8n9t0Uttx2dvazLLUlenHnh1zmZV6D/\nUuZFdwAsagz/0Q4AdNrx33YGAB4c8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWA\nZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwB\noJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNf\nAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3E\nFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz\n8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQ\nTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8A\nNBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuIL\nAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4\nAkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgm\nvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCa\niS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWA\nZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwB\noJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNf\nAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3E\nFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz\n8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQ\nTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8ANBNfAGgmvgDQTHwBoJn4AkAz8QWAZuILAM3EFwCaiS8A\nNPtfmq3Vvt7+mtoAAAAASUVORK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -485,16 +788,16 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAApgAAAFBCAYAAADT6N+zAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAG01JREFUeJzt3Xm0ZVddJ/Dvj0kgmomACJIwy7SCTAYEQhgbkDCJLYMQ\nWCgCAcQhDbTIICygW2igiTTIEGRQEJFZ5iSMYQxpGyIJBKOQIBASMgdI1e4/9rlVt+67r+pVZade\nVfH5rHXXrTpnn3PPsM++33vPvvtVay0AADDKFdZ7AwAA2LMImAAADCVgAgAwlIAJAMBQAiYAAEMJ\nmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAwlIAJAMBQ\nAiYAAEMJmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAw\nlIAJAMBQAiYAAEMJmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAA\nDCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAwlIAJAMBQAiYA\nAEMJmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAwlIAJAMBQAiYAAEMJmAAADCVgAgAwlIC5\nO6o6PlUb13szdidVOagqG6vyxvXelpmq3G3apues97awm6l6Wqq+nqqLUrUxVU9b701iz1SVp1Xl\n61W5qCobqvJHU7t17HpvG5efqhwxnefHLEw/vSrfXss6ds2AWXXE1Gg+ZtuFfy61JAImu56qg6Zr\nd5cJ8nucqocneUWSi5O8PMnzknz+cny9u03n1AehnzNVWa2utenBnm3ZOV7zeb/SwA0ZTeVd3aOT\nXH29NwJYF7+V3j7+Vlr7/npvDHu0TXWttWyqa1W5eZKL1m2r2C3sqgGz1nsDdmmtfXe9NwFW4dq9\n/F0nSXZiuHROf35dJ0nmw+X0/1PXZ3PYnWz7FnnVXqn6aao+vTD9qqm6ZLp18qiFeU+apj92+v9t\nU/XKVJ2Uqh+l6uJUnZqql6Zq34Vlj0s29ZN707SejanakKoD58pdMVVPTtUJqTo3VRem6sRUHZmq\nWljn5tt2VTdJ1TtS9f1pnYeu7VDtRKtv76WpOnRFH8yq353Kv2yV9V0lVeek6oxUXWFh3iNSddw0\n/+JUnZyqP0/VVZasZ2Oqjk3VL6fq9an67rRNu1VXhqr8WlXeU5UfVeWCqny6KvdeKLN3VY6qyieq\n8p2q/KQqP6jKe6tyx1XWu7Eqx1blGlX5m6qcWZVLqvK1qjx2O7bvF6ryj9P6XnUZd3fnqXpukm+n\nf+Px2Llrt3d3mb/VWnWHVH1wag8Wr+3rpuroVJ02tTFnpeq9qbr9Kq+79rZgd1b13Om6v3uS2qJt\n7PMfnKq3pOqUVF0wPb6cqqcuPQ5V15ra4G9MZc+Z/n1Mqq4/lTkmybHp5/R5C+3xLtV2zvezrsoN\np2vorKqcV5WPVuVWU7kDqvL66fq8uCpfqsphS9a3d1VeXJVvTOXOrsqHq3LPJWU39aeuyq2r8sGq\nnFOVC6tyfFXutMo2X7EqT67KCVU5dyp/YlWOrNoc7Kc2a2NVPrGV/f9/Uzv1yzt0ALdc13Orsqmu\nTa+9sSobpvkr+mBW5XnT9EOr8rCqfGHanx9V5e+rpg9GWy5z26q8sionTeUursqpVXlpVfZdUn5T\nv8Cq3L0qx03n99yqfKAqN1tlf65WlWdM5/q8qpxflZOn177mkrLPqspXp/eH86vyuam7wC6pKg+c\n3qtm7zlnTPXuSQvl9pvq9MnV+9T+uCofr4X3v1G2/Q1maxem6gtJfiNVe6W1C6c5d05ylfSG555J\n3ja31D2n6R+f/v8HSR6c5JNJPpYebG+X5E+S3DdVh8yt95gk5yR5UJL3JDlptiVJfpwkqbpSkg8k\nuU+Sb0yvfUn6xfCqJL+R5Igle3PjJF9IckqStya5WpLztnkM1s/i9l41fXsX+7+8J8m5SR6ZqqPS\n2mL/zAcn2SfJ32wxr/eTe2yS7yT5x/Tje8ckL0hyj1Tde8m69k/vg3N+knel9wXdnW7T3TDJCUn+\nJclrkvxKkt9N8qGqPKK1vHMqd/MkL0yvsx9Ir5MHJnlgkvtV5QGt5aNL1r9vks8m+UmSdyb5hSS/\nk+SNVdnQWt6ytY2bGtX3J7lTkme0lr+6LDu7kx2XXs+enn7dvmdu3klJ9pv+/ZtJ/nuSTyd5Q5ID\nkvw0Sf8wmnw0/Th+JL2OHZBehz+TqgentQ9vWuuOtwW7o+PSr/vHpdfF56V/uzhrC16cZEP69XlG\n+rm4R5JXJrl95o9D1dWSfC7JDdLb5PdN6zoovY6/M8npSd6d2QeG5PjpMXP6wH0b6Qbp7ebJ6e8n\n10/y0CTHVeUuSf45va17e3p79ogk/1yVm7aW7yZJVfZJPz43S/KlJP+UXg//a5KPVuWJreV1S177\nDkmeMS37uvTz9LAkH6/Kr7eWb84KVmXNdbe1nFKV45IcVpUbt5Zvzb9oVX4zyS2TvHPx28YdtK26\ntszsfenIJIen16njkxyS3sYePB2Dn80ts9VsUJVDWsuF2VKb1v+g9HP5f5LcIv12/u2rcovWcvas\n8NSmHp/k4PTj/Ib09uZG6fX6XUl+OJXdZ9r3Wyc5cSp7hST/JcnfTevepfoiV+UJ6e9l30s/5mcl\nuVb6/j42/fikKgemH+cD09veDyXZK8kDkny4Kk9oLW8YunGttW0/kue3ZENL7jc37UUt+WlLPtaS\nf5+bXi05qyXfnJt2vZbUkvU+riUbW3LUwvQjptd7zCrb87xpuVdssd7+2q+flj18bvpBU/kNLXnB\nmvZ5PR/b2t7kuJZsWJj2mqn8/ZeU/+A075Zz0x47vcY7W3KVhfLPmco/dWH6bJuOackV1v04bccj\naQclbWPSNiTtJQvzbpu0nybtR0n7xWnaLyVt/yXruU7Szkja15fMm63/tUmruek3T9rPkva1hfJ3\nm5Z5ztw2npy0S5L28PU+Zpex7r5xyby7zdWh318y/4ot+VZLLmrJXRbmXbsl323JGS258tz07WsL\n9oTHsuu/T7/BKuXfNB2HO8xNe8B03F66pPyVWrLXkvP2nHXf9608Fq7xZy7Me/Y078dJ++uFeb83\nzXvZ3LTXTtNevVD2RtM6Lk7agXPT7zb32o9eWOYJ07yjF6Y/b5r+ioX2opL2+mldh89N/+2p/P9c\nsu9vmsrfY/AxPS5pK+ratB3HLkx77twxvsXCvLdN2/ewhenXm9/3uemPm9Z11ML0I6bpP03aYQvz\nXjS9xp8tTP+7afrRS17n6kn7pSXH8U8Xyl0laR9K2qVJO3i96/rCtn15qo/XWDJv/7l/Hz9t/+8s\nlNk7aV9N2oVJu+bCsd6QtMcslP+3pH17Tdu2pp1IDl3RGCVfaMkJLXnS1HjdeJp+m6nsa9aw3mrJ\nj1vy8YXpR7TVAubmAHvG0pCT7DMt+/a5aQdN23TmFm9Ou+pjW9u7PGDeaVrmHQvTf7klP2vJlxam\nf7UlP2nJ3kvWf4WW/LAln1+YvrElF7fkgHU/Rtv5mHvzOTtpey2Zf8yyN4dV1vXKqeyvLkzfmLTz\nZyF1Yd7x0zJXn5s2e1N6TtJunbQzk3bOYsO5Wz3WFjC/ssqyD5zm/49V5j9turbvO/1/+9uCPeGx\nWsBcvfxtp+P67Llps4D5wjUsPztvu0vAPG0xtExBZnZ97rUw7wpTYPnE9P8rJ+2CpJ2btH2XvM5f\nTtfys+emza7lTy4pf6Vp/V+cm1ZJOyv9w+qKupu0fabXePvctCsm7btJ+0HSrrxQ9sKknXo5HNMd\nCZjPX1L+sNXC8SqvW1NQ/fjC9FnA/Nsly1x/mvcPc9OuOYWq7ybtatt4zf3Tvwj4wirzD57W/5K1\n7MNOrPdfnur1irq6ZNvfscr8B0717YkLx/oyBcy1/sjnhPRhCnrfk6q9k9w2yUvSv06uad63svn2\n+Ob+Gf021hPTvya/Rfqtm/m+gNdd43YkyU3Tb2ucmuQvUiu6FtW0rTdfsuz/TWs/WzJ9V7X27W3t\nhFSdmuTwVO2T1s6d5vxe+rF+06ay/fbYwem3Bf54lWP4kyw/hqentbO2Yx92NSe2lbdckn4L5Ygk\nt0n6beyq3DnJH6V3G7hWepeQmZZebxd/cPXN1nLBkvV/Z3reLyt/fXnXJH+a3v3hrq3la2vdmd3U\nF1eZPuundv2pP+eim6TXzZsn+XAuW1uw56naP8l/S3K/9K4ge83NndXXmU+m30Z/Zqpul36r8bNJ\nTsrKbjG7m5NaW3Er98zp+dTF67+1bKzK95P86jTp19JH6fhMa1O3rC0dm+TZ6W3Foq8sTmgtl07r\n329u8hZ1d2XVXVl3W8uGqrwuyXOS/Hb6Lf4keUx6d6/XLtmena1lyTHIlu3fJlM3gR3JBmt9jTtM\n6/tUa7l4q1vey14xSavKsvZn1v7vau3J25K8NMnJVXl7+rX92dYy/z49a1v3WWXfrpXNbeswawuY\nrf0sVZ9Jcs9UXSPJXdJP2ifS2jdS9b30YPnaLAuYyT+k97M4Lb1f1n+mB5gk+eP0fmprdY3p+SbJ\nVvtC7LVk2n9ux+vsCrZ3e/82vd/gw7O5sTkiyc+S/P1cuf3SK9M1s/VjuNhI78g27WpW65802699\nkqQqD0nvh3Zxet+g05JcmGzq+H5oltfbZW9ISXLp9HzFJfN+Pckvpr/Bn7L1zd8jrFaHZtf2w7ay\nbEs/VvPld6Qt2LNU7ZPky+l9KL+Y3hacnV7v9k3vF7u5vrZ2fqoOSfL89D6X90lvE85K1auTvDCt\n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\nbsk7WnLHJeu+3XR8z5k7p4debvu4A4/5a3yV+Vu7Pv8taactTNs7aS9O2inp4wyenbQPJ+2eS5Zf\n9Vpebf1z8x6VtI+lD1t0SdK+M7VJz0ja0rqbtH2n9uTCpO13OR7T45K2oq4tO5artYtbOzfTfhyd\ntG8n7aKkfTNpL0jaVVc5J0dkydA52zrHSbta0p6VtJOyeQiqryXtZUk7YKHslZL25KR9Jn3YuIuT\ndvp0jp56eR7vHTxHT0jau5L2rWnfzkraV6b3kMUhufZK2jOT9qWknTfVn9OS9v6kPT5zQzmtdqy3\nVpcXH9UXAAB2B1W5R/o3U29ube1/hhZ2pu3pgwkArL+j0m+P77RfBMP22p5higCAdVCVW6X3F7xd\n+t/Gfl9r+fL6bhWsTsAEgF3f7dL/kMZ5Sd6RPmYp7LL0wQQAYCh9MAEAGErABABgKAETAIChBEwA\nAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAET\nAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErA\nBABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYS\nMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAICh\nBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABg\nKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEA\nGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwA\nAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAET\nAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErA\nBABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYS\nMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAICh\nBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABg\nKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEA\nGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwA\nAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAET\nAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErA\nBABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYS\nMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAICh\nBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABg\nKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEA\nGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwA\nAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGErABABgKAETAIChBEwAAIYSMAEAGOr/A6wxB0MX\nJ3UgAAAAAElFTkSuQmCC\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAApgAAAFBCAYAAADT6N+zAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAG05JREFUeJzt3Xm0ZFddL/Dvj0kgmoQQIqImzDK4giRgQDSE8QEyRMQn\noJCwUAQCiAOCT2QQluITH/KMPuYggzLKGA1CBsYACSHPB5EEglFIEAgJISOQ7v3+2Ke6q+vW7b7d\n2enb3Xw+a9Wq7n12nTrn1D67vlVn177VWgsAAIxynfXeAAAA9iwCJgAAQwmYAAAMJWACADCUgAkA\nwFACJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmYAAAMJWAC\nADCUgAkAwFACJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmY\nAAAMJWACADCUgAkAwFACJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmYAAAMJWACADCUgAkAwFAC\nJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmYAAAMJWACADCU\ngAkAwFACJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmYAAAMJWACADCUgAkAwFACJgAAQwmYAAAM\nJWDujqpOSdXG9d6M3UlVDqrKxqq8br23ZaYq95626XnrvS3sZqqekarPp+qKVG1M1TPWe5PYM1Xl\nGVX5fFWuqMqGqvz21G+dtN7bxrWnKkdNr/PjF8rPq8qX17KOXTNgVh01dZqP33blH0gtiYDJrqfq\noOnc3WWC/B6n6tFJ/irJlUleluQFST55LT7fvafX1AehHzBVWa2ttenGnm3Za7zm1/16AzdkNI13\ndY9LcuP13ghgXfxiev/4i2nt6+u9MezRNrW11rKprVXljkmuWLetYrewqwbMWu8N2KW19tX13gRY\nhXP32neLJNmJ4dJr+oPrFkkyHy6n/5+zPpvD7mTbl8ir9krV91L10YXyG6bqqunSya8tLHvKVH70\n9P9DUvXyVJ2Zqm+l6spUnZOql6Zq34XHnpxsGif3+mk9G1O1IVUHztW7bqqemqpTU3VJqi5P1Rmp\nOiZVtbDOzZftqm6Xqrem6uvTOg9f26HaiVbf3qtTdfiKMZhVvzrV/8tV1neDVF2cqvNTdZ2FZY9J\n1cnT8itTdVaq/ihVN1iyno2pOilVP5qq16Tqq9M27VZDGaryU1V5d1W+VZXLqvLRqjxgoc7eVXlW\nVU6syleq8t2qfKMq76nKPVZZ78aqnFSVm1blVVW5oCpXVeVzVTl6O7bvh6ryjml9f30Nd3fnqXp+\nki+nf+Nx9Ny524e7zF9qrbp7qo6f+oPFc/vHU3Vsqs6d+pgLU/WeVN1tledde1+wO6t6/nTe3ydJ\nbdE39uVHpuqNqTo7VZdNt9NT9fSlx6HqgKkP/sJU9+Lp38el6pZTneOSnJT+mr5goT/epfrO+XHW\nVbn1dA5dWJXvVOUDVbnzVG//ufPzyqp8uipHLFnf3lX5s6p8Yap3UVVOqMr9ltTdNJ66KnepyvFV\nubgql1fllKrcc5Vtvm5VnlqVU6tyyVT/jKocU7U52E991saqnLiV/f9/Uz/1ozt0ALdc1/Orsqmt\nTc+9sSobpuUrxmBW5QVT+eFVeVRVPjXtz7eq8g9V0wejLR9zSFVeXpUzp3pXVuWcqry0Kvsuqb9p\nXGBV7lOVk6fX95KqvL8qd1hlf25UlWdX5bSp/qVVOWt67pstqfuHVfns9P5waVU+MQ0X2CVV5eHT\ne9XsPef8qd09ZaHeTaY2fVb1MbXfrsqHauH9b5Rtf4PZ2uWp+lSSn03VXmnt8mnJvZLcIL3juV+S\nN8896n5T+Yem//9mkiOTfDjJB9OD7aFJfjfJg1J12Nx6j0tycZJHJHl3kjNnW5Lk20mSqusleX+S\nByb5wvTcV6WfDH+d5GeTHLVkb26b5FNJzk7ypiQ3SvKdbR6D9bO4vTdM397F8S/vTnJJksem6llp\nbXF85pFJ9knyqi2W9XFyRyf5SpJ3pB/feyR5UZL7puoBS9a1X/oYnEuTvDN9LOjudJnu1klOTfKv\nSV6R5MeS/GqSf67KY1rL26d6d0zy4vQ2+/70NnlgkocneXBVHtpa/mXJ+vdN8vEk303y9iQ/lORX\nkryuKhtayxu3tnFTp/q+JPdM8uzW8hfXZGd3spPT29kz08/bd88tOzPJTaZ//1yS/5Hko0lem2T/\nJN9L0j+MJv+Sfhw/kN7G9k9vwx9L1ZFp7YRNa93xvmB3dHL6ef+E9Lb4gvRvF2d9wZ8l2ZB+fp6f\n/lrcN8nLk9wt88eh6kZJPpHkVul98nundR2U3sbfnuS8JO/K7ANDcsp0mzlv4L6NdKv0fvOs9PeT\nWyZ5ZJKTq/JzSU5I7y/fkt6fPSbJP1Xl9q3lq0lSlX3Sj88dkpyW5B/T2+F/T/IvVXlya3n1kue+\ne5JnT499dfrr9KgkH6rKz7SWL84qVmXNbbe1nF2Vk5McUZXbtpYvzT/ptF93TvL2xW8bd9C22toy\ns/elY5I8LL1NnZLksPQ+9uDpGHx/7jFbzQZVOay1XJ4ttWn9j0jyT0n+T5I7pV/Ov1tV7tRaLppV\nnvrUU5IcnH6cX5ve39wmvV2/M8k3p7r7TPt+lyRnTHWvk+S/Jfn7ad271Fjkqjwp/b3sa+nH/MIk\nB6Tv79HpxydVOTD9OB+Y3vf+c5K9kjw0yQlVeVJree3QjWutbfuWvLAlG1ry4LmyP23J91rywZb8\nx1x5teTClnxxruwnW1JL1vuElmxsybMWyo+anu/xq2zPC6bH/dUW6+3P/ZrpsQ+bKz9oqr+hJS9a\n0z6v521b25uc3JINC2WvmOo/ZEn946dld54rO3p6jre35AYL9Z831X/6Qvlsm45ryXXW/Thtxy1p\nByVtY9I2JO0lC8sOSdr3kvatpP3wVPYjSdtvyXpukbTzk/b5Jctm639l0mqu/I5J+37SPrdQ/97T\nY543t41nJe2qpD16vY/ZNWy7r1uy7N5zbeg3liy/bku+1JIrWvLzC8tu3pKvtuT8llx/rnz7+oI9\n4bbs/O/lt1ql/uun43D3ubKHTsftpUvqX68ley153Z637vu+ldvCOf6chWXPnZZ9K2l/s7Ds16dl\nfzlX9sqp7G8X6t4mad9O2pVJO3Cu/N5zz/24hcc8aVp27EL5C6byv1roLyppr5nW9bC58l+e6v/P\nJfv++qn+fQcf05OTtqKtTdtx0kLZ86fybyftTgvL3jxt36MWyn9yft/nyp8wretZC+VHTeXfS9oR\nC8v+dHqO318o//up/Nglz3PjpP3IkuP4ewv1bpC0f07a1Uk7eL3b+sK2nT61x5suWbbf3L9Pmbb/\nVxbq7J20zybt8qTdbOFYb0ja4xfq/3vSvrymbVvTTiSHr+iMkk+15NSWPGXqvG47ld91qvuKNay3\nWvLtlnxoofyotlrA3Bxgz18acpJ9pse+Za7soGmbLtjizWlXvW1re5cHzHtOj3nrQvmPtuT7LTlt\nofyzLfluS/Zesv7rtOSbLfnkQvnGllzZkv3X/Rht523uzeeipO21ZPlxy94cVlnXy6e6P7FQvjFp\nl85C6sKyU6bH3HiubPam9Lyk3SVpFyTt4sWOc7e6rS1gfmaVxz58Wv7nqyx/xnRuP2j6//b3BXvC\nbbWAuXr9Q6bj+ty5slnAfPEaHj973XaXgHnuYmiZgszs/NxrYdl1psBy4vT/6yftsqRdkrR9lzzP\nn0zn8nPnymbn8oeX1L/etP5Pz5VV0i5M/7C6ou0mbZ/pOd4yV3bdqf43knb9hbqXJ+2ca+GY7kjA\nfOGS+kesFo5Xed6aguqHFspnAfPvljzmltOyt82V3WwKVV9N2o228Zz7pX8R8KlVlh88rf8la9mH\nndjuT5/a9Yq2umTb37rK8odP7e3JC8f6GgXMtf7I59T0aQr62JOqvZMckuQl6V8n17TsS9l8eXzz\n+Ix+GevJ6V+T3yn90s38WMAfX+N2JMnt0y9rnJPkj1MrhhbVtK13XPLY/5vWvr+kfFe19u1t7dRU\nnZPkYanaJ61dMi359fRj/fpNdfvlsYPTLwv8zirH8LtZfgzPS2sXbsc+7GrOaCsvuST9EspRSe6a\n9MvYVblXkt9OHzZwQPqQkJmW3m4Xf3D1xdZy2ZL1f2W6v0lW/vryF5L8Xvrwh19oLZ9b687spj69\nSvlsnNotp/Gci26X3jbvmH6Z85r0BXueqv2S/EGSB6cPBdlrbumsvc58OP0y+nNSdWj6pcaPJzkz\nK4fF7G7ObG3FpdwLpvtzFs//1rKxKl9P8hNT0U+lz9LxsdamYVlbOinJc9P7ikWfWSxoLVdP67/J\nXPEWbXdl013ZdlvLhqq8OskfJ/nl9Ev8SfL49OFer1yyPTtby5JjkC37v02mYQI7kg3W+hx3n9b3\nkdZy5Va3vNe9bpJWlWX9z6z/39X6kzcneWmSs6rylvRz++OtZf59eta37rPKvh2QzX3rMGsLmK19\nP1UfS3K/VN00yc+nv2gnprUvpOpr6cHylVkWMJO3pY+zODd9XNZ/pQeYJPmd9HFqa3XT6f52yVbH\nQuy1pOy/tuN5dgXbu71/lz5u8NHZ3NkcleT7Sf5hrt5N0hvTzbL1Y7jYSe/INu1qVhufNNuvfZKk\nKr+UPg7tyvSxQecmuTzZNPD98Cxvt8vekJLk6un+ukuW/UySH05/gz9765u/R1itDc3O7Udt5bEt\n/VjN19+RvmDPUrVPktPTx1B+Or0vuCi93e2bPi52c3tt7dJUHZbkheljLh+Y3idcmKq/TfLitHZ1\ndk+XLBZM4WzpssnVSa4//Xuf6f5rq9Sdla/4EUq2fv7Pn/s72nZfleSPkvxWNgfMJ6W/n75+K+vZ\nmZYdg9X6vx3JBm3Zc8y9xvPPMXuNzl/Dds9ek7tPt2VadrH+pLW8rCrfTPLUJE9P/1IkVflwkme1\nls9k8749YLotXVUG79v2TFN0UpL7pwfIe6UPRv7E3LIHpf/y+OeTfH7Tt1z90/GR6QP3H5Itf2RS\n6QOit8esg3hXWtvaG9EyywLTrmx7t/eN6T/QOSrJK1N11yQ/nX6sLpqrNzuGn01ry3+ZO26bdjWr\n/cLy5tP97Ni8KL2jO7QtTMkx/Rpy5C9oj03/BPmUJO+rypGt5aqB69/VrNaGLpmWPTytHb+G9VyT\nvmBP85vpP2Z5flp70RZLqu6RHjC31NoF0+N+M1V3TP9B0DHpgaeSpd90/CCYtaubr7L8xxbqXZPn\neFdrW/1AtYXWckFV3pvkyKrcPv2HR3dO8g+t5VvXYHt2uqpskQ1a2/zHQ6Zf0G9vNlhmFkTXcpV0\n9pq8rLX8/oDn3mlay5uSvKkqe6f/iPKXkjwx/cc7d8jmffvt1nLsztqu7flLPiemdzr3T++IPpHW\nvje3bL/0N8i9pv/P3Ha6f9+SSy+HpX+1v2jD9FzLvu35Qma/dq5atvwHV58f86Qkh6XqdulBs6V/\nmzFf7/Ikn09y5yxOE7XnO6Rq6ae0+6QfqzOm/98myVlLwmWlX9IeqbWWY9L/YsYDkxxftdtOpL9h\nut+Rc/OT6ef9WsO7vmCz26S3339csuyIbT66tX9La3+T3v6S/sY/c01e093R2enDWO4yvWEvuu90\nf8aSZWu1qe1Wbfdx/dv08+TJ6R8QWnaNy+Pba1M2mA+Xk9Wywfb6dPpVp8Ortrm+Wd3R/ftO01q+\n01pOaC2/lf6N9n7p/ensL33t1H3bnoB5RnoKfkT6WIn5EHlSeoP/w6y8PH7edH/EFmurOiBZNUnP\nPokduGJJaxvSp3C4RZK/TtUNV9Spuvn0ifwH0eun+99Iv1R+YZJl3wb9r/TLD8dNl9e2VLXv9A3o\nnmafLHwzU5W7JXlseoc/m1rnvCS3q1rxLcYLcy2NwWktv5vkT9PD7geqNl0K3p1cnN4HrDx3t+09\n6ZfKjknVg5fWqLrHpnNeXzDvvPQ++IgtSvs5/JwsfmtcdaepD140a+/z4xRX74/3QK1Po/PmJHun\nX8nYpCq3SfKM9Glutjrl2DaeY4u2W5UVbbcqN69a2de0lhPTx24elT5t0tmt5SM7ui3r6Lzp/oj5\nwqpsLRtsl2kc4lvSj/NLq7b8owFV2Wv2IaK1fDP9db9bVZ5btTIfVZ9f9ZYjtm2UWjKH62R2te6K\n6TL5R5M8sipPWGU9P704J+g1tfZL5K1tTNUp6QGzZT5gtvafqTo3/VP01emDTGdOSx9b9shUfTzJ\nx9J3/MHpn+IuyEqnpn+CfGaq9s/mMVv/O61dmn7SH5w+DuVhqTopfYzFAeljWu6VPs/ev615//Yc\n70qfo/KZ6WOKXj69EW+pteOmOQefmuTcVH0gyX+mf+K5VfqnntdNy/ckH0nyxKoclt4ub5HeSVeS\n35r7gc7L0ucPO7Mq70wfx3qv9HD53vR52IZrLc+tylVJ/iR97rwHrfJDg13T5nlzfyFVb0p/I9yQ\nfsy29dirU/XI9B/wHJ+qT6TPn3lFkp9MHxd1q/RLlLMhBPqC7g1JnpXk5am6b5Ivpu//Q9Pn+Vuc\nJPoBSf4iVaemv0bfSP+RyyPSX6/5+VfPTj+mj07V1Un+I/094A1p7SvZMz0n/duep1XlZ9N/zHqz\n9DltfzjJMa3lP67hc2zRdqtPXL7WtvuK9C8JdtdvL5O5bFCVtWaDZPv/stTT0ocRPDnJfarygfQP\nCLdO/8b+YcmmgP609G9WX5jkcVX5WPq4/Vuk9/13S5839bzt3IZr07uqcln6t5TnJZuust09/RjP\n5iN/bHpue01VnpE+V+y308/7g9OP0T0zzQk6uWZ/qGK7fhKfPG2a9uOitjiv5eZ5GD+x5HH7tuTY\nlny59TnuvtiSF7Xkhi3595acu+QxD2zJx1vynWm9G1py4EKdX2t9Hs4LW3JVS77Sko+05Nkt+fG5\negdNj3/tek8psMbjvPXt7dOUXL2Vx796evzVLbnrNp7rIS15b0v+azqGF7Tkk63PfXr7hbobWnLi\nuh+fHbilT2GyIWmvTdpPJe1d6XPiXZa0jyTt/kse8/iknTFNAfGNpL0jaXeepuPYkLTDF+pvyDTV\nyZJ1HTdNl7E4d96GpP3xkvq/Ny07PUvm49ylb8mtW/Ke1qe6urrNphzr091saMmK/V14/P6tz7P7\nry25bOoDzm7J21rymLZ8SqK19QV7wm218z+5Q0vePZ3Ll7bktNbnGj5oRX/S6760JZ9uyddbn37s\nyy15a0vusWTdh07H9+K51/Twa20fd+A2f46vsnxr5+e/J+3chbK9k/ZnSTs7fZ7Bi5J2QtLut+Tx\nq57Lq61/btmvJe2D6dMWXZW0r0x90rOTtrTtJm3fqT+5PGk3uRaP6clJW9HWlh3L1frFrb02034c\nm7QvJ+2KpH0xaS9K2g1XeU2OypKpc7b1GiftRkn7w6Sdmc1TUH0uaX+ZtP0X6l4vaU9N2sfSp427\nMmnnTa/R06/N472Dr9GTkvbOpH1p2rcLk/aZ6T1kcUquvZL2nKSdlrTvTO3n3KS9L2lPzNxUTqsd\n66215cVb9QcAALuD6bLoSUne0Nra/wwt7EzbMwYTAFh/f5B+eXyn/SIYttf2TFMEAKyDqvx0+njB\nQ5M8KMl7W8vp67tVsDoBEwB2fYem/yGN7yR5a/qcpbDLMgYTAIChjMEEAGAoARMAgKEETAAAhhIw\nAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEE\nTAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAo\nARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAY\nSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAA\nhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMA\ngKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAE\nAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIw\nAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEE\nTAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAo\nARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAY\nSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAA\nhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMA\ngKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAE\nAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIw\nAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEE\nTAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAo\nARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAY\nSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAA\nhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMA\ngKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAE\nAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIw\nAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGAoARMAgKEETAAAhhIwAQAYSsAEAGCo/w+PEQc7\nVDsuewAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -534,7 +837,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.12" } }, "nbformat": 4, diff --git a/gensim/interfaces.py b/gensim/interfaces.py index e1024723b0..530fab398b 100644 --- a/gensim/interfaces.py +++ b/gensim/interfaces.py @@ -105,8 +105,10 @@ def save_corpus(fname, corpus, id2word=None, metadata=False): class TransformedCorpus(CorpusABC): - def __init__(self, obj, corpus, chunksize=None): + def __init__(self, obj, corpus, chunksize=None, **kwargs): self.obj, self.corpus, self.chunksize = obj, corpus, chunksize + for key, value in kwargs.items(): #add the new parameters like per_word_topics to base class object of LdaModel + setattr(self.obj, key, value) self.metadata = False def __len__(self): @@ -156,12 +158,12 @@ def __getitem__(self, vec): raise NotImplementedError('cannot instantiate abstract base class') - def _apply(self, corpus, chunksize=None): + def _apply(self, corpus, chunksize=None, **kwargs): """ Apply the transformation to a whole corpus (as opposed to a single document) and return the result as another corpus. """ - return TransformedCorpus(self, corpus, chunksize) + return TransformedCorpus(self, corpus, chunksize, **kwargs) #endclass TransformationABC diff --git a/gensim/models/ldamodel.py b/gensim/models/ldamodel.py index 7def8966b3..a3a91c669d 100755 --- a/gensim/models/ldamodel.py +++ b/gensim/models/ldamodel.py @@ -216,7 +216,8 @@ def __init__(self, corpus=None, num_topics=100, id2word=None, distributed=False, chunksize=2000, passes=1, update_every=1, alpha='symmetric', eta=None, decay=0.5, offset=1.0, eval_every=10, iterations=50, gamma_threshold=0.001, - minimum_probability=0.01, random_state=None, ns_conf={}): + minimum_probability=0.01, random_state=None, ns_conf={}, + minimum_phi_value=0.01, per_word_topics=False): """ If given, start training from the iterable `corpus` straight away. If not given, the model is left untrained (presumably because you want to call `update()` manually). @@ -297,6 +298,8 @@ def __init__(self, corpus=None, num_topics=100, id2word=None, self.passes = passes self.update_every = update_every self.eval_every = eval_every + self.minimum_phi_value = minimum_phi_value + self.per_word_topics = per_word_topics self.alpha, self.optimize_alpha = self.init_dir_prior(alpha, 'alpha') @@ -916,7 +919,12 @@ def get_document_topics(self, bow, minimum_probability=None, minimum_phi_value=N # if the input vector is a corpus, return a transformed corpus is_corpus, corpus = utils.is_corpus(bow) if is_corpus: - return self._apply(corpus) + kwargs = dict( + per_word_topics = per_word_topics, + minimum_probability = minimum_probability, + minimum_phi_value = minimum_phi_value + ) + return self._apply(corpus, **kwargs) gamma, phis = self.inference([bow], collect_sstats=True) topic_dist = gamma[0] / sum(gamma[0]) # normalize distribution @@ -977,7 +985,7 @@ def __getitem__(self, bow, eps=None): Ignore topics with very low probability (below `eps`). """ - return self.get_document_topics(bow, eps) + return self.get_document_topics(bow, eps, self.minimum_phi_value, self.per_word_topics) def save(self, fname, ignore=['state', 'dispatcher'], *args, **kwargs): """ diff --git a/gensim/models/ldamulticore.py b/gensim/models/ldamulticore.py index e7ab9c983c..e6cdd4ccec 100644 --- a/gensim/models/ldamulticore.py +++ b/gensim/models/ldamulticore.py @@ -80,7 +80,8 @@ class LdaMulticore(LdaModel): def __init__(self, corpus=None, num_topics=100, id2word=None, workers=None, chunksize=2000, passes=1, batch=False, alpha='symmetric', eta=None, decay=0.5, offset=1.0, eval_every=10, iterations=50, - gamma_threshold=0.001, random_state=None): + gamma_threshold=0.001, random_state=None, minimum_probability=0.01, + minimum_phi_value=0.01, per_word_topics=False): """ If given, start training from the iterable `corpus` straight away. If not given, the model is left untrained (presumably because you want to call `update()` manually). @@ -144,7 +145,8 @@ def __init__(self, corpus=None, num_topics=100, id2word=None, workers=None, super(LdaMulticore, self).__init__(corpus=corpus, num_topics=num_topics, id2word=id2word, chunksize=chunksize, passes=passes, alpha=alpha, eta=eta, decay=decay, offset=offset, eval_every=eval_every, iterations=iterations, - gamma_threshold=gamma_threshold, random_state=random_state) + gamma_threshold=gamma_threshold, random_state=random_state, minimum_probability= minimum_probability, + minimum_phi_value=minimum_phi_value, per_word_topics=per_word_topics) def update(self, corpus, chunks_as_numpy=False): diff --git a/gensim/test/test_ldamodel.py b/gensim/test/test_ldamodel.py index a96d96ae6f..faf846df5d 100644 --- a/gensim/test/test_ldamodel.py +++ b/gensim/test/test_ldamodel.py @@ -249,6 +249,55 @@ def testGetDocumentTopics(self): self.assertTrue(isinstance(k, int)) self.assertTrue(isinstance(v, float)) + #Test case to use the get_document_topic function for the corpus + all_topics = model.get_document_topics(self.corpus, per_word_topics=True) + + self.assertEqual(model.state.numdocs, len(corpus)) + + for topic in all_topics: + self.assertTrue(isinstance(topic, tuple)) + for k, v in topic[0]: # list of doc_topics + self.assertTrue(isinstance(k, int)) + self.assertTrue(isinstance(v, float)) + + for w, topic_list in topic[1]: # list of word_topics + self.assertTrue(isinstance(w, int)) + self.assertTrue(isinstance(topic_list, list)) + + for w, phi_values in topic[2]: # list of word_phis + self.assertTrue(isinstance(w, int)) + self.assertTrue(isinstance(phi_values, list)) + + #Test case to check the filtering effect of minimum_probability and minimum_phi_value + doc_topic_count_na = 0 + word_phi_count_na = 0 + + all_topics = model.get_document_topics(self.corpus, minimum_probability=0.8, minimum_phi_value=1.0, per_word_topics=True) + + self.assertEqual(model.state.numdocs, len(corpus)) + + for topic in all_topics: + self.assertTrue(isinstance(topic, tuple)) + for k, v in topic[0]: # list of doc_topics + self.assertTrue(isinstance(k, int)) + self.assertTrue(isinstance(v, float)) + if len(topic[0]) != 0: + doc_topic_count_na += 1 + + for w, topic_list in topic[1]: # list of word_topics + self.assertTrue(isinstance(w, int)) + self.assertTrue(isinstance(topic_list, list)) + + for w, phi_values in topic[2]: # list of word_phis + self.assertTrue(isinstance(w, int)) + self.assertTrue(isinstance(phi_values, list)) + if len(phi_values) != 0: + word_phi_count_na += 1 + + self.assertTrue(model.state.numdocs > doc_topic_count_na) + self.assertTrue( sum([len(i) for i in corpus]) > word_phi_count_na) + + doc_topics, word_topics, word_phis = model.get_document_topics(self.corpus[1], per_word_topics=True) for k, v in doc_topics: