<jupyter_start><jupyter_text>Final Presentation Notebook<jupyter_code>import pandas as pd
import seaborn as sns
from yellowbrick.classifier import ClassificationReport, ConfusionMatrix

from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB, BernoulliNB
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from yellowbrick.text import FreqDistVisualizer

from sklearn import metrics

import matplotlib.pyplot as plt
from imblearn.over_sampling import SMOTE<jupyter_output><empty_output><jupyter_text>Load in filtered dataset and look at the formattingThe columns of interest at ['filter_title', 'filter_title_no_stops', 'category_id']    1. 'filter_title' --> raw input that only has punctuation removed and letters to lower case    2. 'filter_title_no_stops' --> 'filter_title' data with addition to removal of stopwords    3. 'category_id' --> output/buckets to categorize video (16 total)<jupyter_code>df_titles_info = pd.read_csv('./output/US_count_vectorizer_dataset.csv')
df_titles_info.head()<jupyter_output><empty_output><jupyter_text>Split dataset before vectorizingThis guards against leaking information from testing to training set (80% training, 20% testing)https://machinelearningmastery.com/data-leakage-machine-learning/https://stackoverflow.com/questions/54491953/can-i-use-countvectorizer-on-both-test-and-train-data-at-the-same-time-or-do-i-n<jupyter_code>df_x = df_titles_info['filter_title']
df_y = df_titles_info['category_id']

x_train, x_test, y_train, y_test = train_test_split(df_x, df_y, test_size=0.2, random_state=117)
target_names = list(df_y.unique())

print("Training data size:", x_train.shape)
print("Traing output: ", y_train.value_counts())
print()
print("Testing data size:", x_test.shape)
print("Testing output: ",y_test.value_counts())<jupyter_output>Training data size: (32759,)
Traing output:  Entertainment            7948
Music                    5227
Howto & Style            3323
Comedy                   2793
People & Blogs           2550
News & Politics          1964
Science & Technology     1940
Film & Animation         1850
Sports                   1737
Education                1327
Pets & Animals            734
Gaming                    668
Travel & Events           315
Autos & Vehicles          293
Nonprofits & Activism      47
Shows                      43
Name: category_id, dtype: int64

Testing data size: (8190,)
Testing output:  Entertainment            2016
Music                    1245
Howto & Style             823
Comedy                    664
People & Blogs            660
News & Politics           523
Film & Animation          495
Science & Technology      461
Sports                    437
Education                 329
Pets & Animals            186
Gaming                    149
Autos & Vehicles           91
Travel &[...]<jupyter_text>Tokenizer words using CountVectorizerBag-of-Words model that allows both tokenize a collection of text documents and build a vocabulary of known wordsThe length of each individual vector will be that of the entire dataset which each indices representing the count of a specific word<jupyter_code>count_vectorizer = CountVectorizer()
train_count_vector = count_vectorizer.fit_transform(x_train)
test_count_vector = count_vectorizer.transform(x_test)<jupyter_output><empty_output><jupyter_text>Tokenizer words using TfidfTransformerWill convert our count values from CountVectorizer into a frequency matrixTerm Frequency: How often a word appears in a particular title.Inverse Document Frequency: Downscale this words that appear often across multiple titles.Main purpose is to reduce the importance of stopwords that a common accross categories<jupyter_code>tfidf_vectorizer = TfidfTransformer()
x_trained_tfidf_vector = tfidf_vectorizer.fit_transform(train_count_vector)
x_test_tfidf_vector = tfidf_vectorizer.transform(test_count_vector)<jupyter_output><empty_output><jupyter_text>Model Training and Prediction  Naive Bayes Model Training  Create, Train, and Predict a Multinomial Naive Bayes Model using CountVectors<jupyter_code>clf_count = MultinomialNB()
clf_count.fit(train_count_vector, y_train)

pred_count = clf_count.predict(test_count_vector)
print("Accuracy: ", metrics.accuracy_score(y_test, pred_count))
print("Precision: ", metrics.precision_score(y_test, pred_count, average='weighted'))
print("F1: ", metrics.f1_score(y_test, pred_count, average='weighted'))
print(metrics.classification_report(y_test, pred_count))

visualizer = ClassificationReport(clf_count, classes=target_names, support=True)
visualizer.fit(train_count_vector, y_train)
visualizer.score(test_count_vector, y_test)
visualizer.show()
# conf_matrix = metrics.confusion_matrix(y_test, pred_count, labels=target_names)
# conf_df = pd.DataFrame(conf_matrix, index=target_names, columns=target_names)

# plt.figure(figsize=(15,6))
# sns.heatmap(conf_df, cmap='YlOrRd', annot=True, fmt='d')
# plt.title('Count NB Model\nAccuracy:{0:.3f}'.format(metrics.accuracy_score(y_test, pred_count)))
# plt.ylabel('True label')
# plt.xlabel('Predicted label')
# plt.show()

