<jupyter_start><jupyter_text>HelpfulnessNumerator - number of users who found the review helpful\HelpfulnessDenominator - number of users who ndicated whether they found the review helpful or not<jupyter_code># Checking IS 'HelpfulnessNumerator' always less than or equal to 'HelpfulnessDenominator'?
data[data['HelpfulnessNumerator'] > data['HelpfulnessDenominator']]
# "HelpfulnessNumerator" can't be greater than "helpfulnessDenominator"
# so taking dataframe in which "helpfulnessNumerator" less than or equal to "HelpfulnessDenominator"
data = data[data['HelpfulnessNumerator'] <= data['HelpfulnessDenominator']]
data.reset_index(drop = True, inplace = True)
print(data.shape)
data.head()
# identifying the missing values
data.isnull().sum()
# data points for each class
print(data['Score'].value_counts())
print("*"*50)

# count plot for score
sns.countplot('Score', data = data)
plt.title("Score Distribution")<jupyter_output>1    307061
0     57110
Name: Score, dtype: int64
**************************************************<jupyter_text>Text Preprocessing: Stemming, stop-word removal and Lemmatization<jupyter_code># set of stopwords
import re
import nltk
from nltk.corpus import stopwords
stop = set(stopwords.words('english'))

# initializing the snowball stemmer
sno = nltk.stem.SnowballStemmer('english')

# function to clean the word of any html-tags
def cleanhtml(sentence):
    cleanr = re.compile('<.*?>')
    cleantext = re.sub(cleanr, ' ', sentence)
    return cleantext

# function to clean the word of any punctuation or special characters
def cleanpunc(sentence):
    cleaned = re.sub(r'[?|!|\'|"|#]', r'', sentence)
    cleaned = re.sub(r'[.|,|)|(|\|/]', r' ', cleaned)
    return cleaned

# function to text summarization
def final_sentence(text):
    
    text = text.split()
    text = [cleanhtml(x) for x in text]
    text = [cleanpunc(x) for x in text]
    
    def test(word):
        if word.isalpha() and len(word) > 2 and word.lower() not in stop:
            return True
        else:
            return False
        
    text = [x for x in text if test(x)]
    return ' '.join(text)
data['CleanedText'] = data['Text'].apply(final_sentence)
print(data.shape)
data.head()<jupyter_output>(364171, 11)<jupyter_text>Converting Text data into vector<jupyter_code>def Text_Into_Vector(model, data):
    model_vect = model(ngram_range = (1,2)) # in scikit-learn
    final_array = model_vect.fit_transform(data.values)
    
    print("the type of count vectorizer ", type(final_array))
    print("the shape of out text BOW vectorizer ", final_array.get_shape())
    print("the number of unique words including both unigrams and bigrams ", final_array.get_shape()[1])
    
    return model_vect, final_array<jupyter_output><empty_output><jupyter_text>Spliting data<jupyter_code># spliting data into train, cross validate and test
from sklearn.model_selection import train_test_split

def Split_data(x_vec, y_vec):
    X_train, X_test, Y_train, Y_test = train_test_split(x_vec, y_vec, test_size = .33, random_state = 0)
    X_tr, X_cv, Y_tr, Y_cv = train_test_split(X_train, Y_train, test_size = .33, random_state = 0)
    return X_tr, X_cv, X_test, Y_tr, Y_test, Y_cv, X_train, Y_train<jupyter_output><empty_output><jupyter_text>Normalize Data<jupyter_code># normalize data
from sklearn import preprocessing
from sklearn.preprocessing import Normalizer

def Normalization(train, cv, test):
    train = preprocessing.normalize(train)
    cv = preprocessing.normalize(cv)
    test = preprocessing.normalize(test)
    
    print("Train Data Size: ", train.get_shape())
    print("CV Data Size: ", cv.get_shape())
    print("Test Data Size: ", test.get_shape())
    
    return train, cv, test<jupyter_output><empty_output><jupyter_text>Training Multinomial Naive Bayes Model<jupyter_code>from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curve
import matplotlib.pylab as pyplt 

