<jupyter_start><jupyter_text><jupyter_code>!pip install fasttext
import fasttext
import numpy as np
import pandas as pd
import tensorflow as tf
import keras.layers as layers
from keras.models import Model
from keras.datasets import imdb
from gensim.models import Word2Vec
from gensim.models import FastText
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.layers import Input,Embedding,Dense,Flatten
from sklearn.metrics import accuracy_score,classification_report
#from sklearn.model_selection import train_test_split
def load_data(vocab_size,max_len):
    """
        Loads the keras imdb dataset

        Args:
            vocab_size = {int} the size of the vocabulary
            max_len = {int} the maximum length of input considered for padding

        Returns:
            X_train = tokenized train data
            X_test = tokenized test data

    """
    INDEX_FROM = 3

    # save np.load
    np_load_old = np.load

    # modify the default parameters of np.load
    np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True, **k)

    (X_train,y_train),(X_test,y_test) = imdb.load_data(num_words = vocab_size,index_from = INDEX_FROM)

    # restore np.load for future normal usage
    np.load = np_load_old

    print(len(X_train), len(X_test), len(y_train), len(y_test), "#####################################")

    return X_train,X_test,y_train,y_test

def prepare_data_for_word_vectors_imdb(X_train):
    """
        Prepares the input

        Args:
            X_train = tokenized train data

        Returns:
            sentences = {list} sentences containing words as tokens
            word_index = {dict} word and its indexes in whole of imdb corpus

    """
    INDEX_FROM = 3
    word_to_index = imdb.get_word_index()
    word_to_index = {k:(v+INDEX_FROM) for k,v in word_to_index.items()}

    word_to_index["<START>"] =1
    word_to_index["<UNK>"]=2

    index_to_word = {v:k for k,v in word_to_index.items()}

    sentences = []
    for i in range(len(X_train)):
        temp = [index_to_word[ids] for ids in X_train[i]]
        sentences.append(temp)
    """
    tokenizer = Tokenizer()
    tokenizer.fit_on_texts(sentences)
    word_indexes = tokenizer.word_index
    """

    #print(sentences[:10],word_to_index,"sentences[:10],word_to_index[:10]*********************************************")
    return sentences,word_to_index
def building_word_vector_model(option,sentences,embed_dim,workers,window,y_train):
    """
        Builds the word vector

        Args:
            type = {bool} 0 for Word2vec. 1 for gensim Fastext. 2 for Fasttext 2018.
            sentences = {list} list of tokenized words
            embed_dim = {int} embedding dimension of the word vectors
            workers = {int} no. of worker threads to train the model (faster training with multicore machines)
            window = {int} max distance between current and predicted word
            y_train = y_train

        Returns:
            model = Word2vec/Gensim fastText/ Fastext_2018 model trained on the training corpus


    """
    if option == 0:
        print("Training a word2vec model")
        model = Word2Vec(sentences=sentences, size = embed_dim, window = window) # workers = workers,
        print("Training complete")

    elif option == 1:
        print("Training a Gensim FastText model")
        model = FastText(sentences=sentences, size = embed_dim, window = window) # workers = workers, 
        print("Training complete")

    elif option == 2:
        print("Training a Fasttext model from Facebook Research")
        y_train = ["__label__positive" if i==1 else "__label__negative" for i in y_train]

        with open("imdb_train.txt","w") as text_file:
            for i in range(len(sentences)):
                print(sentences[i],y_train[i],file = text_file)

        model = fasttext.train_unsupervised("imdb_train.txt", model = "skipgram", lr=0.05, dim=embed_dim, ws=5, epoch=5) 
        print("Training complete")

    return model
# specify “option” as  0 – Word2vec, 1 – Gensim FastText, 2- Fasttext

option = 1

embed_dim = 300
split_ratio= 0.33
max_len= 200
vocab_size= 1000
trainable_param= False
workers = 3,
window = 1


x_train,x_test,y_train,y_test = load_data(vocab_size,max_len)
sentences,word_ix = prepare_data_for_word_vectors_imdb(x_train)
model_wv = building_word_vector_model(option,sentences,embed_dim,workers,window,y_train)
def padding_input(X_train,X_test,maxlen):
    """
        Pads the input upto considered max length

        Args:
            X_train = tokenized train data
            X_test = tokenized test data

        Returns:
            X_train_pad = padded tokenized train data
            X_test_pad = padded tokenized test data

    """
    print(X_train.shape, X_test.shape, "before padding")

    X_train_pad = pad_sequences(X_train,maxlen=maxlen,padding="post")

    X_test_pad = pad_sequences(X_test,maxlen=maxlen,padding="post")

    print(X_train_pad.shape, X_test_pad.shape, "after padding")

    return X_train_pad,X_test_pad
x_train_pad,x_test_pad = padding_input(x_train,x_test,max_len)
def classification_model(embed_dim,X_train_pad,X_test_pad,y_train,y_test,vocab_size,word_index,w2vmodel,trainable_param):
    """
        Builds the classification model for sentiment analysis

        Args:
            embded_dim = {int} dimension of the word vectors
            X_train_pad = padded tokenized train data
            X_test_pad = padded tokenized test data
            vocab_size = {int} size of the vocabulary
            word_index =  {dict} word and its indexes in whole of imdb corpus
            w2vmodel = Word2Vec model
            trainable_param = {bool} whether to train the word embeddings in the Embedding layer
    """

    embedding_matrix = np.zeros((vocab_size,embed_dim))
    print(embedding_matrix.shape, "embedding_matrix")
    for word, i in word_index.items():
        try:
            embedding_vector = w2vmodel[word]
            
        except:
            pass
        try:
            if embedding_vector is not None:
                embedding_matrix[i]=embedding_vector
        except:
            pass
    #print(embedding_vector, word, "embedding_vector, word")
    print(embedding_matrix.shape ,"embedding_matrix")       
    embed_layer = Embedding(vocab_size,embed_dim,weights =[embedding_matrix],trainable=trainable_param)

    input_seq = Input(shape=(X_train_pad.shape[1],))
    embed_seq = embed_layer(input_seq)
    x = Dense(256,activation ="relu")(embed_seq)
    x = Flatten()(x)
    preds = Dense(1,activation="sigmoid")(x)

    model = Model(input_seq,preds)


    model.compile(loss=loss,optimizer=optimizer,metrics= metrics)

    model.fit(X_train_pad,y_train,epochs=epochs,batch_size=batch_size,validation_data=(X_test_pad,y_test))
    predictions = model.predict(X_test_pad)
    predictions = [0 if i<0.5 else 1 for i in predictions]
    print("Accuracy: ",accuracy_score(y_test,predictions))
    print("Classification Report: ",classification_report(y_test,predictions))

    return model

epochs = 1
batch_size = 1024
loss = "binary_crossentropy"
optimizer = "adam"
metrics = ["accuracy"]
      
model = classification_model(embed_dim,x_train_pad,x_test_pad,y_train, y_test,vocab_size,word_ix,model_wv,trainable_param)
print(model.summary())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10037930100243836, 'fraction_numerical': 0.00988891899214305, 'mean_word_length': 3.384204275534442, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '168371', 'license': 'Apache-2.0', 'n_tokens_mistral': 2438, 'n_tokens_neox': 2321, 'n_words': 562, 'path': 'training_word2vec_fasttext_glove_imdb.ipynb', 'repo_name': 'dhana-sekhar/Natural_Language_Processing', 'size': '7382'}