<jupyter_start><jupyter_text>Datasets download<jupyter_code>!pip install -q kaggle
# For reviews sentiment analysis
!kaggle datasets download -d jiashenliu/515k-hotel-reviews-data-in-europe
!unzip 515k-hotel-reviews-data-in-europe.zip<jupyter_output>Archive:  515k-hotel-reviews-data-in-europe.zip
  inflating: Hotel_Reviews.csv<jupyter_text>Pre-trained Embedding downloading<jupyter_code>!wget "https://s3.amazonaws.com/dl4j-distribution/GoogleNews-vectors-negative300.bin.gz"
!gunzip GoogleNews-vectors-negative300.bin.gz<jupyter_output>--2019-09-07 05:46:25--  https://s3.amazonaws.com/dl4j-distribution/GoogleNews-vectors-negative300.bin.gz
Resolving s3.amazonaws.com (s3.amazonaws.com)... 192.168.3.11
Connecting to s3.amazonaws.com (s3.amazonaws.com)|192.168.3.11|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1647046227 (1.5G) [application/x-gzip]
Saving to: ‘GoogleNews-vectors-negative300.bin.gz’

GoogleNews-vectors- 100%[===================>]   1.53G  34.5MB/s    in 46s     

2019-09-07 05:47:12 (33.8 MB/s) - ‘GoogleNews-vectors-negative300.bin.gz’ saved [1647046227/1647046227]<jupyter_text>Libraries and main functions/classes<jupyter_code>import warnings
warnings.filterwarnings("ignore")
# MAIN
import pandas as pd
import numpy as np
from tqdm import tqdm
from collections import Counter
import gc
import pickle
import joblib
from scripts.storing import save_model, load_model
from scripts.cleanup import CleanUpText

# NLP
import spacy
import string
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
from gensim.models import KeyedVectors
import gensim
from gensim.models import Word2Vec

# SKLEARN
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score, confusion_matrix, mean_squared_error, r2_score

# TENSORFLOW
import tensorflow as tf
from keras.models import Sequential, Model
from keras.layers import Input, Embedding, Reshape, Flatten, Conv1D, SpatialDropout1D, MaxPooling1D, Dense, GRU, LSTM, Dropout, BatchNormalization, Bidirectional
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.optimizers import Adam, SGD, RMSprop
from keras.callbacks import LearningRateScheduler, EarlyStopping
optimizer_adam = Adam(lr = 0.0005)

callbacks = [
    EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=2, verbose=1, restore_best_weights=True)
]<jupyter_output><empty_output><jupyter_text>Data description and preprocessing<jupyter_code>reviews = pd.read_csv('Hotel_Reviews.csv')
reviews['Positive_Review'] = reviews['Positive_Review'].apply(lambda x: '' if x == 'No Positive' else x + ' ')
reviews['Negative_Review'] = reviews['Negative_Review'].apply(lambda x: '' if x == 'No Negative' else x + ' ')
reviews['review'] = reviews['Positive_Review'] + np.array([' ']*reviews['Negative_Review'].shape[0]) + reviews['Negative_Review']
reviews = reviews[['Reviewer_Score', 'review']]
reviews.head(5)
text = CleanUpText().fit_transform(reviews['review'])<jupyter_output>100%|██████████| 515738/515738 [03:47<00:00, 2264.07it/s]<jupyter_text>Data preporation for model<jupyter_code># Data splitting and tokenizing 
X_train, X_val, y_train, y_val = train_test_split(text, reviews['Reviewer_Score']/10, random_state=73, test_size=0.2)
# Vocabulary len
NUM_WORDS = 50000

tokenizer = Tokenizer(num_words=NUM_WORDS)
tokenizer.fit_on_texts(X_train)
X_train = tokenizer.texts_to_sequences(X_train)
X_val = tokenizer.texts_to_sequences(X_val)
word_index = tokenizer.word_index
print('Found %s unique tokens.' % len(word_index))
# Save tokenizer object
save_model(tokenizer, 'tokenizer.pkl')
%%time
# Sequence cropping
X_train = pad_sequences(X_train)
X_val = pad_sequences(X_val, maxlen=X_train.shape[1])
print('Shape of X train and X validation tensor:', X_train.shape, X_val.shape)
%%time
MAX_LEN = X_train.shape[1]
gwv = KeyedVectors.load_word2vec_format('GoogleNews-vectors-negative300.bin', binary=True)
EMBEDDING_DIM=300
vocabulary_size=min(len(word_index)+1,NUM_WORDS)
embedding_matrix = np.zeros((vocabulary_size, EMBEDDING_DIM))
%%time
# Create embedding matrix
count_null = 0 
for word, i in word_index.items():
    if i>=NUM_WORDS:
        continue
    try:
        embedding_vector = gwv[word]
        embedding_matrix[i] = embedding_vector
    except KeyError:
        count_null += 1
        embedding_matrix[i]=np.random.normal(0,np.sqrt(0.25),EMBEDDING_DIM)
print('Count of string that not in word2vec vocabulary:', count_null)
print('From %d words' % (vocabulary_size))
del(gwv); gc.collect()<jupyter_output>Count of string that not in word2vec vocabulary: 24155
From 50000 words
CPU times: user 1.05 s, sys: 37 ms, total: 1.08 s
Wall time: 1.08 s<jupyter_text>Model building and fitting<jupyter_code>embedding_layer = Embedding(vocabulary_size,
                            EMBEDDING_DIM,
                            weights=[embedding_matrix],
                            input_shape=(MAX_LEN,),
                            trainable=False)
model = Sequential()
model.add(embedding_layer)
model.add(SpatialDropout1D(0.2))
model.add(Bidirectional(GRU(32, return_sequences=True)))
model.add(Conv1D(32, 11, activation='relu'))
model.add(MaxPooling1D(5))
model.add(SpatialDropout1D(0.2))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mean_absolute_error', optimizer=optimizer_adam, metrics=['mae', 'mse'])
model.summary()
# It's just an example of training a model. Real model have another loss
model.fit(X_train, np.asarray(y_train), batch_size=2048, epochs=1, verbose=1, 
          callbacks=callbacks, validation_data=(X_val, np.asarray(y_val)))<jupyter_output>Train on 412590 samples, validate on 103148 samples
 12288/412590 [..............................] - ETA: 25:47 - loss: 0.2964 - mae: 0.2964 - mse: 0.1055WARNING:tensorflow:Early stopping conditioned on metric `val_loss` which is not available. Available metrics are: loss,mae,mse
{'fraction_non_alphanumeric': 0.12453967191161701, 'fraction_numerical': 0.04904586541680616, 'mean_word_length': 5.587651598676957, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 22, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '225360', 'license': 'MIT', 'n_tokens_mistral': 2299, 'n_tokens_neox': 2083, 'n_words': 434, 'path': 'reviews_scoring.ipynb', 'repo_name': 'Shemka/ReviewsScoring', 'size': '5974'}