def Multinomial_NB(X_train, X_cv, Y_train, Y_cv):
    ###################################################
    best_alpha = 0
    max_roc_auc = -1
    pred_cv = []
    pred_train = []
    alpha = [10000, 5000, 1000, 500, 100, 50, 10, 5, 1, 0.05, 0.01, 0.005, 0.001, 0.0005, 0.0001, 0.00005, 0.00001]
    ####################################################
    
    for i in alpha:
        mulbnb = MultinomialNB(alpha=i)
        mulbnb.fit(X_train, Y_train)
        probs = mulbnb.predict_proba(X_cv)[:,1]
        prob = mulbnb.predict_proba(X_train)[:,1]
        ################################################
        
        auc_score_cv = roc_auc_score(Y_cv, probs)   # auc roc for cv
        auc_score_train = roc_auc_score(Y_train, prob)  # auc roc for train
        ################################################
        
        print(i, "------------>", auc_score_cv)
        ################################################
        
        pred_cv.append(auc_score_cv)
        pred_train.append(auc_score_train)
        ###############################################
        
        if(max_roc_auc<auc_score_cv):
            max_roc_auc = auc_score_cv
            best_alpha = i
    
    
    print("*"*100)
    print(f"\n Best alpha Value {best_alpha} with highest roc_auc Score is {max_roc_auc}")
    print("*"*100)
    ######################################################################
    
    
    
    sns.set_style("darkgrid")
    plt.xscale('log')
    plt.plot(alpha, pred_cv, 'r-', label = 'CV Data')
    plt.plot(alpha, pred_train, 'g-', label = 'Train Data')
    plt.legend(loc = 'upper right')
    plt.title(r'Auc Score v/s $\alpha$')
    plt.xlabel(r"alpha values", fontsize = 12)
    plt.ylabel("roc_auc", fontsize = 12)
    plt.show()
    print("*"*100)
    #####################################################################
    
    # calculate roc curve
    fpr, tpr, thresholds = roc_curve(Y_cv, probs)
    # plot no skill
    pyplt.plot([0,1], [0,1], linestyle = '--')
    # plot the roc curve for the model
    pyplt.plot(fpr, tpr, marker = ".")
    pyplt.title("Line Plot of ROC Curve on Train Data")
    pyplt.ylabel("True Positive Rate")
    pyplt.xlabel("False Positive Rate")
    pyplt.show()
    print("*"*100)
    
    ###################################################################
    
    return best_alpha<jupyter_output><empty_output><jupyter_text>Testing Multinomial Naive Bayes Model<jupyter_code>pip install scikit-plot
import scikitplot.metrics as skplt
from sklearn import metrics
from sklearn.metrics import confusion_matrix


def Testing_model(X_train, Y_train, X_test, Y_test, best_alpha):
    
    ######################################################################
    bnb = MultinomialNB(alpha = best_alpha, fit_prior = True, class_prior = None)
    bnb.fit(X_train, Y_train)
    probs = bnb.predict_proba(X_test)[:, 1]       # keep probabilities for the positive outcome only
    
    ######################################################################
    
    roc_auc = roc_auc_score(Y_test, probs)
    print("AUC Score", roc_auc)
    print("*"*100)
    
    ######################################################################
    
    
    # calcutate roc curve
    fpr, tpr, thresholds = roc_curve(Y_test, probs)
    # plot no skill
    plt.plot([0, 1], [0, 1], linestyle='--')
    # plot the roc curve for the model
    plt.plot(fpr, tpr, marker='.')
    plt.title("Line Plot of ROC Curve on Test Data")
    plt.ylabel('True Positive Rate')
    plt.xlabel('False Positive Rate')    
    plt.show()
    
    #####################################################################
    prediction = bnb.predict(X_test)
    skplt.plot_confusion_matrix(Y_test, prediction)
    #######################################################################
    
    print("macro f1 score for data :",metrics.f1_score(Y_test, prediction, average = 'macro'))
    print("micro f1 score for data:",metrics.f1_score(Y_test, prediction, average = 'micro'))
    print("hamming loss for data:",metrics.hamming_loss(Y_test,prediction))
    print("*"*70)
    print("Precision recall report for data:\n",metrics.classification_report(Y_test, prediction))
    print("*"*70)
    
    return bnb,roc_auc
    ##################################<jupyter_output><empty_output><jupyter_text>top Features<jupyter_code>def Important_features(model, classifier):
    neg = classifier.feature_log_prob_[0].argsort()
    pos = classifier.feature_log_prob_[1].argsort()
    top_pos_words = np.take(model.get_feature_names(), pos)
    top_neg_words = np.take(model.get_feature_names(),neg)
    imp_df = pd.DataFrame(columns = ['Pos_Words','Pos_Importance','Neg_Words','Neg_Importance'])
    imp_df['Pos_Words'] = top_pos_words[::-1]
    imp_df['Pos_Importance'] = np.take(classifier.feature_log_prob_[1],pos)[::-1]
    imp_df['Neg_Words'] = top_neg_words[::-1]
    imp_df['Neg_Importance'] = np.take(classifier.feature_log_prob_[0],neg)[::-1]
    return imp_df<jupyter_output><empty_output><jupyter_text>Individual Prediction<jupyter_code>def Individual_Prediction(model, classifier, review):
    review = final_sentence(review)
    review_vec = model.transform([review])
    review_vec = preprocessing.normalize(review_vec)
    pred = classifier.predict(review_vec)
    
    return "positive review" if pred[0] == 1 else "negative review"<jupyter_output><empty_output><jupyter_text>Bag of Words(BoW)<jupyter_code>from sklearn.feature_extraction.text import CountVectorizer

