Gensim has a built in functionality to find similar words, using Word2vec. You can train a Word2Vec model using gensim:
model = Word2Vec(sentences, size=100, window=5, min_count=5, workers=4)
You can make use of the most_similar
function to find the top n similar words. It allows you to input a list of positive and negative words to tackle the 'good' and 'bad' problem. You can play around with it.
model.most_similar(positive=[], negative=[], topn=10, restrict_vocab=None)
An example, provided in the documentation:
model.most_similar(positive=['woman', 'king'], negative=['man'], topn=10, restrict_vocab=None)
[('queen', 0.50882536), ...]
topn = the number of nearest neighbors you want to the input combination list of positive and negative words.
restrict_vocab = an optional integer which limits the range of vectors which are searched for most-similar values. For example, restrict_vocab=10000 would only check the first 10000 word vectors in the vocabulary order. (This may be meaningful if you’ve sorted the vocabulary by descending frequency.)
Here is the link to the documentation of what I am talking: http://man.hubwiz.com/docset/gensim.docset/Contents/Resources/Documents/radimrehurek.com/gensim/models/word2vec.html
Here is a link to how to train a word2vec model from scratch: https://radimrehurek.com/gensim/models/word2vec.html
You can also look at some other functions that come with it which allow you to find similar words just by a single vector, you can find these in the second link:
self.wv.similar_by_vector()
self.wv.similar_by_word()