Classificação de Texto com Naive Bayes
para entender como realizar a classificação de texto usando o Naive Bayes algoritmo, precisamos primeiro definir o conjunto de dados, vamos usar e importá-lo.
o conjunto de dados que vamos usar é o conjunto de dados de 20 newsgroups (link de download). O conjunto de dados compreende cerca de 18.000 posts de newsgroups sobre 20 tópicos divididos em dois subconjuntos: um para treinamento (ou desenvolvimento) e outro para teste (ou para avaliação de desempenho).
a divisão entre o conjunto de trem e teste é baseada em mensagens postadas antes e depois de uma data específica. Em alternativa, pode fazer o download e extraia os arquivos em Scikit-aprender a utilizar:
from sklearn.datasets import fetch_20newsgroups
neste tutorial, vamos focar em cinco categorias na nossa variável-alvo, nomeadamente alt.atheism
, soc.religion.christian
, talks.politics.misc
, comp.graphics
, e sci.med
, que especifica no trem e conjuntos de teste, como mostrado abaixo:
categories = news_train = fetch_20newsgroups(subset='train', categories=categories, shuffle=True)
news_test = fetch_20newsgroups(subset='test', categories=categories, shuffle=True)
para acessar o alvo nomes de nossos dados de treinamento, nós pode imprimi-lo em uma célula de uma Jupyter notebook por print(news_train)
. Da mesma forma, podemos ver o conteúdo dos dados de treinamento por print(news_train)
— que essencialmente é um dicionário de textos.
preparação de dados& Modelagem
agora precisamos cobrir alguns conceitos importantes no processo de classificação de texto. Vamos usar uma classe especial de sklearn.feature_extraction.text
chamada CountVectorizer
. Portanto, a ideia é que, dado que temos uma string de texto, podemos atribuir números únicos a cada uma das palavras do texto.
depois de atribuir os números únicos, contamos a ocorrência desses números. Esse conceito de atribuição de números únicos a cada uma das palavras em um texto é chamado de tokenização. Vamos dar uma olhada em um exemplo:
Example Text: The boy in green shirt is sitting on the chair.Assigning unique number to each word gives:
{'the': 9, 'boy': 0, 'in': 4, 'green': 3, 'shirt': 7, 'is': 5, 'sitting': 8, 'on': 6, 'chair': 2}
Assim, as características do vocabulário dicionário como mostrado abaixo:
podemos implementar esta em Scikit-aprender com o fragmento de código abaixo:
from sklearn.feature_extraction.text import CountVectorizer
text =
vector = CountVectorizer()
vector.fit(text)#learn a vocabulary dictionary of all tokens in the raw documents
print("Print Vocabulary: "+str(vector.vocabulary_)+'\n\n')vector.get_feature_names()
print("Feature names:"+str(vector.get_feature_names())+'\n\n')counts = vector.transform(text)
print("The shape of count is: "+str(counts.shape)+'\n\n')
#Only 1 sample space and it has 8 features
print("Printing count: "+'\n'+str(counts.toarray()))
tome nota, no entanto, que, para usar o CountVectorizer
, primeiro temos que importar a classe, criar uma instância da classe que chamamos de vector
, e chamar a fit
método para aprender o vocabulário de matérias documento. O método transform
conta as ocorrências de cada palavra: basicamente em termos de ML, dizemos “codificação de documentos”. Os resultados do snippet são o dicionário de vocabulário, nomes de recursos e forma e a contagem de recursos.

Isto parece promissor. No entanto, uma coisa a notar que você pode ter descoberto é que palavras como “o” tendem a aparecer com frequência em quase todos os documentos de texto. Como tal, a contagem da palavra “o” não significa necessariamente que seja importante na classificação.
existem maneiras de lidar com isso:
- removendo o que chamamos de palavras de parada (palavras comumente ocorrendo em inglês, como artigos, preposições, etc) e/ou
- introduzindo um conceito chamado frequência de Documento inverso de frequência de termo (TF-IDF). Em resumo, TF-IDF primeiro conta o número de vezes que uma determinada palavra aparece em um documento e, em seguida, dá um peso à palavra, o que delineia sua importância na classificação. Então, vamos ver como isso é feito em Python:
from sklearn.feature_extraction.text import TfidfTransformer
vectorizer = TfidfTransformer()
vectorizer.fit(counts)
print('Learning Frequency of all features:'+str(vectorizer.idf_)+'\n\n')
freq = vectorizer.transform(counts)
print('Transforming the matrix based on the learnt frequencies or weight: \n\n'+str(freq.toarray()))
Novamente, vamos importar o TfidfTransformer
, crie uma instância da classe e chamar o fit
método passando como argumento a matriz de contagens devolvidos por CountVectorizer
no bloco anterior—e, finalmente, usamos o transform
método para atribuir relevantes pesos a esses recursos, como impresso abaixo:

Agora que temos uma compreensão sólida de CountVectorizer
e TF-IDF, podemos repetir os mesmos passos para os nossos 20 de notícias do grupo de conjunto de dados.
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer()
X_train_tf = count_vect.fit_transform(news_train.data)from sklearn.feature_extraction.text import TfidfTransformer
tfidf_transformer = TfidfTransformer()
X_train_tfidf = tfidf_transformer.fit_transform(X_train_tf)
agora que a respectiva transformação e atribuição de pesos foi feita, agora é hora de realmente construir o modelo ingênuo de Bayes :).
fazemos isso através da importação de MultiNomialNB
de sklearn.naive_bayes
para ajustar o modelo para o conjunto de treinamento:
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB().fit(X_train_tfidf, news_train.target)
podemos criar nossas próprias frases para testar as previsões do classificador:
docs_new =
X_new_counts = count_vect.transform(docs_new)
X_new_tfidf = tfidf_transformer.transform(X_new_counts)
predicted = clf.predict(X_new_tfidf)

Como podemos ver ele executa muito bem, classificando os documentos em docs_new
em suas respectivas metas.