<jupyter_start><jupyter_text>Yelp Review<jupyter_code>import pandas as pd
import tqdm
from tqdm import tqdm
import regex as re 
import spacy
nlp = spacy.load("en_core_web_lg")<jupyter_output><empty_output><jupyter_text>OverviewMy goal with this Machine Learning Model is to help Yelp or a Business Owner automactically rate a reviewer's review. I used the 'text' columns which represents the review  Data Exploration<jupyter_code>reviews_df = pd.read_csv('data/review.csv', engine='python', error_bad_lines=False)
business_df = pd.read_csv('data/business.csv', engine='python', error_bad_lines=False)
reviews_df.head()
import pandas as pd
pd.set_option('display.max_rows', 500)
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)
business_df.head()
reviews_df.shape
business_df['state'].value_counts()
reviews_df_copy = reviews_df.drop(columns = {'review_id', 'date', 'useful', 'funny', 'cool'})
business_df_copy = business_df.drop(columns = {'name', 'address', 'postal_code', 'latitude', 'longitude', 'is_open', 'city', 'review_count','hours','attributes.GoodForKids', 'attributes.RestaurantsReservations', 'attributes.GoodForMeal', 'attributes.BusinessParking', 'attributes.Caters', 'attributes.NoiseLevel', 'attributes.RestaurantsTableService', 'attributes.RestaurantsTakeOut', 'attributes.RestaurantsPriceRange2', 'attributes.OutdoorSeating','attributes.BikeParking', 'attributes.Ambience', 'attributes.HasTV', 'attributes.WiFi', 'attributes.Alcohol', 'attributes.RestaurantsAttire', 'attributes.RestaurantsGoodForGroups', 'attributes.RestaurantsDelivery', 'hours.Monday', 'hours.Tuesday', 'hours.Wednesday', 'hours.Thursday', 'hours.Friday', 'hours.Saturday', 'hours.Sunday','attributes.BusinessAcceptsCreditCards','attributes','attributes.BusinessAcceptsBitcoin','attributes.ByAppointmentOnly','attributes.AcceptsInsurance','attributes.Music','attributes.GoodForDancing','attributes.CoatCheck','attributes.HappyHour','attributes.BestNights','attributes.WheelchairAccessible','attributes.DogsAllowed','attributes.BYOBCorkage','attributes.DriveThru','attributes.Smoking','attributes.AgesAllowed','attributes.HairSpecializesIn','attributes.Corkage','attributes.BYOB','attributes.DietaryRestrictions','attributes.Open24Hours','attributes.RestaurantsCounterService'})
business_df_copy = business_df_copy.rename(columns={'stars' : 'rating'})
''' Merging the DataFrames '''
reviews_df_merged = pd.merge(reviews_df_copy, business_df_copy, how='inner')
print(reviews_df_merged.shape)
reviews_df_merged.head()<jupyter_output>(6685900, 7)<jupyter_text>Filter the Dataframe on Ontario and Restaurant<jupyter_code>reviews_df_merged = reviews_df_merged[reviews_df_merged['state']=='ON']
reviews_df_merged.shape
reviews_df_merged.isnull().sum()
reviews_df_merged = reviews_df_merged.dropna()
reviews_df_merged.shape
categories = ['Restaurant', 'Restaurants']
reviews_df_merged = reviews_df_merged[reviews_df_merged['categories'].str.contains('|'.join(categories))]
reviews_df_merged.shape
reviews_df_merged.head()
reviews_df_merged['categories'].value_counts()
reviews_df_merged['categories'].nunique()
reviews_df_merged['stars'].hist()<jupyter_output><empty_output><jupyter_text>Tokenize, Remove Stop words, and Punct<jupyter_code>df = reviews_df_merged.sample(12000).reset_index()
df.head()
def token_clean(doc_list):
    #Extract tokens from reviews using Spacy
    # nlp.Defaults.stop_words |= {"my_new_stopword1","my_new_stopword2",}

    other_words = []

    tokens = []

    for document in tqdm(doc_list):
        doc = re.sub("[^a-zA-Z]+"," ",str(document))
        doc = doc.lower().strip()
        doc = nlp(doc)
        doc = [token.lemma_ for token in doc if (token.is_stop != True) and (token.is_punct != True) and (str(token) not in other_words) and (str(token).isdigit() != True) and (len(str(token)) >1)]
        tokens.append(doc)
        
    return tokens
