Skip to content

Instantly share code, notes, and snippets.

@lucaspg96
Created February 18, 2018 13:12
Show Gist options
  • Save lucaspg96/000359651a41cf617bdffdffe25bf221 to your computer and use it in GitHub Desktop.
Save lucaspg96/000359651a41cf617bdffdffe25bf221 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Classificador de notícias"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import math\n",
"import re\n",
"import matplotlib.pyplot as plt\n",
"from lxml import etree as et\n",
"\n",
"#Imports nltk ---------------------------------------------\n",
"import nltk\n",
"from nltk.stem.snowball import SnowballStemmer\n",
"\n",
"#Imports sklearn\n",
"\n",
"#tfidf\n",
"from sklearn.feature_extraction.text import TfidfTransformer\n",
"from sklearn.feature_extraction.text import CountVectorizer\n",
"\n",
"#naive bayes\n",
"from sklearn.naive_bayes import GaussianNB\n",
"from sklearn.naive_bayes import MultinomialNB\n",
"from sklearn.naive_bayes import BernoulliNB\n",
"\n",
"#regressão logística\n",
"from sklearn.linear_model import LogisticRegression\n",
"\n",
"#knn\n",
"from sklearn.neighbors import KNeighborsClassifier"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Importando stopwords e stemmer"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"stemmer = SnowballStemmer('portuguese')\n",
"stopwords = nltk.corpus.stopwords.words('portuguese')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Importando notícias"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total de notícias: 2109\n",
"Noticias para classificação: 1958\n"
]
},
{
"data": {
"image/png": "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\nl6TO/X+BTHi1VYvUJgAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f509a203fd0>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"title: 2109 ocorrências\n",
"description: 1341 ocorrências\n",
"text: 1667 ocorrências\n",
"when: 2109 ocorrências\n",
"link: 2109 ocorrências\n",
"image: 2109 ocorrências\n",
"pubDate: 1610 ocorrências\n"
]
}
],
"source": [
"parser = et.XMLParser(recover=True)\n",
"data = et.parse(\"news_data.xml\", parser=parser).getroot()\n",
"news = []\n",
"labels = []\n",
"\n",
"tags = [\"title\",\"link\",\"pubDate\",\"description\",\"image\",\"text\",\"when\"]\n",
"hist = {}\n",
"for t in tags:\n",
" hist[t] = 0;\n",
"total = len(data.findall(\"item\"))\n",
"\n",
"for c in data.findall(\"item\"):\n",
" #id = c.get(\"id\")\n",
" aux = \"\"\n",
" text = c.find(\"text\").text\n",
" desc = c.find(\"description\").text\n",
" if not text == None:\n",
" aux += text\n",
" if not desc == None:\n",
" aux += desc\n",
" if aux!=\"\":\n",
" news.append(aux)\n",
" labels.append(c.get(\"category\"))\n",
" \n",
" for t in tags:\n",
" if c.find(t).text != None:\n",
" hist[t] += 1\n",
"\n",
"print(\"Total de notícias: {}\".format(total))\n",
"print(\"Noticias para classificação: {}\".format(len(news)))\n",
"\n",
"plt.bar(range(len(hist)),hist.values(),align='center')\n",
"plt.xticks(range(len(hist)),hist.keys())\n",
"plt.show()\n",
"\n",
"for k in hist.keys():\n",
" print(\"{}: {} ocorrências\".format(k,hist[k]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Análise dos atributos das notícias\n",
"\n",
"Através do histograma acima, podemos analizar que todas as notícias possuem data(when), link, imagem e título.\n",
"\n",
"* Imagem e link não são interpretáveis para o nosso problema, logo não compensa que coloquemos estes atributos em nosso classificador;\n",
"* Data(when) e data de publicação, embora sejam interpretáveis, é provável que não acrescentem nenhuma informação relevante para nossa classificação;\n",
"* Texto, título e descrição podem ser bastante úteis em nosso problema, embora o título, devido a sua natureza mais interativa para chamar a atenção, possa atrapalhar nos cálculos, portanto, colocaremos ele de fora da classificação."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Iniciando pré-processamento\n",
"\n",
"### Processando notícias"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'A rodada deste fim de semana ainda não confirmou o título do Corinthians, que segue com mais de 99% de chance de conquista, contra menos de 1% do Atlético Mineiro segundo o site Infobola, do matemático Tristão Garcia. Para o Galo, o triunfo sofre o Figueirense, com um gol no finzinho, além de manter a chance matemática de título para os mineiros, também confirmou o time com uma das vagas para a Libertadores. Para as vagas que restam para a competição sul-americana, o Grêmio, embora derrotado pelo Sport, segue bem tranquilo. Só uma catástrofe tira o time gaúcho da vaga 3 e por isso suas chances estão em 96%. Daí para a frente, a coisa embola um pouco. A rodada fez o leque de possibilidades se ampliar. Um exemplo é que o Flamengo saiu do traço e voltou a ter uma pequena chance após a sua vitória e os resultados dos rivais. Afinal, quem estava bem à frente não venceu. Santos, São Paulo e Internacional seguem bem cotados. O Sport (que tem uma tabela bem complicada e por isso está com apenas 7%) precisa de mais um bom resultado na próxima rodada para se aproximar da trinca. Ponte Preta, Palmeiras, Cruzeiro e o Rubro-Negro (que respira graças ao seu bom número de vitórias que lhe dará vantagem caso empate em pontos contra qualquer um dos demais concorrentes) respiram por aparelho. Na turma que tenta escapar da degola, o Vasco segue construindo notável reação. Embora ainda apareça com 84% de possibilidade de rebaixamento, o Cruz-Maltino conseguiu resultado pouco esperado, a vitória sobre o Palmeiras fora de casa, e pode dar um supersalto rumo à salvação já na próxima rodada quando ocorrem dois jogos de rivais diretos pelo rebaixamento: Goiás x Coritiba e Avaí x Joinville. Olho vivo no Figueirense. A série de resultados ruins fez o time encostar muito no bolo dos desesperados. Já a Chapecoense, com a vitória sobre o Fluminense, se despediu dessa briga.'"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"news[0]"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"#Removendo stopwords, aplicando stemmer e \"tokenizando\"\n",
"data_processed = []\n",
"for k in news:\n",
" tokenizedText = nltk.word_tokenize(k)\n",
" stemmedText = [stemmer.stem(t) for t in tokenizedText if t not in stopwords]\n",
" data_processed.append(stemmedText)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"#Removendo caracteres indesejáveis\n",
"#undesired = [',','.',\"'\",'\"','´',';',':','-','?','!','%','(',')']\n",
"undesired = [str(',').encode('utf-8'),\n",
" str('.').encode('utf-8'),\n",
" str(\"'\").encode('utf-8'),\n",
" str('\"').encode('utf-8'),\n",
" str(';').encode('utf-8'),\n",
" str(':').encode('utf-8'),\n",
" str('-').encode('utf-8'),\n",
" str('?').encode('utf-8'),\n",
" str('!').encode('utf-8'),\n",
" str('%').encode('utf-8'),\n",
" str('(').encode('utf-8'),\n",
" str(')').encode('utf-8')\n",
" ]\n",
"for data in data_processed :\n",
" for word in data:\n",
" if word in undesired:\n",
" word.encode('utf-8')\n",
" data.remove(word)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'a rod dest fim seman aind confirm títul corinthians , seg 99 % chanc conquist , contr men 1 % atlét mineir segund sit infobol , matemát tristã garc . par gal , triunf sofr figueirens , gol finzinh , além mant chanc matemát títul mineir , confirm tim vag libert . par vag rest competiçã sul-american , grêmi , embor derrot sport , seg bem tranquil . só catástrof tir tim gaúch vag 3 chanc 96 % . daí frent , cois embol pouc . a rod fez lequ possibil ampli . um exempl é flameng saiu trac volt ter pequen chanc após vitór result riv . afinal , bem frent venc . sant , sã paul internacional segu bem cot . o sport ( tabel bem complic apen 7 % ) precis bom result próxim rod aproxim trinc . pont pret , palmeir , cruzeir rubro-negr ( resp grac bom númer vitór dar vantag cas empat pont contr qualqu dem concorrent ) resp aparelh . na turm tent escap degol , vasc seg constru notável reaçã . embor aind aparec 84 % possibil rebaix , cruz-maltin consegu result pouc esper , vitór sobr palmeir cas , pod dar supersalt rum salvaçã próxim rod ocorr dois jog riv diret rebaix : goiás x coritib ava x joinvill . olho viv figueirens . a séri result ruins fez tim encost bol desesper . já chapecoens , vitór sobr fluminens , desped dess brig .'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#Reescrevendo noticias\n",
"new_data = []\n",
"for data in data_processed:\n",
" new_data.append(\" \".join(data))\n",
"\n",
"data_processed = new_data\n",
"\n",
"data_processed[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Iniciando classificação"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Preparando dados para classificação"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"#Permutação dos dados\n",
"temp = np.column_stack((data_processed,labels))\n",
"temp = np.random.permutation(temp)\n",
"data_processed = temp[:,0]\n",
"labels = temp[:,1]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/lucaspg/miniconda3/envs/analyse/lib/python3.5/site-packages/ipykernel_launcher.py:6: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future\n",
" \n",
"/home/lucaspg/miniconda3/envs/analyse/lib/python3.5/site-packages/ipykernel_launcher.py:7: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future\n",
" import sys\n"
]
}
],
"source": [
"#Separação das labels de treino e teste\n",
"p = 70\n",
"size = len(data_processed)\n",
"partition = (size*p/100)\n",
"\n",
"trainLabels = labels[0:partition]\n",
"testLabels = labels[partition:size]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Gerando matrizes dos dados"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"cv = CountVectorizer()\n",
"\n",
"X_counts = cv.fit_transform(data_processed)\n",
"tf_transformer = TfidfTransformer(use_idf=True).fit(X_counts)\n",
"X_tf = tf_transformer.transform(X_counts)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Separando features de treino e teste"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"size = X_tf.shape[0]\n",
"partition = math.floor(size*p/100)\n",
"\n",
"trainText = X_tf[0:partition]\n",
"testText = X_tf[partition:size]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Classificando"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Multinomial: 60.54% de precisão\n",
"Gaussian: 71.94% de precisão\n",
"Bernoulli: 64.97% de precisão\n",
"Regressão: 71.60% de precisão\n",
"KNN: 75.68% de precisão\n"
]
}
],
"source": [
"clf_multinomial = MultinomialNB().fit(trainText, trainLabels)\n",
"print(\"Multinomial: {0:.2f}% de precisão\".format(clf_multinomial.score(testText,testLabels)*100))\n",
"\n",
"clf_gaussian = GaussianNB().fit(trainText.toarray(), trainLabels)\n",
"print(\"Gaussian: {0:.2f}% de precisão\".format(clf_gaussian.score(testText.toarray(),testLabels)*100))\n",
"\n",
"clf_bernouli = BernoulliNB().fit(trainText.toarray(), trainLabels)\n",
"print(\"Bernoulli: {0:.2f}% de precisão\".format(clf_bernouli.score(testText.toarray(),testLabels)*100))\n",
"\n",
"clf_logistic = LogisticRegression().fit(trainText.toarray(), trainLabels)\n",
"print(\"Regressão: {0:.2f}% de precisão\".format(clf_logistic.score(testText.toarray(),testLabels)*100))\n",
"\n",
"clf_knn = KNeighborsClassifier(n_neighbors=7).fit(trainText.toarray(), trainLabels)\n",
"print(\"KNN: {0:.2f}% de precisão\".format(clf_knn.score(testText.toarray(),testLabels)*100))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"def process_new(new):\n",
" tokenizedText = nltk.word_tokenize(new)\n",
" stemmedText = [stemmer.stem(t) for t in tokenizedText if t not in stopwords]\n",
"\n",
" text = [word for word in stemmedText if not word in undesired]\n",
" text = \" \".join(text)\n",
" cv_text = cv.transform([text])\n",
" \n",
" return tf_transformer.transform(cv_text)\n",
"\n",
"def classify_new(new):\n",
" processed_new = process_new(new)\n",
" \n",
" print(\"Multinomial: {}\".format(clf_multinomial.predict(processed_new)))\n",
" print(\"Bernouli: {}\".format(clf_bernouli.predict(processed_new)))\n",
" print(\"Gaussian: {}\".format(clf_gaussian.predict(processed_new.toarray())))\n",
" print(\"Logistic: {}\".format(clf_logistic.predict(processed_new.toarray())))\n",
" print(\"KNN: {}\".format(clf_knn.predict(processed_new.toarray())))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Teste com uma notícia"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Multinomial: ['esporte']\n",
"Bernouli: ['esporte']\n",
"Gaussian: ['esporte']\n",
"Logistic: ['esporte']\n",
"KNN: ['esporte']\n"
]
}
],
"source": [
"new = \"A rodada deste fim de semana ainda não confirmou o título do Corinthians, que segue com mais de 99% de chance de conquista, contra menos de 1% do Atlético Mineiro segundo o site Infobola, do matemático Tristão Garcia. Para o Galo, o triunfo sofre o Figueirense, com um gol no finzinho, além de manter a chance matemática de título para os mineiros, também confirmou o time com uma das vagas para a Libertadores. Para as vagas que restam para a competição sul-americana, o Grêmio, embora derrotado pelo Sport, segue bem tranquilo. Só uma catástrofe tira o time gaúcho da vaga 3 e por isso suas chances estão em 96%. Daí para a frente, a coisa embola um pouco. A rodada fez o leque de possibilidades se ampliar. Um exemplo é que o Flamengo saiu do traço e voltou a ter uma pequena chance após a sua vitória e os resultados dos rivais. Afinal, quem estava bem à frente não venceu. Santos, São Paulo e Internacional seguem bem cotados. O Sport (que tem uma tabela bem complicada e por isso está com apenas 7%) precisa de mais um bom resultado na próxima rodada para se aproximar da trinca. Ponte Preta, Palmeiras, Cruzeiro e o Rubro-Negro (que respira graças ao seu bom número de vitórias que lhe dará vantagem caso empate em pontos contra qualquer um dos demais concorrentes) respiram por aparelho. Na turma que tenta escapar da degola, o Vasco segue construindo notável reação. Embora ainda apareça com 84% de possibilidade de rebaixamento, o Cruz-Maltino conseguiu resultado pouco esperado, a vitória sobre o Palmeiras fora de casa, e pode dar um supersalto rumo à salvação já na próxima rodada quando ocorrem dois jogos de rivais diretos pelo rebaixamento: Goiás x Coritiba e Avaí x Joinville. Olho vivo no Figueirense. A série de resultados ruins fez o time encostar muito no bolo dos desesperados. Já a Chapecoense, com a vitória sobre o Fluminense, se despediu dessa briga.\"\n",
"\n",
"classify_new(new)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Quem sabe faz ao vivo!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"new = \"\"\"\n",
"\n",
"\"\"\"\n",
"\n",
"classify_new(new)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.3"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment