We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Wrong calculation for max_iter_dump
In
https://github.com/RaRe-Technologies/gensim/blob/develop/gensim/models/wrappers/wordrank.py#L144
Shouldnt this line `max_iter_dump = iter / dump_period * dump_period - 1` just be 
`max_iter_dump = iter - dump_period` ?

To reproduce try these parameters:
`model = Wordrank.train(wr_path, data, out_dir, iter=100, dump_period=5)`
It will error out with -
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ajkale/anaconda2/envs/wordrank/lib/python2.7/site-packages/gensim/models/wrappers/wordrank.py", line 146, in train
    copyfile('model_word_%d.txt' % max_iter_dump, 'wordrank.words')
  File "/home/ajkale/anaconda2/envs/wordrank/lib/python2.7/shutil.py", line 82, in copyfile
    with open(src, 'rb') as fsrc:
IOError: [Errno 2] No such file or directory: 'model_word_99.txt'
```

Mainly because `max_iter_dump = iter / dump_period * dump_period - 1`  calculates max_iter_dump=99 instead of 95.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gensim/models/wrappers/wordrank.py`
Content:
```
1 # Copyright (C) 2017 Parul Sethi <parul1sethi@gmail.com>
2 # Copyright (C) 2017 Radim Rehurek <me@radimrehurek.com>
3 # Licensed under the GNU LGPL v2.1 - http://www.gnu.org/licenses/lgpl.html
4 
5 """
6 Python wrapper around word representation learning from Wordrank.
7 The wrapped model can NOT be updated with new documents for online training -- use gensim's
8 `Word2Vec` for that.
9 
10 Example:
11 >>> model = gensim.models.wrappers.Wordrank('/Users/dummy/wordrank', corpus_file='text8', out_path='wr_model')
12 >>> print model[word]  # prints vector for given words
13 
14 .. [1] https://bitbucket.org/shihaoji/wordrank/
15 .. [2] https://arxiv.org/pdf/1506.02761v3.pdf
16 """
17 
18 from __future__ import division
19 
20 import logging
21 import os
22 import sys
23 import copy
24 import multiprocessing
25 
26 import numpy as np
27 
28 from gensim import utils
29 from gensim.models.keyedvectors import KeyedVectors
30 from gensim.scripts.glove2word2vec import glove2word2vec
31 
32 from six import string_types
33 from smart_open import smart_open
34 from shutil import copyfile, rmtree
35 
36 
37 logger = logging.getLogger(__name__)
38 
39 
40 class Wordrank(KeyedVectors):
41     """
42     Class for word vector training using Wordrank. Communication between Wordrank and Python
43     takes place by working with data files on disk and calling the Wordrank binary and glove's
44     helper binaries (for preparing training data) with subprocess module.
45     """
46     
47     @classmethod
48     def train(cls, wr_path, corpus_file, out_path, size=100, window=15, symmetric=1, min_count=5, max_vocab_size=0,
49               sgd_num=100, lrate=0.001, period=10, iter=91, epsilon=0.75, dump_period=10, reg=0, alpha=100,
50               beta=99, loss='hinge', memory=4.0, cleanup_files=True, sorted_vocab=1, ensemble=0):
51         """
52         `wr_path` is the path to the Wordrank directory.
53         `corpus_file` is the filename of the text file to be used for training the Wordrank model.
54         Expects file to contain space-separated tokens in a single line
55         `out_path` is the path to directory which will be created to save embeddings and training data.
56         `size` is the dimensionality of the feature vectors.
57         `window` is the number of context words to the left (and to the right, if symmetric = 1).
58         `symmetric` if 0, only use left context words, else use left and right both.
59         `min_count` = ignore all words with total frequency lower than this.
60         `max_vocab_size` upper bound on vocabulary size, i.e. keep the <int> most frequent words. Default is 0 for no limit.
61         `sgd_num` number of SGD taken for each data point.
62         `lrate` is the learning rate (too high diverges, give Nan).
63         `period` is the period of xi variable updates
64         `iter` = number of iterations (epochs) over the corpus.
65         `epsilon` is the power scaling value for weighting function.
66         `dump_period` is the period after which embeddings should be dumped.
67         `reg` is the value of regularization parameter.
68         `alpha` is the alpha parameter of gamma distribution.
69         `beta` is the beta parameter of gamma distribution.
70         `loss` = name of the loss (logistic, hinge).
71         `memory` = soft limit for memory consumption, in GB.
72         `cleanup_files` if True, delete directory and files used by this wrapper, setting to False can be useful for debugging
73         `sorted_vocab` = if 1 (default), sort the vocabulary by descending frequency before assigning word indexes.
74         `ensemble` = 0 (default), use ensemble of word and context vectors
75         """
76 
77         meta_data_path = 'matrix.meta'
78         vocab_file = 'vocab.txt'
79         temp_vocab_file = 'tempvocab.txt'
80         cooccurrence_file = 'cooccurrence'
81         cooccurrence_shuf_file = 'wiki.toy'
82         meta_file = 'meta'
83 
84         # prepare training data (cooccurrence matrix and vocab)
85         model_dir = os.path.join(wr_path, out_path)
86         meta_dir = os.path.join(model_dir, 'meta')
87         os.makedirs(meta_dir)
88         logger.info("Dumped data will be stored in '%s'", model_dir)
89         copyfile(corpus_file, os.path.join(meta_dir, corpus_file.split('/')[-1]))
90         os.chdir(meta_dir)
91 
92         cmd_vocab_count = ['../../glove/vocab_count', '-min-count', str(min_count), '-max-vocab', str(max_vocab_size)]
93         cmd_cooccurence_count = ['../../glove/cooccur', '-memory', str(memory), '-vocab-file', temp_vocab_file, '-window-size', str(window), '-symmetric', str(symmetric)]
94         cmd_shuffle_cooccurences = ['../../glove/shuffle', '-memory', str(memory)]
95         cmd_del_vocab_freq = ['cut', '-d', " ", '-f', '1', temp_vocab_file]
96 
97         commands = [cmd_vocab_count, cmd_cooccurence_count, cmd_shuffle_cooccurences]
98         logger.info("Prepare training data using glove code '%s'", commands)
99         input_fnames = [corpus_file.split('/')[-1], corpus_file.split('/')[-1], cooccurrence_file]
100         output_fnames = [temp_vocab_file, cooccurrence_file, cooccurrence_shuf_file]
101 
102         for command, input_fname, output_fname in zip(commands, input_fnames, output_fnames):
103             with smart_open(input_fname, 'rb') as r:
104                 with smart_open(output_fname, 'wb') as w:
105                     utils.check_output(w, args=command, stdin=r)
106         with smart_open(vocab_file, 'wb') as w:
107             utils.check_output(w, args=cmd_del_vocab_freq)
108 
109         with smart_open(vocab_file, 'rb') as f:
110             numwords = sum(1 for line in f)
111         with smart_open(cooccurrence_shuf_file, 'rb') as f:
112             numlines = sum(1 for line in f)
113         with smart_open(meta_file, 'wb') as f:
114             meta_info = "{0} {1}\n{2} {3}\n{4} {5}".format(numwords, numwords, numlines, cooccurrence_shuf_file, numwords, vocab_file)
115             f.write(meta_info.encode('utf-8'))
116 
117         wr_args = {
118             'path': 'meta',
119             'nthread': multiprocessing.cpu_count(),
120             'sgd_num': sgd_num,
121             'lrate': lrate,
122             'period': period,
123             'iter': iter,
124             'epsilon': epsilon,
125             'dump_prefix': 'model',
126             'dump_period': dump_period,
127             'dim': size,
128             'reg': reg,
129             'alpha': alpha,
130             'beta': beta,
131             'loss': loss
132         }
133 
134         os.chdir('..')
135         # run wordrank executable with wr_args
136         cmd = ['mpirun', '-np', '1', '../wordrank']
137         for option, value in wr_args.items():
138             cmd.append("--%s" % option)
139             cmd.append(str(value))
140         logger.info("Running wordrank binary '%s'", cmd)
141         output = utils.check_output(args=cmd)
142 
143         # use embeddings from max. iteration's dump
144         max_iter_dump = iter / dump_period * dump_period - 1
145         copyfile('model_word_%d.txt' % max_iter_dump, 'wordrank.words')
146         copyfile('model_context_%d.txt' % max_iter_dump, 'wordrank.contexts')
147         model = cls.load_wordrank_model('wordrank.words', os.path.join('meta', vocab_file), 'wordrank.contexts', sorted_vocab, ensemble)
148         os.chdir('../..')
149 
150         if cleanup_files:
151             rmtree(model_dir)
152         return model
153 
154     @classmethod
155     def load_wordrank_model(cls, model_file, vocab_file=None, context_file=None, sorted_vocab=1, ensemble=1):
156         glove2word2vec(model_file, model_file+'.w2vformat')
157         model = cls.load_word2vec_format('%s.w2vformat' % model_file)
158         if ensemble and context_file:
159             model.ensemble_embedding(model_file, context_file)
160         if sorted_vocab and vocab_file:
161             model.sort_embeddings(vocab_file)
162         return model
163 
164     def sort_embeddings(self, vocab_file):
165         """Sort embeddings according to word frequency."""
166         counts = {}
167         vocab_size = len(self.vocab)
168         prev_syn0 = copy.deepcopy(self.syn0)
169         prev_vocab = copy.deepcopy(self.vocab)
170         self.index2word = []
171 
172         # sort embeddings using frequency sorted vocab file in wordrank
173         with utils.smart_open(vocab_file) as fin:
174             for index, line in enumerate(fin):
175                 word, count = utils.to_unicode(line).strip(), vocab_size - index
176                 # store word with it's count in a dict
177                 counts[word] = int(count)
178                 # build new index2word with frequency sorted words
179                 self.index2word.append(word)
180         assert len(self.index2word) == vocab_size, 'mismatch between vocab sizes'
181 
182         for word_id, word in enumerate(self.index2word):
183             self.syn0[word_id] = prev_syn0[prev_vocab[word].index]
184             self.vocab[word].index = word_id
185             self.vocab[word].count = counts[word]
186 
187     def ensemble_embedding(self, word_embedding, context_embedding):
188         """Replace syn0 with the sum of context and word embeddings."""
189         glove2word2vec(context_embedding, context_embedding+'.w2vformat')
190         w_emb = KeyedVectors.load_word2vec_format('%s.w2vformat' % word_embedding)
191         c_emb = KeyedVectors.load_word2vec_format('%s.w2vformat' % context_embedding)
192         # compare vocab words using keys of dict vocab
193         assert set(w_emb.vocab) == set(c_emb.vocab), 'Vocabs are not same for both embeddings'
194 
195         # sort context embedding to have words in same order as word embedding
196         prev_c_emb = copy.deepcopy(c_emb.syn0)
197         for word_id, word in enumerate(w_emb.index2word):
198             c_emb.syn0[word_id] = prev_c_emb[c_emb.vocab[word].index]
199         # add vectors of the two embeddings
200         new_emb = w_emb.syn0 + c_emb.syn0
201         self.syn0 = new_emb
202         return new_emb
203 
204
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gensim/models/wrappers/wordrank.py b/gensim/models/wrappers/wordrank.py
--- a/gensim/models/wrappers/wordrank.py
+++ b/gensim/models/wrappers/wordrank.py
@@ -46,7 +46,7 @@
     
     @classmethod
     def train(cls, wr_path, corpus_file, out_path, size=100, window=15, symmetric=1, min_count=5, max_vocab_size=0,
-              sgd_num=100, lrate=0.001, period=10, iter=91, epsilon=0.75, dump_period=10, reg=0, alpha=100,
+              sgd_num=100, lrate=0.001, period=10, iter=90, epsilon=0.75, dump_period=10, reg=0, alpha=100,
               beta=99, loss='hinge', memory=4.0, cleanup_files=True, sorted_vocab=1, ensemble=0):
         """
         `wr_path` is the path to the Wordrank directory.
@@ -113,6 +113,11 @@
         with smart_open(meta_file, 'wb') as f:
             meta_info = "{0} {1}\n{2} {3}\n{4} {5}".format(numwords, numwords, numlines, cooccurrence_shuf_file, numwords, vocab_file)
             f.write(meta_info.encode('utf-8'))
+            
+        if iter % dump_period == 0:
+            iter += 1
+        else:
+            logger.warning('Resultant embedding would be from %d iteration', iter - iter % dump_period)
 
         wr_args = {
             'path': 'meta',
@@ -141,7 +146,7 @@
         output = utils.check_output(args=cmd)
 
         # use embeddings from max. iteration's dump
-        max_iter_dump = iter / dump_period * dump_period - 1
+        max_iter_dump = iter - iter % dump_period
         copyfile('model_word_%d.txt' % max_iter_dump, 'wordrank.words')
         copyfile('model_context_%d.txt' % max_iter_dump, 'wordrank.contexts')
         model = cls.load_wordrank_model('wordrank.words', os.path.join('meta', vocab_file), 'wordrank.contexts', sorted_vocab, ensemble)

{"golden_diff": "diff --git a/gensim/models/wrappers/wordrank.py b/gensim/models/wrappers/wordrank.py\n--- a/gensim/models/wrappers/wordrank.py\n+++ b/gensim/models/wrappers/wordrank.py\n@@ -46,7 +46,7 @@\n     \n     @classmethod\n     def train(cls, wr_path, corpus_file, out_path, size=100, window=15, symmetric=1, min_count=5, max_vocab_size=0,\n-              sgd_num=100, lrate=0.001, period=10, iter=91, epsilon=0.75, dump_period=10, reg=0, alpha=100,\n+              sgd_num=100, lrate=0.001, period=10, iter=90, epsilon=0.75, dump_period=10, reg=0, alpha=100,\n               beta=99, loss='hinge', memory=4.0, cleanup_files=True, sorted_vocab=1, ensemble=0):\n         \"\"\"\n         `wr_path` is the path to the Wordrank directory.\n@@ -113,6 +113,11 @@\n         with smart_open(meta_file, 'wb') as f:\n             meta_info = \"{0} {1}\\n{2} {3}\\n{4} {5}\".format(numwords, numwords, numlines, cooccurrence_shuf_file, numwords, vocab_file)\n             f.write(meta_info.encode('utf-8'))\n+            \n+        if iter % dump_period == 0:\n+            iter += 1\n+        else:\n+            logger.warning('Resultant embedding would be from %d iteration', iter - iter % dump_period)\n \n         wr_args = {\n             'path': 'meta',\n@@ -141,7 +146,7 @@\n         output = utils.check_output(args=cmd)\n \n         # use embeddings from max. iteration's dump\n-        max_iter_dump = iter / dump_period * dump_period - 1\n+        max_iter_dump = iter - iter % dump_period\n         copyfile('model_word_%d.txt' % max_iter_dump, 'wordrank.words')\n         copyfile('model_context_%d.txt' % max_iter_dump, 'wordrank.contexts')\n         model = cls.load_wordrank_model('wordrank.words', os.path.join('meta', vocab_file), 'wordrank.contexts', sorted_vocab, ensemble)\n", "issue": "Wrong calculation for max_iter_dump\nIn\r\nhttps://github.com/RaRe-Technologies/gensim/blob/develop/gensim/models/wrappers/wordrank.py#L144\r\nShouldnt this line `max_iter_dump = iter / dump_period * dump_period - 1` just be \r\n`max_iter_dump = iter - dump_period` ?\r\n\r\nTo reproduce try these parameters:\r\n`model = Wordrank.train(wr_path, data, out_dir, iter=100, dump_period=5)`\r\nIt will error out with -\r\n```\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/home/ajkale/anaconda2/envs/wordrank/lib/python2.7/site-packages/gensim/models/wrappers/wordrank.py\", line 146, in train\r\n    copyfile('model_word_%d.txt' % max_iter_dump, 'wordrank.words')\r\n  File \"/home/ajkale/anaconda2/envs/wordrank/lib/python2.7/shutil.py\", line 82, in copyfile\r\n    with open(src, 'rb') as fsrc:\r\nIOError: [Errno 2] No such file or directory: 'model_word_99.txt'\r\n```\r\n\r\nMainly because `max_iter_dump = iter / dump_period * dump_period - 1`  calculates max_iter_dump=99 instead of 95.\n", "before_files": [{"content": "# Copyright (C) 2017 Parul Sethi <parul1sethi@gmail.com>\n# Copyright (C) 2017 Radim Rehurek <me@radimrehurek.com>\n# Licensed under the GNU LGPL v2.1 - http://www.gnu.org/licenses/lgpl.html\n\n\"\"\"\nPython wrapper around word representation learning from Wordrank.\nThe wrapped model can NOT be updated with new documents for online training -- use gensim's\n`Word2Vec` for that.\n\nExample:\n>>> model = gensim.models.wrappers.Wordrank('/Users/dummy/wordrank', corpus_file='text8', out_path='wr_model')\n>>> print model[word]  # prints vector for given words\n\n.. [1] https://bitbucket.org/shihaoji/wordrank/\n.. [2] https://arxiv.org/pdf/1506.02761v3.pdf\n\"\"\"\n\nfrom __future__ import division\n\nimport logging\nimport os\nimport sys\nimport copy\nimport multiprocessing\n\nimport numpy as np\n\nfrom gensim import utils\nfrom gensim.models.keyedvectors import KeyedVectors\nfrom gensim.scripts.glove2word2vec import glove2word2vec\n\nfrom six import string_types\nfrom smart_open import smart_open\nfrom shutil import copyfile, rmtree\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass Wordrank(KeyedVectors):\n    \"\"\"\n    Class for word vector training using Wordrank. Communication between Wordrank and Python\n    takes place by working with data files on disk and calling the Wordrank binary and glove's\n    helper binaries (for preparing training data) with subprocess module.\n    \"\"\"\n    \n    @classmethod\n    def train(cls, wr_path, corpus_file, out_path, size=100, window=15, symmetric=1, min_count=5, max_vocab_size=0,\n              sgd_num=100, lrate=0.001, period=10, iter=91, epsilon=0.75, dump_period=10, reg=0, alpha=100,\n              beta=99, loss='hinge', memory=4.0, cleanup_files=True, sorted_vocab=1, ensemble=0):\n        \"\"\"\n        `wr_path` is the path to the Wordrank directory.\n        `corpus_file` is the filename of the text file to be used for training the Wordrank model.\n        Expects file to contain space-separated tokens in a single line\n        `out_path` is the path to directory which will be created to save embeddings and training data.\n        `size` is the dimensionality of the feature vectors.\n        `window` is the number of context words to the left (and to the right, if symmetric = 1).\n        `symmetric` if 0, only use left context words, else use left and right both.\n        `min_count` = ignore all words with total frequency lower than this.\n        `max_vocab_size` upper bound on vocabulary size, i.e. keep the <int> most frequent words. Default is 0 for no limit.\n        `sgd_num` number of SGD taken for each data point.\n        `lrate` is the learning rate (too high diverges, give Nan).\n        `period` is the period of xi variable updates\n        `iter` = number of iterations (epochs) over the corpus.\n        `epsilon` is the power scaling value for weighting function.\n        `dump_period` is the period after which embeddings should be dumped.\n        `reg` is the value of regularization parameter.\n        `alpha` is the alpha parameter of gamma distribution.\n        `beta` is the beta parameter of gamma distribution.\n        `loss` = name of the loss (logistic, hinge).\n        `memory` = soft limit for memory consumption, in GB.\n        `cleanup_files` if True, delete directory and files used by this wrapper, setting to False can be useful for debugging\n        `sorted_vocab` = if 1 (default), sort the vocabulary by descending frequency before assigning word indexes.\n        `ensemble` = 0 (default), use ensemble of word and context vectors\n        \"\"\"\n\n        meta_data_path = 'matrix.meta'\n        vocab_file = 'vocab.txt'\n        temp_vocab_file = 'tempvocab.txt'\n        cooccurrence_file = 'cooccurrence'\n        cooccurrence_shuf_file = 'wiki.toy'\n        meta_file = 'meta'\n\n        # prepare training data (cooccurrence matrix and vocab)\n        model_dir = os.path.join(wr_path, out_path)\n        meta_dir = os.path.join(model_dir, 'meta')\n        os.makedirs(meta_dir)\n        logger.info(\"Dumped data will be stored in '%s'\", model_dir)\n        copyfile(corpus_file, os.path.join(meta_dir, corpus_file.split('/')[-1]))\n        os.chdir(meta_dir)\n\n        cmd_vocab_count = ['../../glove/vocab_count', '-min-count', str(min_count), '-max-vocab', str(max_vocab_size)]\n        cmd_cooccurence_count = ['../../glove/cooccur', '-memory', str(memory), '-vocab-file', temp_vocab_file, '-window-size', str(window), '-symmetric', str(symmetric)]\n        cmd_shuffle_cooccurences = ['../../glove/shuffle', '-memory', str(memory)]\n        cmd_del_vocab_freq = ['cut', '-d', \" \", '-f', '1', temp_vocab_file]\n\n        commands = [cmd_vocab_count, cmd_cooccurence_count, cmd_shuffle_cooccurences]\n        logger.info(\"Prepare training data using glove code '%s'\", commands)\n        input_fnames = [corpus_file.split('/')[-1], corpus_file.split('/')[-1], cooccurrence_file]\n        output_fnames = [temp_vocab_file, cooccurrence_file, cooccurrence_shuf_file]\n\n        for command, input_fname, output_fname in zip(commands, input_fnames, output_fnames):\n            with smart_open(input_fname, 'rb') as r:\n                with smart_open(output_fname, 'wb') as w:\n                    utils.check_output(w, args=command, stdin=r)\n        with smart_open(vocab_file, 'wb') as w:\n            utils.check_output(w, args=cmd_del_vocab_freq)\n\n        with smart_open(vocab_file, 'rb') as f:\n            numwords = sum(1 for line in f)\n        with smart_open(cooccurrence_shuf_file, 'rb') as f:\n            numlines = sum(1 for line in f)\n        with smart_open(meta_file, 'wb') as f:\n            meta_info = \"{0} {1}\\n{2} {3}\\n{4} {5}\".format(numwords, numwords, numlines, cooccurrence_shuf_file, numwords, vocab_file)\n            f.write(meta_info.encode('utf-8'))\n\n        wr_args = {\n            'path': 'meta',\n            'nthread': multiprocessing.cpu_count(),\n            'sgd_num': sgd_num,\n            'lrate': lrate,\n            'period': period,\n            'iter': iter,\n            'epsilon': epsilon,\n            'dump_prefix': 'model',\n            'dump_period': dump_period,\n            'dim': size,\n            'reg': reg,\n            'alpha': alpha,\n            'beta': beta,\n            'loss': loss\n        }\n\n        os.chdir('..')\n        # run wordrank executable with wr_args\n        cmd = ['mpirun', '-np', '1', '../wordrank']\n        for option, value in wr_args.items():\n            cmd.append(\"--%s\" % option)\n            cmd.append(str(value))\n        logger.info(\"Running wordrank binary '%s'\", cmd)\n        output = utils.check_output(args=cmd)\n\n        # use embeddings from max. iteration's dump\n        max_iter_dump = iter / dump_period * dump_period - 1\n        copyfile('model_word_%d.txt' % max_iter_dump, 'wordrank.words')\n        copyfile('model_context_%d.txt' % max_iter_dump, 'wordrank.contexts')\n        model = cls.load_wordrank_model('wordrank.words', os.path.join('meta', vocab_file), 'wordrank.contexts', sorted_vocab, ensemble)\n        os.chdir('../..')\n\n        if cleanup_files:\n            rmtree(model_dir)\n        return model\n\n    @classmethod\n    def load_wordrank_model(cls, model_file, vocab_file=None, context_file=None, sorted_vocab=1, ensemble=1):\n        glove2word2vec(model_file, model_file+'.w2vformat')\n        model = cls.load_word2vec_format('%s.w2vformat' % model_file)\n        if ensemble and context_file:\n            model.ensemble_embedding(model_file, context_file)\n        if sorted_vocab and vocab_file:\n            model.sort_embeddings(vocab_file)\n        return model\n\n    def sort_embeddings(self, vocab_file):\n        \"\"\"Sort embeddings according to word frequency.\"\"\"\n        counts = {}\n        vocab_size = len(self.vocab)\n        prev_syn0 = copy.deepcopy(self.syn0)\n        prev_vocab = copy.deepcopy(self.vocab)\n        self.index2word = []\n\n        # sort embeddings using frequency sorted vocab file in wordrank\n        with utils.smart_open(vocab_file) as fin:\n            for index, line in enumerate(fin):\n                word, count = utils.to_unicode(line).strip(), vocab_size - index\n                # store word with it's count in a dict\n                counts[word] = int(count)\n                # build new index2word with frequency sorted words\n                self.index2word.append(word)\n        assert len(self.index2word) == vocab_size, 'mismatch between vocab sizes'\n\n        for word_id, word in enumerate(self.index2word):\n            self.syn0[word_id] = prev_syn0[prev_vocab[word].index]\n            self.vocab[word].index = word_id\n            self.vocab[word].count = counts[word]\n\n    def ensemble_embedding(self, word_embedding, context_embedding):\n        \"\"\"Replace syn0 with the sum of context and word embeddings.\"\"\"\n        glove2word2vec(context_embedding, context_embedding+'.w2vformat')\n        w_emb = KeyedVectors.load_word2vec_format('%s.w2vformat' % word_embedding)\n        c_emb = KeyedVectors.load_word2vec_format('%s.w2vformat' % context_embedding)\n        # compare vocab words using keys of dict vocab\n        assert set(w_emb.vocab) == set(c_emb.vocab), 'Vocabs are not same for both embeddings'\n\n        # sort context embedding to have words in same order as word embedding\n        prev_c_emb = copy.deepcopy(c_emb.syn0)\n        for word_id, word in enumerate(w_emb.index2word):\n            c_emb.syn0[word_id] = prev_c_emb[c_emb.vocab[word].index]\n        # add vectors of the two embeddings\n        new_emb = w_emb.syn0 + c_emb.syn0\n        self.syn0 = new_emb\n        return new_emb\n\n", "path": "gensim/models/wrappers/wordrank.py"}], "after_files": [{"content": "# Copyright (C) 2017 Parul Sethi <parul1sethi@gmail.com>\n# Copyright (C) 2017 Radim Rehurek <me@radimrehurek.com>\n# Licensed under the GNU LGPL v2.1 - http://www.gnu.org/licenses/lgpl.html\n\n\"\"\"\nPython wrapper around word representation learning from Wordrank.\nThe wrapped model can NOT be updated with new documents for online training -- use gensim's\n`Word2Vec` for that.\n\nExample:\n>>> model = gensim.models.wrappers.Wordrank('/Users/dummy/wordrank', corpus_file='text8', out_path='wr_model')\n>>> print model[word]  # prints vector for given words\n\n.. [1] https://bitbucket.org/shihaoji/wordrank/\n.. [2] https://arxiv.org/pdf/1506.02761v3.pdf\n\"\"\"\n\nfrom __future__ import division\n\nimport logging\nimport os\nimport sys\nimport copy\nimport multiprocessing\n\nimport numpy as np\n\nfrom gensim import utils\nfrom gensim.models.keyedvectors import KeyedVectors\nfrom gensim.scripts.glove2word2vec import glove2word2vec\n\nfrom six import string_types\nfrom smart_open import smart_open\nfrom shutil import copyfile, rmtree\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass Wordrank(KeyedVectors):\n    \"\"\"\n    Class for word vector training using Wordrank. Communication between Wordrank and Python\n    takes place by working with data files on disk and calling the Wordrank binary and glove's\n    helper binaries (for preparing training data) with subprocess module.\n    \"\"\"\n    \n    @classmethod\n    def train(cls, wr_path, corpus_file, out_path, size=100, window=15, symmetric=1, min_count=5, max_vocab_size=0,\n              sgd_num=100, lrate=0.001, period=10, iter=90, epsilon=0.75, dump_period=10, reg=0, alpha=100,\n              beta=99, loss='hinge', memory=4.0, cleanup_files=True, sorted_vocab=1, ensemble=0):\n        \"\"\"\n        `wr_path` is the path to the Wordrank directory.\n        `corpus_file` is the filename of the text file to be used for training the Wordrank model.\n        Expects file to contain space-separated tokens in a single line\n        `out_path` is the path to directory which will be created to save embeddings and training data.\n        `size` is the dimensionality of the feature vectors.\n        `window` is the number of context words to the left (and to the right, if symmetric = 1).\n        `symmetric` if 0, only use left context words, else use left and right both.\n        `min_count` = ignore all words with total frequency lower than this.\n        `max_vocab_size` upper bound on vocabulary size, i.e. keep the <int> most frequent words. Default is 0 for no limit.\n        `sgd_num` number of SGD taken for each data point.\n        `lrate` is the learning rate (too high diverges, give Nan).\n        `period` is the period of xi variable updates\n        `iter` = number of iterations (epochs) over the corpus.\n        `epsilon` is the power scaling value for weighting function.\n        `dump_period` is the period after which embeddings should be dumped.\n        `reg` is the value of regularization parameter.\n        `alpha` is the alpha parameter of gamma distribution.\n        `beta` is the beta parameter of gamma distribution.\n        `loss` = name of the loss (logistic, hinge).\n        `memory` = soft limit for memory consumption, in GB.\n        `cleanup_files` if True, delete directory and files used by this wrapper, setting to False can be useful for debugging\n        `sorted_vocab` = if 1 (default), sort the vocabulary by descending frequency before assigning word indexes.\n        `ensemble` = 0 (default), use ensemble of word and context vectors\n        \"\"\"\n\n        meta_data_path = 'matrix.meta'\n        vocab_file = 'vocab.txt'\n        temp_vocab_file = 'tempvocab.txt'\n        cooccurrence_file = 'cooccurrence'\n        cooccurrence_shuf_file = 'wiki.toy'\n        meta_file = 'meta'\n\n        # prepare training data (cooccurrence matrix and vocab)\n        model_dir = os.path.join(wr_path, out_path)\n        meta_dir = os.path.join(model_dir, 'meta')\n        os.makedirs(meta_dir)\n        logger.info(\"Dumped data will be stored in '%s'\", model_dir)\n        copyfile(corpus_file, os.path.join(meta_dir, corpus_file.split('/')[-1]))\n        os.chdir(meta_dir)\n\n        cmd_vocab_count = ['../../glove/vocab_count', '-min-count', str(min_count), '-max-vocab', str(max_vocab_size)]\n        cmd_cooccurence_count = ['../../glove/cooccur', '-memory', str(memory), '-vocab-file', temp_vocab_file, '-window-size', str(window), '-symmetric', str(symmetric)]\n        cmd_shuffle_cooccurences = ['../../glove/shuffle', '-memory', str(memory)]\n        cmd_del_vocab_freq = ['cut', '-d', \" \", '-f', '1', temp_vocab_file]\n\n        commands = [cmd_vocab_count, cmd_cooccurence_count, cmd_shuffle_cooccurences]\n        logger.info(\"Prepare training data using glove code '%s'\", commands)\n        input_fnames = [corpus_file.split('/')[-1], corpus_file.split('/')[-1], cooccurrence_file]\n        output_fnames = [temp_vocab_file, cooccurrence_file, cooccurrence_shuf_file]\n\n        for command, input_fname, output_fname in zip(commands, input_fnames, output_fnames):\n            with smart_open(input_fname, 'rb') as r:\n                with smart_open(output_fname, 'wb') as w:\n                    utils.check_output(w, args=command, stdin=r)\n        with smart_open(vocab_file, 'wb') as w:\n            utils.check_output(w, args=cmd_del_vocab_freq)\n\n        with smart_open(vocab_file, 'rb') as f:\n            numwords = sum(1 for line in f)\n        with smart_open(cooccurrence_shuf_file, 'rb') as f:\n            numlines = sum(1 for line in f)\n        with smart_open(meta_file, 'wb') as f:\n            meta_info = \"{0} {1}\\n{2} {3}\\n{4} {5}\".format(numwords, numwords, numlines, cooccurrence_shuf_file, numwords, vocab_file)\n            f.write(meta_info.encode('utf-8'))\n            \n        if iter % dump_period == 0:\n            iter += 1\n        else:\n            logger.warning('Resultant embedding would be from %d iteration', iter - iter % dump_period)\n\n        wr_args = {\n            'path': 'meta',\n            'nthread': multiprocessing.cpu_count(),\n            'sgd_num': sgd_num,\n            'lrate': lrate,\n            'period': period,\n            'iter': iter,\n            'epsilon': epsilon,\n            'dump_prefix': 'model',\n            'dump_period': dump_period,\n            'dim': size,\n            'reg': reg,\n            'alpha': alpha,\n            'beta': beta,\n            'loss': loss\n        }\n\n        os.chdir('..')\n        # run wordrank executable with wr_args\n        cmd = ['mpirun', '-np', '1', '../wordrank']\n        for option, value in wr_args.items():\n            cmd.append(\"--%s\" % option)\n            cmd.append(str(value))\n        logger.info(\"Running wordrank binary '%s'\", cmd)\n        output = utils.check_output(args=cmd)\n\n        # use embeddings from max. iteration's dump\n        max_iter_dump = iter - iter % dump_period\n        copyfile('model_word_%d.txt' % max_iter_dump, 'wordrank.words')\n        copyfile('model_context_%d.txt' % max_iter_dump, 'wordrank.contexts')\n        model = cls.load_wordrank_model('wordrank.words', os.path.join('meta', vocab_file), 'wordrank.contexts', sorted_vocab, ensemble)\n        os.chdir('../..')\n\n        if cleanup_files:\n            rmtree(model_dir)\n        return model\n\n    @classmethod\n    def load_wordrank_model(cls, model_file, vocab_file=None, context_file=None, sorted_vocab=1, ensemble=1):\n        glove2word2vec(model_file, model_file+'.w2vformat')\n        model = cls.load_word2vec_format('%s.w2vformat' % model_file)\n        if ensemble and context_file:\n            model.ensemble_embedding(model_file, context_file)\n        if sorted_vocab and vocab_file:\n            model.sort_embeddings(vocab_file)\n        return model\n\n    def sort_embeddings(self, vocab_file):\n        \"\"\"Sort embeddings according to word frequency.\"\"\"\n        counts = {}\n        vocab_size = len(self.vocab)\n        prev_syn0 = copy.deepcopy(self.syn0)\n        prev_vocab = copy.deepcopy(self.vocab)\n        self.index2word = []\n\n        # sort embeddings using frequency sorted vocab file in wordrank\n        with utils.smart_open(vocab_file) as fin:\n            for index, line in enumerate(fin):\n                word, count = utils.to_unicode(line).strip(), vocab_size - index\n                # store word with it's count in a dict\n                counts[word] = int(count)\n                # build new index2word with frequency sorted words\n                self.index2word.append(word)\n        assert len(self.index2word) == vocab_size, 'mismatch between vocab sizes'\n\n        for word_id, word in enumerate(self.index2word):\n            self.syn0[word_id] = prev_syn0[prev_vocab[word].index]\n            self.vocab[word].index = word_id\n            self.vocab[word].count = counts[word]\n\n    def ensemble_embedding(self, word_embedding, context_embedding):\n        \"\"\"Replace syn0 with the sum of context and word embeddings.\"\"\"\n        glove2word2vec(context_embedding, context_embedding+'.w2vformat')\n        w_emb = KeyedVectors.load_word2vec_format('%s.w2vformat' % word_embedding)\n        c_emb = KeyedVectors.load_word2vec_format('%s.w2vformat' % context_embedding)\n        # compare vocab words using keys of dict vocab\n        assert set(w_emb.vocab) == set(c_emb.vocab), 'Vocabs are not same for both embeddings'\n\n        # sort context embedding to have words in same order as word embedding\n        prev_c_emb = copy.deepcopy(c_emb.syn0)\n        for word_id, word in enumerate(w_emb.index2word):\n            c_emb.syn0[word_id] = prev_c_emb[c_emb.vocab[word].index]\n        # add vectors of the two embeddings\n        new_emb = w_emb.syn0 + c_emb.syn0\n        self.syn0 = new_emb\n        return new_emb\n\n", "path": "gensim/models/wrappers/wordrank.py"}]}