df['tokens'] = token_clean(df['text'])
# Object from Base Python
from collections import Counter

# The object `Counter` takes an iterable, but you can instaniate an empty one and update it. 
word_counts = Counter()

def count(docs):

        word_counts = Counter()
        appears_in = Counter()
        
        total_docs = len(docs)

        for doc in docs:
            word_counts.update(doc)
            appears_in.update(set(doc))

        temp = zip(word_counts.keys(), word_counts.values())
        
        wc = pd.DataFrame(temp, columns = ['word', 'count'])

        wc['rank'] = wc['count'].rank(method='first', ascending=False)
        total = wc['count'].sum()

        wc['pct_total'] = wc['count'].apply(lambda x: x / total)
        
        wc = wc.sort_values(by='rank')
        wc['cul_pct_total'] = wc['pct_total'].cumsum()

        t2 = zip(appears_in.keys(), appears_in.values())
        ac = pd.DataFrame(t2, columns=['word', 'appears_in'])
        wc = ac.merge(wc, on='word')

        wc['appears_in_pct'] = wc['appears_in'].apply(lambda x: x / total_docs)
        
        return wc.sort_values(by='rank')
    
wc = count(df['tokens'])

import squarify
import matplotlib.pyplot as plt
import seaborn as sns

wc_top20 = wc[wc['rank'] <= 20]

squarify.plot(sizes=wc_top20['pct_total'], label=wc_top20['word'], alpha=.8 )
plt.axis('off')
plt.show()<jupyter_output><empty_output><jupyter_text>Find Baseline<jupyter_code>df['rating'].value_counts(normalize=True).sort_index()
df['rating_grade'] = ["Not Good" if rate<4.0 else "Good" for rate in df['rating']]
df['rating_grade'].value_counts(normalize=True).sort_index()<jupyter_output><empty_output><jupyter_text>Check TFIDF features<jupyter_code>from sklearn.feature_extraction.text import TfidfVectorizer

tfidf = TfidfVectorizer(ngram_range=(1,2),
                      max_df=0.97,
                      min_df=2)

description = df['tokens'].astype(str)

dtm = tfidf.fit_transform(description)

dtm = pd.DataFrame(dtm.todense(), columns=tfidf.get_feature_names())

dtm.head()<jupyter_output><empty_output><jupyter_text>Random Forest Classifier  Burrito Applied Modeling/Define ML problems<jupyter_code>df['tokens']= df['tokens'].astype(str)

# Define how much percent data you wanna split
split_pcent = 0.20
split = int(split_pcent * len(df))

# Shuffles dataframe
df = df.sample(frac=1).reset_index(drop=True)

# Training Sets
train = df[split:]

# Validation Sets
valid = df[:split]
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import TruncatedSVD

svd = TruncatedSVD(n_components=5000, algorithm='randomized',n_iter=10)
vect = TfidfVectorizer(stop_words='english', ngram_range=(1,2))
rfc = RandomForestClassifier()
params = {
    'lsi__svd__n_components': [10,50,100],
    'lsi__vect__min_df':[.02,.05],
    'lsi__vect__max_df':[.9, .95, 1.0],
    'lsi__vect__ngram_range':[(1,1),(1,2),(1,3)],
    'clf__n_estimators':[300,500,1000]}
# LSI
lsi = Pipeline([('vect', vect), ('svd', svd)])


# Pipe
pipe = Pipeline([('lsi', lsi), ('clf', rfc)])
# Fit
from sklearn.model_selection import RandomizedSearchCV

grid_search = RandomizedSearchCV(pipe,params, cv=5, n_jobs=-1, verbose=1)
grid_search.fit(train['tokens'], train['rating_grade'])
grid_search.best_score_
grid_search.best_params_<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14452435880037998, 'fraction_numerical': 0.012891844212240466, 'mean_word_length': 6.169260700389105, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 29, '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': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '442881', 'license': 'MIT', 'n_tokens_mistral': 2644, 'n_tokens_neox': 2499, 'n_words': 429, 'path': 'notebooks/yelp_reviews-using-rating.ipynb', 'repo_name': 'ashleyadrias/yelp-review-ratings', 'size': '7369'}