conf_matrix = ConfusionMatrix(clf_count, cmapstring='YlOrRd', percent=True)
conf_matrix.fit(train_count_vector, y_train)
conf_matrix.score(test_count_vector, y_test)
conf_matrix.show()<jupyter_output>/home/loc/anaconda3/envs/yt-trends/lib/python3.7/site-packages/sklearn/base.py:197: FutureWarning: From version 0.24, get_params will raise an AttributeError if a parameter cannot be retrieved as an instance attribute. Previously it would return None.
  FutureWarning)<jupyter_text>Create, Train, and Predict a Multinomial Naive Bayes Model using Tfidf Vector<jupyter_code>clf_tfidf = MultinomialNB()
clf_tfidf.fit(x_trained_tfidf_vector, y_train)

pred_tfidf = clf_tfidf.predict(x_test_tfidf_vector)
print("Accuracy: ", metrics.accuracy_score(y_test, pred_tfidf))
print("Precision: ", metrics.precision_score(y_test, pred_tfidf, average='weighted'))
print("F1: ", metrics.f1_score(y_test, pred_tfidf, average='weighted'))
print(metrics.classification_report(y_test, pred_tfidf))

visualizer = ClassificationReport(clf_tfidf, classes=target_names, support=True)
visualizer.fit(x_trained_tfidf_vector, y_train)
visualizer.score(x_test_tfidf_vector, y_test)
visualizer.show()
# conf_matrix = metrics.confusion_matrix(y_test, pred_tfidf, labels=target_names)
# conf_df = pd.DataFrame(conf_matrix, index=target_names, columns=target_names)

# plt.figure(figsize=(15,6))
# sns.heatmap(conf_df, cmap='YlOrRd', annot=True, fmt='d')
# plt.title('Tfidf NB Model\nAccuracy:{0:.3f}'.format(metrics.accuracy_score(y_test, pred_tfidf)))
# plt.ylabel('True label')
# plt.xlabel('Predicted label')
# plt.show()

conf_matrix = ConfusionMatrix(clf_tfidf, cmapstring='YlOrRd', percent=True)
conf_matrix.fit(x_trained_tfidf_vector, y_train)
conf_matrix.score(x_test_tfidf_vector, y_test)
conf_matrix.show()<jupyter_output>/home/loc/anaconda3/envs/yt-trends/lib/python3.7/site-packages/sklearn/base.py:197: FutureWarning: From version 0.24, get_params will raise an AttributeError if a parameter cannot be retrieved as an instance attribute. Previously it would return None.
  FutureWarning)<jupyter_text>Utilize SMOTE to oversample minority classesOversampling to have the same number of features in minority classes as in majority classes<jupyter_code>smote = SMOTE(sampling_strategy='not majority')

x_train_smote, y_train_smote = smote.fit_sample(train_count_vector, y_train)

print(y_train.value_counts().tail())
print()
print(y_train_smote.value_counts().tail())
norm_smp = y_train.value_counts().rename_axis('categories').reset_index(name='counts')
plot_norm = sns.barplot(x='counts', y='categories',data=norm_smp, color=(0.2, 0.4, 0.6, 0.6))
over_smp = y_train_smote.value_counts().rename_axis('categories').reset_index(name='counts')
plot_over = sns.barplot(x='counts', y='categories',data=over_smp, color=(0.2, 0.4, 0.6, 0.6))
clf_count.fit(x_train_smote, y_train_smote)

pred_count_smote = clf_count.predict(test_count_vector)
print("Count Model")
print("Accuracy: ", metrics.accuracy_score(y_test, pred_count_smote))
print("Precision: ", metrics.precision_score(y_test, pred_count_smote, average='weighted'))
print("F1: ", metrics.f1_score(y_test, pred_count_smote, average='weighted'))
print(metrics.classification_report(y_test, pred_count_smote))

visualizer = ClassificationReport(clf_count, classes=target_names, support=True, cmap='YlOrRd')
visualizer.fit(x_train_smote, y_train_smote)
visualizer.score(test_count_vector, y_test)
visualizer.show()
# conf_matrix = metrics.confusion_matrix(y_test, pred_count_smote, labels=target_names)
# conf_df = pd.DataFrame(conf_matrix, index=target_names, columns=target_names)

# plt.figure(figsize=(15,6))
# sns.heatmap(conf_df, cmap='YlOrRd', annot=True, fmt='d')
# plt.title('SMOTE NB Model \nAccuracy:{0:.3f}'.format(metrics.accuracy_score(y_test, pred_count_smote)))
# plt.ylabel('True label')
# plt.xlabel('Predicted label')
# plt.show()

conf_matrix = ConfusionMatrix(clf_count, cmapstring='YlOrRd', percent=True)
conf_matrix.fit(x_train_smote, y_train_smote)
conf_matrix.score(test_count_vector, y_test)
conf_matrix.show()<jupyter_output>/home/loc/anaconda3/envs/yt-trends/lib/python3.7/site-packages/sklearn/base.py:197: FutureWarning: From version 0.24, get_params will raise an AttributeError if a parameter cannot be retrieved as an instance attribute. Previously it would return None.
  FutureWarning)
{'fraction_non_alphanumeric': 0.10154105974245303, 'fraction_numerical': 0.020371543170783196, 'mean_word_length': 5.936310395314788, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 32, 'https://': 2, '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': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '283443', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 3320, 'n_tokens_neox': 3122, 'n_words': 658, 'path': 'Final_Winter_Notebook.ipynb', 'repo_name': 'Vic-the-Legend/yt-trends', 'size': '9474'}