Repository: piskvorky/gensim

Issue:
doc2vec's infer_vector has `epochs` and `steps` input parameters - `steps` not in use
Refer to doc2vec.py, `infer_vector` function seems to be using `epochs` for the number of iterations and `steps` is not in used.

However, in the `similarity_unseen_docs` function, `steps` is used when calling the infer_vector function.

![image](https://user-images.githubusercontent.com/62754326/119926239-9085d400-bfa9-11eb-838b-dae98da26c3f.png)



Discussion:
Yes, that's broken - `steps` is the older name for that parameter, & pre-4.0 would be accepted & copied into `epochs`. It looks like it's now just ignored by `infer_vector()`, thus this caller thinks it's doing the right thing, but isn't. The fix will be to:

* eliminate `steps` entirely from the signature of `infer_vector()` (as was intended) – & clean up comment language about `steps`
* correct `similarity_unseen_docs()` to use `epochs`
* check if any other code/comments/docs/examples still use outdated `steps` parameter or terminology, & correct

Resolving patch:
diff --git a/gensim/models/doc2vec.py b/gensim/models/doc2vec.py
--- a/gensim/models/doc2vec.py
+++ b/gensim/models/doc2vec.py
@@ -581,13 +581,13 @@ def estimated_lookup_memory(self):
         """
         return 60 * len(self.dv) + 140 * len(self.dv)
 
-    def infer_vector(self, doc_words, alpha=None, min_alpha=None, epochs=None, steps=None):
+    def infer_vector(self, doc_words, alpha=None, min_alpha=None, epochs=None):
         """Infer a vector for given post-bulk training document.
 
         Notes
         -----
         Subsequent calls to this function may infer different representations for the same document.
-        For a more stable representation, increase the number of steps to assert a stricket convergence.
+        For a more stable representation, increase the number of epochs to assert a stricter convergence.
 
         Parameters
         ----------
@@ -1047,7 +1047,7 @@ def scan_vocab(self, corpus_iterable=None, corpus_file=None, progress_per=10000,
 
         return total_words, corpus_count
 
-    def similarity_unseen_docs(self, doc_words1, doc_words2, alpha=None, min_alpha=None, steps=None):
+    def similarity_unseen_docs(self, doc_words1, doc_words2, alpha=None, min_alpha=None, epochs=None):
         """Compute cosine similarity between two post-bulk out of training documents.
 
         Parameters
@@ -1062,7 +1062,7 @@ def similarity_unseen_docs(self, doc_words1, doc_words2, alpha=None, min_alpha=N
             The initial learning rate.
         min_alpha : float, optional
             Learning rate will linearly drop to `min_alpha` as training progresses.
-        steps : int, optional
+        epochs : int, optional
             Number of epoch to train the new document.
 
         Returns
@@ -1071,8 +1071,8 @@ def similarity_unseen_docs(self, doc_words1, doc_words2, alpha=None, min_alpha=N
             The cosine similarity between `doc_words1` and `doc_words2`.
 
         """
-        d1 = self.infer_vector(doc_words=doc_words1, alpha=alpha, min_alpha=min_alpha, steps=steps)
-        d2 = self.infer_vector(doc_words=doc_words2, alpha=alpha, min_alpha=min_alpha, steps=steps)
+        d1 = self.infer_vector(doc_words=doc_words1, alpha=alpha, min_alpha=min_alpha, epochs=epochs)
+        d2 = self.infer_vector(doc_words=doc_words2, alpha=alpha, min_alpha=min_alpha, epochs=epochs)
         return np.dot(matutils.unitvec(d1), matutils.unitvec(d2))
 
 


Test patch:
diff --git a/gensim/test/test_doc2vec.py b/gensim/test/test_doc2vec.py
--- a/gensim/test/test_doc2vec.py
+++ b/gensim/test/test_doc2vec.py
@@ -718,8 +718,8 @@ def __str__(self):
     def epochs(self):
         return self.models[0].epochs
 
-    def infer_vector(self, document, alpha=None, min_alpha=None, epochs=None, steps=None):
-        return np.concatenate([model.infer_vector(document, alpha, min_alpha, epochs, steps) for model in self.models])
+    def infer_vector(self, document, alpha=None, min_alpha=None, epochs=None):
+        return np.concatenate([model.infer_vector(document, alpha, min_alpha, epochs) for model in self.models])
 
     def train(self, *ignore_args, **ignore_kwargs):
         pass  # train subcomponents individually