Não se esqueça do CountVectorizer

Muitas das vezes quando vamos usar dados textuais para treinamento de modelos de machine learning usando o Scikit-Learn, algumas das vezes ficamos emperrados em problemas complexos com soluções simples.

TL;DR: Sempre que forem usar treinamento de modelos no Scikit, não esqueça do CountVectorizer()(ou da implementação que vai gerar a matrix de frequência).

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
# Carga do conjunto de dados
df = \
pd.read_csv("https://raw.githubusercontent.com/fclesio/metalbr/master/rebirth-remains.csv",
index_col=False)
df.columns = ['index','artist','album','lyric']
# Limpa os NaN para nao quebrar o vectorizer
df = df.dropna()
# Treino e teste basicos
X_train, X_test, y_train, y_test = \
train_test_split(df['lyric'], df['artist'], random_state=42)
# CountVectorizer para converter o texto em uma matriz de tokens
cv = CountVectorizer(strip_accents='ascii',
lowercase=True,
stop_words='english')
# Gera o dicionario, aprende com o mesmo e retorna
# uma matriz de frequencia (term-document matrix)
X_train_cv = cv.fit_transform(X_train)
# Transforma a base de teste em
X_test_cv = cv.transform(X_test)
# Treina o seu modelo e retorna as predições
naive_bayes = MultinomialNB()
naive_bayes.fit(X_train_cv, y_train)
predictions = naive_bayes.predict(X_test_cv)
# Checagem dos resultados
print('Predicoes do modelo:')
print(predictions)
print('\n')
# Novos dados
X_new_data = \
['the queen of the day the master of good pretending dreams with the grace of rain']
#########
## ERRO
#########
# Se passar os dados diretos sem usar o CountVectorizer da erro,
# pois voce vai estar passando string ou lista quando a classe
# esta esperando uma matriz de frequencia
banda = naive_bayes.predict(X_new_data)
print(f'A banda e: {banda}')
##########
## SOLUCAO
##########
# Se voce passar no CountVectorizer ele vai pegar as palavras
# verificar os termos que estao no dicionario, e gerar a matrix
# de frequencia com as palavras correspondentes
# Transforma o novo documento em uma matriz de frequencia (term-document matrix)
X_new_data_cv = cv.transform(X_new_data)
# E agora o predict consegue aceitar o documento
banda = naive_bayes.predict(X_new_data_cv)
print(f'A banda e: {banda}')
# Referencias
# [1] - https://towardsdatascience.com/brazilian-heavy-metal-an-exploratory-data-analysis-using-nlp-and-lda-f92324d0381e
# [2] - https://towardsdatascience.com/naive-bayes-document-classification-in-python-e33ff50f937e