import gensim  # The library we're using
import logging  # Gives us a much better view of what gensim does
import os  # Lets us talk to the file system

# The basic model:

sentences = [['first', 'sentence'], ['second', 'sentence']]

model = gensim.models.Word2Vec(sentences, min_count=1)


# Configure loggging:
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

# And build the model again:

sentences = [['first', 'sentence'], ['second', 'sentence']]

model = gensim.models.Word2Vec(sentences, min_count=1)

"""
Explanation: Word2Vec in Gensim
word2vec
gensim
This is an aggregation of the following tutorials / docs:
* https://rare-technologies.com/word2vec-tutorial/
* https://radimrehurek.com/gensim/models/word2vec.html
Theoretical explanation:
* http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/
* http://mccormickml.com/2017/01/11/word2vec-tutorial-part-2-negative-sampling/
End of explanation
"""


wolf_filename = '004.txt'

wolf_data = None
with open(wolf_filename, 'r') as content_file:
    wolf_data = content_file.read()
print(wolf_data[:1000])

wolf_data_no_newlines = wolf_data.replace('\n', ' ')
print(wolf_data_no_newlines[:1000])

wolf_data_sentences = wolf_data_no_newlines.split('.')

for i, s in enumerate(wolf_data_sentences[:5]):
    print(i, s)

def clean_and_process_sentence(sentence):
    sentence = sentence.replace(',', '')
    # This is where you could put any other form of normalization.
    return sentence.strip().split()

wolf_final = [clean_and_process_sentence(s) for s in wolf_data_sentences]

for s in wolf_final[:5]:
    print(s)

"""
Explanation: Regarding configuring the model:
Full list of params and description of each:
https://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec
Four params of special note, copied from the docs:

size is the dimensionality of the feature vectors.
max_vocab_size = limit RAM during vocabulary building; if there are more unique words than this, then prune the infrequent ones. Every 10 million word types need about 1GB of RAM. Set to None for no limit (default).
sg defines the training algorithm. By default (sg=0), CBOW is used. Otherwise (sg=1), skip-gram is employed.
hs = if 1, hierarchical softmax will be used for model training. If set to 0 (default), and negative is non-zero, negative sampling will be used.

Some Real Data (ish)
Grimm's Fairy Tales: The Wolf and the Seven Little Kids
wget https://www.cs.cmu.edu/~spok/grimmtmp/004.txt
End of explanation
"""


# Let's make a model with more respectable stats:
model = Word2Vec(wolf_final, size=10, window=5, min_count=2, workers=4)

"""
Explanation: New Model To Train:
End of explanation
"""


# Load Google's pre-trained Word2Vec vectors.
google_news_word_vectors_filename = os.path.join(
    'big_models','word2vec', 'GoogleNews-vectors-negative300.bin.gz')
# model = gensim.models.Word2Vec.load_word2vec_format(
#     google_news_word_vectors_filename, binary=True) 

google_news_vectors = gensim.models.KeyedVectors.load_word2vec_format(
    google_news_word_vectors_filename, binary=True) 

"""
Explanation: Okay, that's still far too small for us to actually work with.
We have a few options.  Pick your own favorite NLP dataset that is also actually "big", or use pre-built models.  
Pre-built models:
Back at https://code.google.com/archive/p/word2vec/, you'll find a link to word vectors trained the Google News dataset - "The model contains 300-dimensional vectors for 3 million words and phrases".  It's 1.5 gig compressed.
And about 5 gig when loaded into gensim. (only try if you have the avaialble memory!)
End of explanation
"""


# Access an individual vector:
print("length of vector: {}".format(len(google_news_vectors['data'])))
print("{}...".format(google_news_vectors['data'][:10]))

# Compare word vector similarity:
print(google_news_vectors.similarity('data', 'information'))
print(google_news_vectors.similarity('data', 'science'))
print(google_news_vectors.similarity('data', 'art'))
print(google_news_vectors.similarity('data', 'news'))

# Vector math, different operator:
google_news_vectors.most_similar(positive=['woman', 'king'], negative=['man'])

# Vector math:
google_news_vectors.most_similar_cosmul(positive=['woman', 'king'], negative=['man'])

# The more standard interface to save and load your own models:

# model.save('some_filename')

# from gensim.models import Word2Vec

# model = Word2Vec.load('some_filename')  # you can continue training with the loaded model!


"""
Explanation: Interacting with the model
End of explanation
"""


# Took my comptuer about 2 days to build and save this model.
# WARNING:  Loading the model takes roughly 7 gig in memory.
# WARNGIN:  Inferring vectors later ups the needed memory to around 19 gig!

wiki_doc2vec_filename = os.path.join(
    'big_models','doc2vec', 'wiki_example_dbow')
wiki_doc2vec_model = gensim.models.Doc2Vec.load(wiki_doc2vec_filename)

# get a word vector:
print("length of word vector: {}".format(len(wiki_doc2vec_model['data'])))
print("{}...".format(wiki_doc2vec_model['data'][:10]))

# get a document vector:
print("length of doc vector: {}".format(len(wiki_doc2vec_model.docvecs['Machine learning'])))
print("{}...".format(wiki_doc2vec_model.docvecs['Machine learning'][:10]))

# From: https://markroxor.github.io/gensim/static/notebooks/doc2vec-wikipedia.html
vec = [wiki_doc2vec_model.docvecs["Lady Gaga"] - 
       wiki_doc2vec_model["american"] + 
       wiki_doc2vec_model["japanese"]]
for m in wiki_doc2vec_model.docvecs.most_similar(vec, topn=11):
    print m

# Get most similar documents given new document:

doc_vec = wiki_doc2vec_model.infer_vector(['only', 'you', 'can', 'prevent', 'forrest', 'fires'])

wiki_doc2vec_model.docvecs.most_similar([doc_vec], topn=10)

# Get most similar words given new document:

doc_vec = wiki_doc2vec_model.infer_vector(['only', 'you', 'can', 'prevent', 'forrest', 'fires'])

wiki_doc2vec_model.most_similar([doc_vec], topn=10)

"""
Explanation: There are other pre-built models online:

https://github.com/jhlau/doc2vec
...(help me add to this list?  I can't find my old bookmarks...)

Doc2Vec
Following https://github.com/RaRe-Technologies/gensim/blob/develop/docs/notebooks/doc2vec-wikipedia.ipynb , I generated a doc2vec model using Wikipedia on 'just' the english. ;)
End of explanation
"""