BOW, X = Text_Into_Vector(CountVectorizer, data['CleanedText'])
BOW.get_feature_names()[:20]
BOW.get_params()
# split the data into train, cross validate and test
X_tr, X_cv, X_test, Y_tr, Y_test, Y_cv, X_train, Y_train = Split_data(X, data['Score'])
print('X_test, Y_test', X_test.shape, Y_test.shape)
print('X_tr, Y_tr', X_tr.shape, Y_tr.shape)
print('X_cv, Y_cv', X_cv.shape, Y_cv.shape)
print('X_Train, Y_Train', X_train.shape, Y_train.shape)
# normalization
X_tr, X_cv, X_test = Normalization(X_tr, X_cv, X_test)<jupyter_output>Train Data Size:  (163475, 3474709)
CV Data Size:  (80519, 3474709)
Test Data Size:  (120177, 3474709)<jupyter_text>Naive Bayes for BOW<jupyter_code># training NB

best_alpha_bow = Multinomial_NB(X_tr, X_cv, Y_tr, Y_cv)
# testing NB

NB_bow, roc_auc_bow = Testing_model(X_tr, Y_tr, X_test, Y_test, best_alpha_bow)
# Top features

Important_features(BOW, NB_bow)<jupyter_output><empty_output><jupyter_text>TF-IDF<jupyter_code># TFidf Vectorizer

from sklearn.feature_extraction.text import TfidfVectorizer

TfIdf, X = Text_Into_Vector(TfidfVectorizer, data['CleanedText'])
TfIdf.get_feature_names()[:20]
TfIdf.get_params()
#split data into train, cross validate and test 

X_tr, X_cv, X_test, Y_tr, Y_test, Y_cv, X_train, Y_train = Split_data(X, data['Score'])
print('X_test, Y_test', X_test.shape, Y_test.shape)
print('X_tr, Y_tr', X_tr.shape, Y_tr.shape)
print('X_cv, Y_cv', X_cv.shape, Y_cv.shape)
print('X_Train, Y_Train', X_train.shape, Y_train.shape)
# Normalize Data

X_tr, X_cv, X_test = Normalization(X_tr, X_cv, X_test)
#Training NB model

best_alpha_idf = Multinomial_NB(X_tr,X_cv,Y_tr,Y_cv)
# Testing NB Model

NB_tfidf, roc_auc_idf = Testing_model(X_tr,Y_tr,X_test,Y_test,best_alpha_idf)
# Top features using NB and tfidf

Important_features(TfIdf, NB_tfidf)<jupyter_output><empty_output><jupyter_text>Conclusion<jupyter_code>from prettytable import PrettyTable

x = PrettyTable()
x.field_names = ['Vectorizer', 'Model', "Hyperameter(alpha)", "Test Auc Score"]

################################################################################

x.add_row(["BoW", "MultinomialNB", best_alpha_bow, roc_auc_bow])
x.add_row(["Tf-Idf", "MultinomialNB", best_alpha_idf, roc_auc_idf])


#################################################################################

from IPython.display import Markdown, display
def printmd(string):
    display(Markdown(string))
    
###########################################################################

printmd("****Final Conclusion for MultiNomialNB Model:****")
print(x)
# Individual prediction
review = """Great, healthier alternative to the usual bhujia we Indians are used to having along with our tea or our beer.
            Much less salt than traditional tea snacks as well. I love the variety of texture as well with the very 
            crunchy peas to soft cheese bits, the sesame seed coated snack to good old roasted peanuts. It is pretty 
            expensive though, at 600rs at a kilo perhaps the most expensive tea snack Ive ever had."""

print("Prediction using BOW:", Individual_Prediction(BOW, NB_bow, review))
print("Prediction using TF-Idf:", Individual_Prediction(TfIdf, NB_tfidf, review))
# Individual prediction
review = """Good but Made in China. They are rubberbands yes, but Alliance brand is made in USA. 
            I guess would depend on your use needs and if you want to give your support to another 
            Country rather than your neighbor."""

print("Prediction using BOW:", Individual_Prediction(BOW, NB_bow, review))
print("Prediction using TF-Idf:", Individual_Prediction(TfIdf, NB_tfidf, review))<jupyter_output>Prediction using BOW: positive review
Prediction using TF-Idf: positive review
{'fraction_non_alphanumeric': 0.19493000378357928, 'fraction_numerical': 0.014453272796065078, 'mean_word_length': 4.827160493827161, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '406838', 'license': 'MIT', 'n_tokens_mistral': 4599, 'n_tokens_neox': 4293, 'n_words': 1021, 'path': 'NLP Project.ipynb', 'repo_name': 'mahfuz978/TECH-I.S.-----NLP', 'size': '13215'}