<jupyter_start><jupyter_text>dataset https://www.kaggle.com/gdberrio/spooky-authors-csvPredict author of sentence (3 different authors)<jupyter_code>from string import punctuation

import pandas as pd
import numpy as np

from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.preprocessing import LabelEncoder
from sklearn.naive_bayes import MultinomialNB, GaussianNB, BernoulliNB

from nltk.corpus import stopwords
from nltk import wordpunct_tokenize
from nltk.stem import PorterStemmer
df = pd.read_csv("../datasets/authors.csv")
df.head()
df['author'].value_counts()<jupyter_output><empty_output><jupyter_text>more or less equal counts<jupyter_code>texts = df['text']
le = LabelEncoder().fit(df['author'])
authors = le.transform(df['author'])
np.bincount(authors)
stopwords = set(stopwords.words('english'))  # remove not important words
stemmer = PorterStemmer()  # stem the words so the vocabulary will be smaller
# removing punctuation, stopwords and stemming words to reduce the vocabulary
cleared_texts = []
for i in texts:
    cleared_texts.append(' '.join([stemmer.stem(x) for x in wordpunct_tokenize(i.lower())
              if x not in punctuation and x not in stopwords]))  # removing punctiation and all to lowercase
print(texts[0])
print()
print(cleared_texts[0])
x_train, x_test, y_train, y_test = train_test_split(cleared_texts, authors,
                                                    stratify=authors, test_size=0.2)
cv = CountVectorizer(decode_error='ignore', ngram_range=(1, 1), 
                     max_df=1.0, min_df=1)

cv.fit(x_train)
x_train_transformed = cv.transform(x_train)
x_test_transformed = cv.transform(x_test)
x_train_transformed.shape
clf = MultinomialNB()  # default
clf.fit(x_train_transformed.toarray(), y_train)
clf.score(cv.transform(x_test).toarray(), y_test)
print(np.bincount(y_test))
print(np.bincount(clf.predict(x_test_transformed.toarray())))
# with different params
param_grid = {'alpha': [0.001, 0.01, 0.1, 1, 10, 100, 1000], 'fit_prior': [True, False]}
grid_search_multinomial = GridSearchCV(MultinomialNB(), param_grid=param_grid, cv=5)
grid_search_multinomial.fit(x_train_transformed.toarray(), y_train)
grid_search_multinomial.best_params_
grid_search_multinomial.score(x_test_transformed.toarray(), y_test)
from sklearn.metrics import log_loss  # in kaggle competition this metric is used
predictions_proba = grid_search_multinomial.predict_proba(x_test_transformed.toarray())
log_loss(y_test, predictions_proba)<jupyter_output><empty_output><jupyter_text>well, not great, not terrible<jupyter_code>from sklearn.linear_model import LogisticRegression  # let's try LR as well
param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000], 'n_jobs': [-1]}
grid_search_lr = GridSearchCV(LogisticRegression(solver='lbfgs'), param_grid=param_grid, cv=5)
grid_search_lr.fit(x_train_transformed, y_train)
grid_search_lr.best_params_
print(grid_search_lr.score(x_test_transformed.toarray(), y_test))
predictions_proba = grid_search_lr.predict_proba(x_test_transformed.toarray())
print(log_loss(y_test, predictions_proba))<jupyter_output><empty_output><jupyter_text>seems to be a bit better in terms of logloss What can be tested as well:different preprocessing - n-grams, no removal of stopwords, no stemming, TF-IDF instead of TF,different algorithms<jupyter_code>idf = TfidfTransformer().fit(x_train_transformed)
x_train_transformed_idf = idf.transform(x_train_transformed)
clf = MultinomialNB()
clf.fit(x_train_transformed_idf.toarray(), y_train)
x_test_transformed_idf = idf.transform(cv.transform(x_test)).toarray()
print(clf.score(x_test_transformed_idf, y_test))
predictions_proba = clf.predict_proba(x_test_transformed.toarray())
print(log_loss(y_test, predictions_proba))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10673575129533679, 'fraction_numerical': 0.013212435233160623, 'mean_word_length': 6.960824742268041, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '250865', 'license': 'MIT', 'n_tokens_mistral': 1408, 'n_tokens_neox': 1316, 'n_words': 269, 'path': 'notebooks/authors MultinominalNB.ipynb', 'repo_name': 'Levich125/ml_dl_tests', 'size': '3860'}