Upload
iam-malcolm
View
68
Download
2
Embed Size (px)
DESCRIPTION
TCC
Citation preview
Universidade Estadual de Maringá
Centro de Tecnologia
Departamento de Informática
Maringá-Paraná
2012
Proposta de um Sistema Inteligente para
Recomendação de News
Nathan Siegle Hartmann
Trabalho de Graduação – 2012
Universidade Estadual de Maringá
Centro de Tecnologia
Departamento de Informática
i
Maringá-Paraná
2012
Proposta de um Sistema Inteligente para
Recomendação de News
Nathan Siegle Hartmann
Trabalho de Graduação – 2012
Trabalho de Graduação do Curso de Ciência da
Computação, do Centro de Tecnologia, da Universidade
Estadual de Maringá.
Orientador: Prof. Dr. Sérgio Roberto Pereira da Silva
ii
Maringá – Paraná
2012
Nathan Siegle Hartmann
Proposta de um Sistema Inteligente para
Recomendação de News
Este exemplar corresponde à redação final da monografia aprovada como requisito
parcial para obtenção do grau de Bacharel em Ciência da Computação da Universidade
Estadual de Maringá, pela Banca Examinadora formada pelos seguintes membros:
____________________________________
Orientador: Prof. Dr. Sérgio Roberto Pereira da Silva
Departamento de Informática, CTC, DIN
____________________________________
Prof. Me. Marco Aurélio Lopes Barbosa
Departamento de Informática, CTC, DIN
____________________________________
Profa. Dr. Valéria Delisandra Feltrim
Departamento de Informática, CTC, DIN
iii
Agradecimentos
Agradeço aos meus pais, por terem aceitado minha decisão em fazer este curso de
graduação e também por terem me apoiado durante minha caminhada.
Agradeço a Deus, por ter me guiado durante não só a execução deste trabalho de
conclusão de curso, mas durante toda minha jornada na graduação.
Agradeço por fim ao meu orientador Prof. Dr. Sérgio Roberto Pereira da Silva por
ter compartilhado seus conhecimentos e experiências ao longo de minha orientação,
sendo fundamental para a elaboração deste trabalho.
iv
Resumo
A recomendação de notícias é uma subárea da área de recomendação de informação,
sendo que a principal diferença entre elas é o aspecto temporal da notícia, ou seja, sua
perda de relevância com o decorrer do tempo. Um problema destacado nessa área é a
dificuldade em encontrar um equilíbrio entre a qualidade dos resultados gerados e a
eficiência do processamento dos dados. Para tentar obter uma boa relação entre
desempenho e qualidade é utilizado nesse trabalho um classificador Naive Bayes para
separar as notícias em classes de interesse do usuário, bem como a técnica de
similaridade pelo cosseno para a criação de um ranking de notícias a serem
apresentadas. Por fim, também é realizada a personalização da apresentação das
notícias, por meio da criação de um modelo de interesse do usuário com o uso de
feedback explicito.
Palavras-chave
Recomendação de Notícias, Modelagem do interesse do usuário, Recuperação de
Informação.
v
Abstract
News recommendation is a subarea of information recommendation. The mainly
difference between them is the temporal aspect of news, i.e., its loss of relevance after
some time. A highlighted problem in this area is the difficulty to find a balance between
the quality of the results and the efficiency of the data processing. Trying to get a good
trade-off between performance and quality, a Naïve Bayes classifier was used in this
paper to sort out the news in categories according to the user’s interest. The cosine
similarity technique was used in order to create a ranking of news to be showed.
Finally, a personalization of the news display is also made through the creation of the
user’s interest model with the use of explicit feedback.
Key-words
News Recommendation, User Interesting Modeling, Information Retrieval.
vi
Sumário
1 INTRODUÇÃO ......................................................................................................................... 1
2 REVISÃO BIBLIOGRÁFICA ................................................................................................. 3
2.1 A Recuperação de Informação .................................................................................................... 3
2.2 Classificação de novas notícias ................................................................................................... 4
2.2.1 Pré-processamento do Texto .................................................................................................. 4
2.2.2 Técnicas para classificação de documentos ........................................................................... 6
2.3 Personalização ............................................................................................................................ 6
2.3.1 Cálculo de Similaridade entre Documentos ........................................................................... 6
2.3.2 Relevance Feedback ............................................................................................................... 7
3 DESENVOLVIMENTO ........................................................................................................... 9
3.1 O Pré-Processamento .................................................................................................................. 9
3.2 O Treinamento do Classificador ............................................................................................... 11
3.3 A classificação .......................................................................................................................... 12
3.4 A apresentação .......................................................................................................................... 14
3.5 Modelagem do Interesse do Usuário ......................................................................................... 16
3.6 Relevance Feedback .................................................................................................................. 16
3.7 Recomendação .......................................................................................................................... 18
3.8 As Classes do Sistema .............................................................................................................. 20
3.9 Bibliotecas e Frameworks Utilizados ....................................................................................... 23
3.9.1 BeautifulSoup ....................................................................................................................... 23
3.9.2 CherryPy............................................................................................................................... 23
3.9.3 Feedparser ............................................................................................................................ 24
3.9.4 NLTK .................................................................................................................................... 24
3.9.5 Reverend ............................................................................................................................... 24
4 ANÁLISE DOS RESULTADOS ............................................................................................ 25
4.1 Modelos de Representação........................................................................................................ 25
4.2 Qualidade do Ranking de Notícias ............................................................................................ 25
4.3 Custo de Processamento do Sistema ......................................................................................... 27
vii
4.4 Desempenho de 20% e 100% de Termos Utilizados até a Classificação .................................. 28
4.5 Representação de Notícias por meio de Títulos e Sumários ..................................................... 30
5 CONCLUSÕES ....................................................................................................................... 33
6 REFERÊNCIAS BIBLIOGRÁFICAS .................................................................................. 35
7 APÊNDICE .............................................................................................................................. 38
7.1 Websites utilizados para recuperar notícias ............................................................................... 38
7.2 Código Fonte ............................................................................................................................. 40
7.2.1 Main ...................................................................................................................................... 40
7.2.2 NewsSearch .......................................................................................................................... 41
7.2.3 ClassifierTrainer .................................................................................................................. 44
7.2.4 PreProcessing ....................................................................................................................... 48
7.2.5 Scorer ................................................................................................................................... 50
7.2.6 User ...................................................................................................................................... 54
7.2.7 News ..................................................................................................................................... 57
7.2.8 Web ....................................................................................................................................... 58
viii
Lista de Figuras
Figura 1. Componentes de um sistema recuperador de informação (Cardoso, 2000). 3
Figura 2. Equação para o cálculo da similaridade pelo cosseno (Huang, 2008). ....... 7
Figura 3. Equação para o cálculo do coeficiente de Jaccard (Huang, 2008). ............. 7
Figura 4. Visão geral do sistema. ................................................................................ 9
Figura 5. Pré-processamento das notícias. ................................................................ 11
Figura 6. Treinamento do classificador Naive Bayes. .............................................. 12
Figura 7. Classificação de novas notícias. ................................................................ 13
Figura 8. Equação de decaimento de relevância de uma notícia. ............................. 13
Figura 9. Interface da tela inicial do protótipo. ......................................................... 14
Figura 10. Interface da tela de notícias de tecnologia. .............................................. 15
Figura 11. Feedback positivo e interesse do usuário. ............................................... 17
Figura 12. Feedback negativo e o interesse do usuário. ........................................... 17
Figura 13. Página de notícias recomendadas ao usuário........................................... 19
Figura 14. Diagrama de classe do sistema. ............................................................... 21
Figura 15. Ranking das notícias por categorias utilizando 100% dos termos para
representação de notícias. ......................................................................................... 27
Figura 16. Custo de processamento do sistema utilizando 100% de termos do texto.
.................................................................................................................................. 28
Figura 17. Ranking das notícias por categorias utilizando “título” e “sumário” para
representação de documentos. .................................................................................. 31
ix
Lista de Tabelas
Tabela 1. Quantidade de websites vistoriados para a aprendizagem do classificador
Naive Bayes. ............................................................................................................. 12
Tabela 2. Algumas funcionalidades da biblioteca Feedparser. ................................ 24
Tabela 3. Resultado do teste de qualidade do ranking de notícias. .......................... 26
Tabela 4. Resultado do teste de desempenho do sistema.......................................... 27
Tabela 5. Comparação de desempenho entre 20% e 100% de termos de documentos
utilizados. .................................................................................................................. 29
Tabela 6. Comparação de desempenho entre a utilização de “título” e “sumário” e
de 100% de termos de documentos. .......................................................................... 30
Tabela 7. Resultado do teste de qualidade do ranking de notícias com a utilização de
“título” e “sumário” como forma de representação de documentos. ........................ 31
1
1 Introdução
A Internet é um sistema público mundial ao qual qualquer pessoa possui acesso por
meio de um computador. A invenção da Internet possibilitou que a informação fosse
registrada em um domínio de acesso público (Surface Web) (Meng & Yu, 2010),
facilitando a visualização desse conteúdo. O início da era da Internet foi composto por
poucos websites, consequentemente pouca informação estava disponível na rede de
computadores.
Atualmente a World Wide Web Size (2012), website mantido pela Tilburg
University, garante que a Internet possui ao menos 8,23 bilhões de páginas indexadas na
Surface Web e, segundo Meng & Yu (2010), estima-se mais de 900 bilhões de websites
contidos na Deep Web (porção de websites que não são públicos). Com essas
informações percebe-se que há uma quantidade excessiva de informação disponível na
Internet, fenômeno que torna a pesquisa do usuário, por um assunto específico,
desgastante e muitas vezes demorada. Esse problema é conhecido como sobrecarga de
informação (information overload) e ocorre quando o usuário possui muita informação
ao seu alcance, porém, não tem condições de tratá-la e encontrar o que realmente deseja
ou lhe interessa (Chen, 1994).
A Internet está repleta de páginas que apresentam notícias (news), na maioria das
vezes diárias, divulgando acontecimentos sobre diversos temas. Um ponto que
diferencia essas páginas das demais é que as notícias têm um forte aspecto temporal, ou
seja, depois de passado determinado tempo, elas já não apresentam o mesmo valor
informativo. Outro problema importante é a distinção entre notícias relevantes e não
relevantes. Essa distinção pode ser feita obtendo notícias apenas de fontes que possuam
autoridade nos assuntos publicados (Rieh, 2002), ou seja, que informem notícias de
qualidade. Apesar dessa distinção poder ser feita, identificar quais dessas informações
são relevantes não é uma tarefa simples para o usuário. Para isso pode ser utilizada a
recomendação de informação.
A recomendação de notícias pode ser formulada como um problema de
classificação. Conforme citado por Marmanis & Babenko (2009), Jannach, Janker,
Felfernig, & Friedrich (2011), Owen, Anil, Dunning, & Friedman (2012) e Alag (2009),
sobre a criação de sistemas recomendadores de informação, o uso de aprendizagem de
máquina é um meio de se classificar a informação, tornando mais rápido o acesso aos
2
dados. Em particular, as técnicas de aprendizagem supervisionada baseiam-se em um
conteúdo de treinamento existente, o qual, neste trabalho, são os documentos que
definem cada uma das categorias de notícias que possam vir a ser utilizadas.
O objetivo deste trabalho é desenvolver um sistema recomendador de informação,
focado em notícias em língua inglesa, que considere o aspecto temporal de tal conteúdo.
Para tanto, são acessados websites que possuam autoridade na publicação de notícias. A
partir do acesso a essas páginas é feita a extração e o processamento da informação
contida, a aplicação de técnicas de aprendizagem de máquina para classificar os dados
em classes que melhor os representem e, por fim, a personalização e o armazenamento
das notícias classificadas.
As seções que seguem serão divididas da seguinte maneira: na Seção 2 serão
apresentados os conceitos relevantes ao desenvolvimento do trabalho, que são:
recuperação de informação, o pré-processamento dessa informação, a classificação de
notícias e a utilização de relevance feedback na personalização da recuperação de
informação. Na Seção 3 é apresentado o corpo do trabalho, que consiste no
desenvolvimento de um sistema de recomendação de notícias recuperadas da Web. Na
Seção 4 é apresentada a análise dos resultados provenientes de diversos testes. Por fim,
na Seção 5 são apresentadas conclusões acerca deste trabalho.
3
2 Revisão Bibliográfica
Para entender os problemas inerentes à recuperação de notícias, é preciso entender o
conceito de Recuperação de Informação (RI) e como ele pode ser aplicado no escopo de
notícias. Também é necessário estudar técnicas que possibilitem a criação de um
classificador que filtre as notícias em suas devidas categorias. Além disso, é interessante
estudar meios para modelar o interesse do usuário e como essa modelagem pode ser
empregada na recomendação de informação. Com estas técnicas, é possível personalizar
a recomendação de notícias para apresentar as de maior relevância ao usuário.
2.1 A Recuperação de Informação
A atividade de recuperação de informação, em geral, preocupa-se com as operações
de indexação e seleção de documentos, geralmente textos (Cardoso, 2000), que
forneçam uma resposta a uma demanda (necessidade por informação) de usuários
(Ferneda, 2003).
Figura 1. Componentes de um sistema recuperador de informação (Cardoso, 2000).
Um sistema recuperador de informação pode ser estruturado como apresentado na
Figura 1. Do lado esquerdo da figura se tem os documentos buscados e indexados pelo
sistema. De outro lado, encontra-se o usuário e sua necessidade de informação,
especificada no sistema na forma de uma consulta. Fazendo-se uso de técnicas que
relacionem o interesse do usuário com os documentos indexados pelo sistema, pode-se
recuperar as informações de interesse do usuário.
4
A diferença entre a recuperação de notícias e a recuperação de informação está no
aspecto temporal da notícia. A informação, na maioria das vezes, não perde seu valor
informativo com o passar do tempo, já a notícia sim. Uma notícia que poderia ser
relevante há uma semana, hoje pode não ser mais. Esse aspecto temporal influencia
diretamente a maneira como a relevância de uma notícia deve ser calculada, produzindo
um resultado que decaia com o passar do tempo.
Após ser feita a recuperação de notícias é preciso agrupar os documentos resultantes
em áreas de interesse, de forma a possibilitar uma melhor visualização deste conteúdo
por parte do usuário. Para este trabalho foram escolhidas as áreas de interesse: esporte,
ciência, mundo, negócios, saúde e tecnologia. A classificação das notícias nas áreas de
interesse escolhidas pode ser feita com o uso de técnicas de classificação.
2.2 Classificação de novas notícias
Em alguns casos, o escopo (conjunto de trabalho) das notícias a serem trabalhadas
é suficientemente complexo para que o processamento destes dados seja um gargalo no
sistema. Esse fenômeno influencia, entre outras atividades, o desempenho da
classificação de informação, em específico, ele é mais sério na classificação de notícias
devido ao seu volume e volatilidade. Uma maneira de minimizar o tempo de
processamento da classificação de notícias é por meio da inserção de uma etapa de pré-
processamento, a fim de retirar as informações consideradas irrelevantes à sua
classificação. A diminuição do volume de dados presentes em um documento implica
em um melhor tempo de processamento do mesmo.
2.2.1 Pré-processamento do Texto
É possível otimizar o processamento de notícias na tarefa de recomendação de
informação, fazendo uso de técnicas como a aplicação de stemming, a eliminação de
stop words e reduzindo a quantidade de termos dos documentos (Jannach, Janker,
Felfernig, & Friedrich, 2011). Estas técnicas são descritas a seguir.
O conceito de stop words representa todas as preposições e artigos, além de termos
sem valor no domínio em questão, que podem ser removidos do documento sem alterar
o resultado dos algoritmos que realizam cálculos de similaridades de documentos
5
(Jannach, Janker, Felfernig, & Friedrich, 2011). Em geral, aplica-se a filtragem das stop
words logo após a extração do texto de sua fonte.
O termo stemming, ou conflation, consiste na substituição de palavras pelos seus
radicais (root word), com o intuito de reduzir o conjunto de termos de trabalho e
aumentar a frequência das palavras que representam um mesmo termo. Essa técnica
comumente utiliza análises morfológicas, como por exemplo o algoritmo Porter’s
suffix-stripping (Porter, 1980) e a busca de palavras em bases como a WordNet
(Fellbaum, 1998).
Um problema com o stemming é que essa técnica pode reduzir duas palavras com
funções linguísticas diferentes (e.g. substantivo e verbo) ao mesmo radical, mas que na
prática não se referem ao mesmo termo (Jannach, Janker, Felfernig, & Friedrich, 2011).
Uma solução para este problema é a utilização da técnica de lematização, a qual difere
do stemming por não perder a função linguística das palavras analisadas (Manning,
Raghavan, & Schütze, 2008). Em geral a lematização produz melhores resultados do
que o stemming, porém com uma carga maior de processamento. Neste trabalho, foi
escolhido utilizar a técnica de stemming, visando obter um melhor desempenho do
sistema.
A redução do número de elementos a serem trabalhados é um método que busca, por
meio da redução de dimensionalidade do documento, reduzir os ruídos contidos nos
dados e também melhorar o desempenho do seu processamento, utilizando apenas os
termos mais relevantes do conteúdo (Jannach, Janker, Felfernig, & Friedrich, 2011).
Segundo o princípio 80/20 de Vilfredo Pareto, 80% dos resultados são provenientes de
20% dos esforços utilizados (Koch, 2000). Esta técnica já foi empregada por (Marchi,
2010) na tarefa de RI, produzindo uma boa relação entre ganho de desempenho e perda
de qualidade dos resultados. A relação de ganhos de desempenho versus a perda na
qualidade dos resultados é abordada na Seção 4 deste trabalho.
As técnicas de stemming, eliminação de stop words e redução do número de
elementos, foram empregadas neste trabalho visando melhorar o desempenho da
classificação de novas notícias recuperadas da Internet.
6
2.2.2 Técnicas para classificação de documentos
Existem diversas técnicas para classificação de documentos como, por exemplo, o
algoritmo probabilístico Naive Bayes (Segaran, 2007) e as técnicas matemáticas de
similaridade pelo cosseno e o coeficiente de Jaccard (Marmanis & Babenko, 2009).
O classificador Naive Bayes (Bayesiano Ingênuo) é um classificador estatístico
comumente utilizado, sendo uma de suas características a aprendizagem supervisionada
de atributos classificadores, que representam conjuntos aprendidos pelo classificador.
Neste trabalho, os conjuntos aprendidos pelo classificador são as áreas de interesse de
notícias.
Para o classificador Naive Bayes, as probabilidades dos atributos classificadores são
incondicionais, ou seja, não dependem umas das outras. Deste modo, o resultado de
uma classificação pode ser calculado pela multiplicação das probabilidades individuais
de cada atributo classificador por uma área de interesse, ou seja, ( )
( ) ( ).
2.3 Personalização
A recomendação de notícias é uma forma de personalização da recuperação de
informação. O foco da área de recomendação de informação é a localização e a
apresentação da informação relevante a um tópico específico. Em geral, sistemas
recomendadores servem a dois propósitos: estimular o usuário há realizar uma tarefa
(como comprar um livro ou assistir um filme), ou tratar a sobrecarga de informação, por
meio da seleção, em um conjunto extenso de itens, do conteúdo mais relevante ao
usuário (Jannach, Janker, Felfernig, & Friedrich, 2011).
A recomendação de informação pode ser feita com o uso de técnicas que calculam a
similaridade entre documentos como, por exemplo, a similaridade pelo cosseno e o
coeficiente de Jaccard (Marmanis & Babenko, 2009). Essas técnicas já foram
empregadas com sucesso por Marmanis & Babenko (2009) e Segaran (2007) na
construção de sistemas recomendadores. Estas técnicas são descritas a seguir.
2.3.1 Cálculo de Similaridade entre Documentos
A técnica de similaridade pelo cosseno consiste no cálculo do cosseno do ângulo
entre dois vetores n-dimensionais de termos, ⃗⃗ ⃗ e ⃗⃗ ⃗, que representam documentos,
7
conforme a equação apresentada na Figura 2. A equação calcula a divisão entre os
resultados da multiplicação entre os vetores ⃗⃗ ⃗ e ⃗⃗ ⃗ e a multiplicação da norma desses
vetores, | ⃗⃗ ⃗| e | ⃗⃗ ⃗|. A similaridade entre os dois documentos estará no intervalo [0,1] em
que valores próximos a 1 indicam uma similaridade forte e valores próximos a 0,
indicam uma similaridade fraca (Jannach, Janker, Felfernig, & Friedrich, 2011).
Figura 2. Equação para o cálculo da similaridade pelo cosseno (Huang, 2008).
A similaridade entre documentos por meio do uso da técnica do coeficiente de
Jaccard consiste na divisão entre a intersecção dos vetores ⃗⃗ ⃗ e ⃗⃗ ⃗, que representam
documentos, e também a união destes vetores, resultando na porção similar de termos
entre os dois documentos, como apresentado na Figura 3. O intervalo de valores
resultantes desta técnica está entre [0,1], em que valores próximos a 1 indicam uma
similaridade forte e, valores próximos a 0, uma similaridade fraca (Huang, 2008).
Figura 3. Equação para o cálculo do coeficiente de Jaccard (Huang, 2008).
Para utilizar as equações apresentadas na Figura 2 e na Figura 3 para cálculo de
similaridade a fim de recomendar notícias aos usuários, é necessário modelar
vetorialmente as notícias e também o interesse do usuário. Com a utilização da
representação vetorial dos dados é possível recomendar notícias com uso das técnicas
descritas. Para um sistema automatizado aprender sobre o interesse do usuário podem
ser utilizadas as técnicas de relevance feedback.
2.3.2 Relevance Feedback
Existem duas maneiras de um sistema automatizado identificar o interesse de um
usuário: requisitar a sua opinião implicitamente ou explicitamente. O feedback implícito
captura o interesse do usuário de forma transparente, utilizando técnicas como o
monitoramento das ações do usuário. Essa forma de coleta de feedback muitas vezes
gera dados equivocados, por causa da interpretação erronia das intenções do usuário
(Jannach, Janker, Felfernig, & Friedrich, 2011). O feedback explícito, por sua vez,
8
consiste em capturar o interesse do usuário de maneira explícita, requerendo sua
avaliação sobre um dado elemento. Esse é provavelmente o método mais preciso para se
coletar o feedback do usuário, pois sua intenção é explicitada de maneira espontânea,
dificilmente havendo equívocos quanto ao seu interesse.
O principal problema do feedback explicito é, além de requerer esforços do usuário
na avaliação de um dado elemento, existir a possibilidade do usuário não estar disposto
a fazê-lo. Portanto, o número de avaliações realizadas pode ser pequeno, tornando a
recomendação pobre. Uma solução para esse problema é fazer com que o usuário
pontue tantos itens quanto forem necessários no prólogo do fluxo de execução do
recomendador. Assim o sistema passa a ter condições de iniciar sua recomendação de
dados baseado no interesse do usuário (Jannach, Janker, Felfernig, & Friedrich, 2011).
O feedback implícito, por sua vez, pode ser coletado constantemente sem requerer
esforços do usuário, porém não se há certeza de que a ação do usuário tenha sido
interpretada corretamente pelo recomendador. Por exemplo, se um usuário compra
vários livros, o recomendador deve interpretar que o usuário se interessa por esses
livros. Essa avaliação pode ser equivocada, uma vez que um ou mais livros sejam
destinados à outra pessoa.
Apesar de ambas as técnicas terem suas vantagens, coletar feedback explicitamente
resulta em uma melhor precisão do que coletá-lo implicitamente (Jannach, Janker,
Felfernig, & Friedrich, 2011). Portanto, neste trabalho, optou-se pelo uso do feedback
explícito, por se entender que o esforço dos usuários em indicar se uma notícia lhe
agrada ou não é compensador em função da filtragem de informação que isso
proporciona.
9
3 Desenvolvimento
Com base na análise dos problemas levantados, foi elaborada uma arquitetura para
um sistema recomendador de notícias. A Figura 4 representa a arquitetura de alto nível
do sistema recomendador de notícias desenvolvido.
Figura 4. Visão geral do sistema.
Esta arquitetura consiste de um processo de cinco etapas. Primeiramente é feito
o pré-processamento do conteúdo extraído da Web. Então esse conteúdo é classificado
entre as áreas de interesse escolhidas para serem abordadas no sistema. Após a
classificação, o conteúdo é submetido ao módulo de recomendação (o qual modela os
interesses do usuário) que gera a apresentado dos resultados ao usuário, possibilitando a
interação do usuário com o sistema, por meio de feedback positivo e/ou negativo.
3.1 O Pré-Processamento
Para classificar ou recomendar notícias ao usuário, primeiramente deve ser realizado
o pré-processamento dessas informações, a fim de prepará-las para serem trabalhadas.
Para tanto, foi utilizado o mecanismo de RSS (Rich Site Summary), o qual é um padrão
que consiste em arquivos com extensão XML e permite a distribuição de notícias e
outros conteúdos Web a usuários (Çelikbaş, 2004). Fazendo uso da estrutura RSS e
tendo acesso a um conjunto de websites que apresentam suas notícias nesse formato, é
possível recuperar a informação da Web de forma rápida e estruturada, permitindo o
processamento dessa informação e, por consequência, sua recomendação.
Para o desenvolvimento deste trabalho foi escolhida a linguagem de programação
Python (Lutz, 2006), versão 2.7.3, por se entender que a mesma possui facilidades para
trabalhar com o desenvolvimento Web e por esta possuir diversas bibliotecas que podem
10
auxiliar o desenvolvimento da ferramenta proposta, como por exemplo as bibliotecas
para extração de conteúdo RSS.
Na fase de pré-processamento, foi utilizada uma lista de websites que trabalham com
a estrutura de RSS e que apresentam notícias diariamente. As páginas desses websites
foram processadas a partir de seus arquivos RSS, sendo todas suas notícias extraídas,
como apresentado na Figura 5. Após a extração do conteúdo RSS, foi realizado um pré-
processamento dessa informação, retirando termos insignificantes à sua classificação e
recomendação e também reduzindo as palavras aos seus radicais. Nessa fase foram
utilizadas as técnicas de eliminação de stop words e o stemming. Com a aplicação
dessas técnicas, obtêm-se um conjunto mais compacto de dados, o que implica em um
melhor desempenho na recomendação de notícias, segundo Marchi (2010).
Após a aplicação do stemming e a eliminação de stop words é calculada a frequência
de todas as palavras do documento e montado um vetor termo-frequência que representa
formalmente o documento. É importante gerar uma boa estrutura de representação de
um documento, pois quanto mais coerente essa estrutura for, melhores resultados são
apresentados na recomendação de informação. Após montado o vetor termo-frequência,
pode-se ainda fazer um corte no número de termos que representam o documento
aplicando, por exemplo, o princípio 80/20 de Pareto (Jannach, Janker, Felfernig, &
Friedrich, 2011). Neste trabalho, foi escolhido realizar este corte visando o desempenho
do sistema, fazendo uso de somente 20% dos termos mais relevantes de um documento,
ou seja, aqueles que possuem maior frequência no vetor termo-frequência. Este valor
pode ser alterado futuramente para um processo de otimização. Por fim, a estrutura
criada foi salva em uma base de dados, para que não fosse necessário reprocessar o
conteúdo.
11
Figura 5. Pré-processamento das notícias.
Após o pré-processamento do conteúdo, passa-se à etapa de classificação das
notícias recuperadas da Web dentre as áreas de interesse escolhidas para este trabalho,
que são: ciência, esporte, mundo, negócios, saúde e tecnologia. Classificando as
notícias, pode-se apresentar o conteúdo de maneira categorizada, facilitando ao usuário
a busca por notícias de seu interesse.
3.2 O Treinamento do Classificador
Para classificar as notícias foi escolhido utilizar o classificador Naive Bayes, por sua
simplicidade de implementação e qualidade dos resultados gerados. Para utilizar esse
classificador foi necessário treiná-lo a identificar, dado um conjunto de notícias, a área
de interesse que cada uma melhor se enquadra. Sabendo-se de qual página Web cada
notícia foi retirada, pode-se etiquetar cada página com sua respectiva área de interesse e
usar este conjunto de dados para treinar o classificador, a fim de identificar quais os
termos que definem cada uma das categorias escolhidas, como apresentado na Figura 6.
12
Figura 6. Treinamento do classificador Naive Bayes.
Na Tabela 1 é apresentada a quantidade de websites publicadores de notícias de uma
área de interesse vistoriados durante duas semanas, a fim de tornar o classificador Naive
Bayes apto a identificar a área de interesse de uma dada notícia. A quantidade de
páginas não é uniforme entre as categorias de notícias porque este detalhe não foi
planejado previamente ao treinamento do classificador, porém é interessante para testes
futuros que sejam coletadas amostras com quantidades similares de notícias de cada
área de interesse.
Tabela 1. Quantidade de websites vistoriados para a aprendizagem do classificador Naive Bayes.
Ciência Esporte Mundo Negócios Saúde Tecnologia
6 12 22 8 8 14
Uma vez treinado, o classificador estará apto a classificar notícias entre áreas de
interesse. O treinamento do classificador também pode ser contínuo, ou seja, continuar a
ocorrer durante o processo de uso do sistema.
3.3 A classificação
Conforme apresentado na Figura 7, para a classificação de uma nova notícia,
primeiramente é carregada a base pré-processada de notícias. Em seguida, é realizada a
limpeza das notícias que não são mais consideradas relevantes dentro de uma janela de
tempo estabelecida. Esta janela é o intervalo de tempo que uma notícia pode ter valor
13
para o usuário, pois as notícias perdem seu valor informativo ao passar do tempo. A
janela considerada neste trabalho foi de sete dias. A eliminação de notícias antigas, além
de retirar da base pré-processada de notícias aqueles elementos que não são relevantes,
reduz a dimensão da base de dados, melhorando o desempenho de seu processamento.
Figura 7. Classificação de novas notícias.
Após remover as notícias consideradas antigas, inicia-se a pontuação das novas por
meio do classificador Naive Bayes. Por meio de uma consulta ao classificador, uma
notícia é pontuada para cada área de interesse, por meio da probabilidade desta notícia
pertencer à área específica. Vale ressaltar que neste ponto a base de dados contém
notícias novas, que foram buscadas da Web e ainda não classificadas, e também notícias
já classificadas, mas que ainda se encontram na janela de tempo estabelecida. Após ser
determinada a pontuação, o conjunto de novas notícias é mesclado ao conjunto antigo e,
então, realizado um decaimento das notas para cada dia de envelhecimento da notícia,
pois ao passar de cada dia, a notícia perde relevância, até sair de sua janela de vida e não
ser mais considerada relevante. Para o cálculo do decaimento da nota de uma notícia é
utilizada a equação da Figura 8.
Figura 8. Equação de decaimento de relevância de uma notícia.
A equação da Figura 8 decrementa 15% da nota atribuída pelo classificador a uma
notícia para cada dia de envelhecimento da mesma, o que faz com que a noticia perca
seu valor em torno de uma semana. Esse intervalo de tempo e o valor de decremento
14
foram considerados como valores iniciais a serem utilizados, mas devem ser otimizados
em um próximo trabalho para garantir melhores resultados.
Após o decaimento das notas, as notícias podem ser ordenadas para cada área de
interesse. Desta forma, têm-se as notícias ordenadas pela significância referente à área
de interesse da qual fazem parte. Esta tarefa é conhecida na literatura como ranking das
notícias. Por fim, esse conjunto ordenado é salvo em uma base de resultados pronto para
ser apresentado ao usuário.
3.4 A apresentação
Após a classificação, as notícias podem ser apresentadas ao usuário. A Figura 9
exibe o protótipo da tela inicial do sistema proposto.
Figura 9. Interface da tela inicial do protótipo.
No centro da tela inicial do sistema existem sete botões, os seis primeiros referentes
às categorias de notícias e o último ao conteúdo personalizado, baseado na modelagem
do interesse do usuário, a ser discutida adiante. A tela inicial permite também que o
usuário se cadastre no sistema, definindo um nome de usuário e senha, para ter acesso
personalizado à apresentação das notícias. A Figura 10 exemplifica a apresentação de
notícias referentes à área de interesse de tecnologia.
15
Figura 10. Interface da tela de notícias de tecnologia.
A tela de apresentação de notícias, mostrada na Figura 10, contém os 10 itens
considerados mais relevantes em suas categorias pelo algoritmo de ranking utilizado na
fase de classificação. Esta tela não foi otimizada para aspectos de usabilidade, sendo
construída somente para fins de experimentação.
Desde que o usuário esteja conectado no sistema com suas credenciais, ele pode
interagir com o sistema de recomendação por meio de dois botões localizados a direita
de cada notícia: o primeiro possibilitando o usuário atribuir um feedback positivo e o
segundo um feedback negativo em relação a notícia referida. A possibilidade de o
usuário interagir com o sistema, por meio do uso de feedback, permite ao sistema
16
capturar o interesse do usuário. Por meio da modelagem deste interesse, uma
recomendação personalizada de notícias pode ser apresentada ao usuário.
3.5 Modelagem do Interesse do Usuário
Uma boa recomendação para o usuário do sistema de notícias é baseada em uma boa
modelagem tanto do conteúdo (informação) trabalhado quanto do usuário ao qual a
notícia será recomendada. Para isso é necessário fazer uso de técnicas que permitam
relacionar o interesse do usuário e também as notícias. Uma maneira de fazer esse
relacionamento é por meio da utilização do modelo termo-frequência na modelagem do
interesse do usuário, assim como utilizado na modelagem de notícias. Deste modo, o
interesse do usuário é composto por um vetor de palavras e suas respectivas frequências,
que correspondem às palavras e as frequências dos termos mais significativos dos
documentos que o usuário apresenta interesse.
3.6 Relevance Feedback
Para conhecer o conteúdo que o usuário deseja ou não ter acesso é feito uso de
relevance feedback por parte do usuário. O feedback é de extrema importância para um
sistema recomendador de notícias, pois é por meio desta ação que é captado o interesse
do usuário do sistema em um determinado tópico. Para este trabalho foi escolhido fazer
uso apenas de feedback explícito, por se entender que esta técnica não causa falsas
interpretações quanto ao interesse do usuário e porque seus resultados são
suficientemente relevantes.
Neste trabalho foi considerado que o usuário ou possui interesse em uma notícia, ou
ele não possui interesse. Ou seja, não foi considerado que haja um meio termo no
interesse do usuário por um determinado dado. Desta maneira, pode-se criar um
mecanismo que capte esse interesse por uma notícia, sendo ele positivo ou negativo.
Visto que a representação das notícias e do interesse do usuário são modelados na
forma de vetores termo-frequência, o feedback positivo age de forma incremental no
modelo do usuário, somando a frequência das palavras contidas em um documento que
o usuário tenha mostrado interesse ao modelo de interesse atual do usuário, como
exemplificado na Figura 11.
17
Figura 11. Feedback positivo e interesse do usuário.
O feedback negativo, por sua vez, age de forma decremental. As frequências das
palavras contidas no documento que o usuário demonstrou desinteresse são
decrementadas do modelo de interesse do usuário, como exemplificado na Figura 12. O
intervalo dos possíveis valores das frequências dos termos é o dos números inteiros, ou
seja, podem-se ter valores negativos e positivos. Percebe-se assim que se for aplicado
um feedback negativo e um termo do documento vinculado ao feedback ainda não
estiver contido no modelo de interesse do usuário, ou então se esse documento possuir
uma frequência maior do que a contida no modelo de interesse do usuário, a frequência
deste termo será negativa. Isto está correto, pois caso a frequência fosse limitada
inferiormente a zero, haveria uma limitação quanto à expressividade do desinteresse do
usuário, não sendo perceptível a dimensão da falta de interesse do usuário por um
documento.
Figura 12. Feedback negativo e o interesse do usuário.
18
Por fim, capturando o interesse do usuário, pode-se recomendar notícias a ele,
tomando como base este interesse. Assim, acessando o sétimo botão da tela inicial do
sistema, apresentada na Figura 9, o usuário terá acesso a uma apresentação
personalizada de notícias, criada por meio da recomendação de informação.
3.7 Recomendação
A fase de recomendação consiste em, por meio da utilização dos mecanismos de
relevance feedback, obter o interesse do usuário e recomendar notícias baseado nesse
interesse. Como já foi descrito, existe um modelo que representa o interesse do usuário
e toda vez que o usuário do sistema realiza um feedback esse modelo sofre uma
alteração, de forma a convergir ao interesse real do usuário.
A recomendação de notícias no sistema proposto neste trabalho consistem em uma
apresentação personalizada da informação. Após buscar as notícias na Web e classificá-
las conforme sua área de interesse, o cálculo de similaridade entre o modelo de cada
notícia e o modelo de interesse do usuário é efetuado, com o propósito de listar as
notícias em ordem de relevância ao modelo de interesse do usuário. Desta forma, em
uma pesquisa personalizada podem aparecer notícias de áreas de interesse distintas,
como exemplificado na Figura 13.
19
Figura 13. Página de notícias recomendadas ao usuário.
Para realizar a tarefa de recomendação de notícias foi utilizada, primeiramente, a
técnica do coeficiente de Jaccard para calcular a similaridade entre os modelos de uma
notícia e do usuário. Nessa abordagem, o interesse do usuário foi determinado por meio
de um conjunto de palavras, sem considerar suas frequências, o que resultou em
problemas ao modelar o interesse do usuário e ao calcular a similaridade entre os
documentos.
Primeiramente percebeu-se que o resultado obtido do cálculo da similaridade entre
documentos era limitado. Isto ocorreu por serem levadas em consideração apenas a
união e a interseção entre os documentos que consistiam em termos, sem considerar as
suas frequencias, resultando em similaridades errôneas. O segundo problema a ser
destacado foi quanto ao uso de relevance feedback. Quando o usuário realizava um
feedback positivo, as novas palavras eram adicionadas ao seu modelo de interesse e,
20
quando um feedback negativo era efetuado, as novas palavras eram retiradas do modelo
de interesse do usuário. O problema ocorre quando um termo realmente significativo na
representação do interesse do usuário é retirado do seu modelo de interesse por aparecer
em um documento que o usuário não se interessou. Este fenômeno torna o modelo de
interesse do usuário inconsistente, o que afeta os resultados apresentados. Com essas
conclusões foi decidido modificar os métodos de representação de documentos e do
interesse do usuário e também modificar a técnica para cálculo de similaridade entre
documentos.
A técnica de similaridade pelo cosseno obteve bons resultados quando utilizada
juntamente com o modelo termo-frequência para representação de documentos e dos
interesses dos usuários. Nessa abordagem os documentos são representados por um
vetor de tuplas termo-frequência, o que não gerou os mesmos problemas da técnica
anterior, devido à utilização das frequências dos termos. Agora, o cálculo de
similaridade leva em consideração uma equação matemática que calcula a similaridade
entre dois documentos e não apenas a semelhança de conjuntos, como feita
anteriormente. Por fim, o mecanismo de relevance feedback incrementa ou decrementa
as frequências dos termos do documento, não ocorrendo o problema de descarte de
termos relevantes devido a ocorrência de um feedback negativo do usuário em um
documento que contém esses termos.
3.8 As Classes do Sistema
Após serem descritas as etapas de funcionamento do sistema, pôde-se fazer uma
última representação da arquitetura do sistema, desta vez focando nas classes escolhidas
para a modelagem do sistema utilizando o paradigma de Orientação a Objetos. A Figura
14 representa as classes implementadas no sistema e a maneira com a qual elas se
relacionam.
21
Figura 14. Diagrama de classe do sistema.
22
Foram criadas oito classes para modelar o sistema. A classe Web modela a parte do
sistema Web com a qual o usuário interage, fazendo-se uso da biblioteca CherryPy,
apresentada na Subseção 3.9. Por meio desta classe o usuário possui acesso às notícias
classificadas (Figura 10) e também às notícias recomendadas (Figura 13).
A classe NaiveBayes representa o classificador Naive Bayes, importado da
biblioteca Python Reverend (Reverend B, 2012), que foi utilizada para classificar as
notícias entre as categorias do sistema.
A classe ClassifierTrainer é utilizada para treinar o classificador Naive Bayes, a fim
de torná-lo apto a classificar corretamente uma notícia em uma das áreas de interesse
escolhidas para este trabalho. Esta classe faz uso da classe NewsSearch para buscar
notícias da Web e faz uso dos termos gerados pela classe PreProcessing, que contém
métodos para a etapa de pré-processamento, utilizada na extração das notícias da Web.
A classe NewsSearch também faz uso da classe Scorer, que efetua a etapa de pontuação
das notícias, eliminação das notícias antigas e também o ranking das notícias por áreas
de interesse.
A classe User representa o usuário, seu login e senha de acesso ao sistema, os
websites que ele gosta ou não no sistema e os termos que representam seu interesse.
Esta classe relaciona-se diretamente com a classe News, que modela uma notícia
extraída de documentos RSS, contendo seu título, descrição, data de acesso, o endereço
de acesso à notícia e os termos que a representam.
A classe NewsSearch pode ser considerada o coração do sistema. Percebe-se por
meio da Figura 14, que esta é a classe com o maior número de relacionamentos do
sistema. A classe NewsSearch varre as páginas Web escolhidas (ver Apêndice) a fim de
buscar notícias e classificá-las. Ou seja, esta classe utiliza a classe PreProcessing, a
Naive Bayes, a News e a Scorer, enfim, é por meio desta classe que o sistema, em sua
maior parte, funciona.
Diversas bibliotecas foram utilizadas no desenvolvimento das classes do sistema.
Uma das principais vantagens de se utilizar bibliotecas é o reuso de código. Assim se
ganha tempo no desenvolvimento do sistema e também confiabilidade, uma vez que
essas bibliotecas já foram testadas pela comunidade que as utilizam.
23
3.9 Bibliotecas e Frameworks Utilizados
Na linguagem de programação Python os conjuntos de sub-rotinas empacotados são
conhecidos como bibliotecas. Isso explica as ocorrências prévias deste termo ao longo
deste trabalho. Para o desenvolvimento deste trabalho foram utilizadas algumas
bibliotecas não padrões da linguagem de programação Python, a fim de facilitar
algumas etapas de desenvolvimento como: a extração de conteúdo RSS, o
processamento de linguagem natural, a criação do classificador Naive Bayes e a criação
de um servidor Python para manter o sistema online. As bibliotecas utilizadas, em
ordem alfabética, foram: BeautifulSoup, CherryPy, Feedparser, NLTK e Reverend.
3.9.1 BeautifulSoup
A BeautifulSoup (BeautifulSoup, 2012) é uma biblioteca Python que provê suporte a
screen-scraping. Suas três principais características são:
1. Possui suporte a navegação e a busca pelo conteúdo na Web e também à
alteração de parse trees, ou seja, o BeautifulSoup extrai conteúdo de
documentos, com o benefício do programador utilizar poucas linhas de
código nessas operações;
2. Não é necessário se preocupar com a codificação dos documentos utilizados,
o BeautifulSoup codifica e decodifica os documentos automaticamente;
3. O BeautifulSoup é um dos parsers Python mais utilizados para extração de
conteúdo HTML e XML.
A BeautifulSoup foi utilizado neste trabalho para auxiliar na extração do conteúdo
HTML. A versão utilizada da biblioteca foi a 4.1.3.
3.9.2 CherryPy
O CherryPy (CherryPy, 2012) é um framework Python que permite o
desenvolvimento de aplicações Python Web da mesma maneira que se desenvolvem
aplicações orientadas a objetos, não voltadas à Web. Essa forma de desenvolvimento
resulta em um código mais compacto e desenvolvido em um menor tempo (CherryPy
3.2.0 Documentation). O CherryPy foi utilizado como servidor para manter o sistema
online. Foi utilizada a versão 3.2.2 desse framework no desenvolvimento do trabalho.
24
3.9.3 Feedparser
A biblioteca Feedparser (Feedparser B, 2012) é uma biblioteca Python que fornece
suporte ao tratamento do conteúdo RSS. Dada uma estrutura RSS é possível acessar os
dados de cada item contido nessa estrutura como exemplificado na Tabela 2 (a qual
contém algumas das funcionalidades disponibilizadas pela biblioteca Feedparser)
segundo (RSS Libraries - PythonInfo Wiki).
Tabela 2. Algumas funcionalidades da biblioteca Feedparser.
Item[‘date’] "2004-02-13T22:28:23+08:00" - ISO 8601 date
item[ "date_parsed" ] (2004,02,13,14,28,23,4,44,0)
item[ "title" ] Título do item RSS
item[ "summary" ] Sumário do item RSS
item[ "link" ] Link para o conteúdo original do item RSS
Neste trabalho foi utilizada a versão 5.1.2 da biblioteca Feedparser.
3.9.4 NLTK
A NLTK (Natural Language Toolkit) (Natural Language Toolkit - NLTK 2.0
documentation) é uma biblioteca Python para processamento de linguagem natural e
também uma ferramenta para ensinar e trabalhar a linguística computacional. A NLTK
provê suporte à classificação, tokenização, stemming, tagging, parsing e análise
semântica para linguagem natural. Neste trabalho a biblioteca foi utilizada no pré-
processamento de texto por meio da eliminação de stop words, a aplicação do stemming
e a criação de tuplas termo-frequência. A versão da biblioteca utilizada foi a 2.0.
3.9.5 Reverend
O Reverend é um classificador Naive Bayes, de propósito geral, desenvolvido em
Python (Feedparser A, 2012). Esse classificador foi desenvolvido para ser facilmente
estendido para qualquer domínio de aplicação, apenas havendo de adaptá-lo aos dados
de entrada (Feedparser B, 2012). Utilizado na forma de uma biblioteca, o Reverend foi
escolhido para a classificação de notícias neste trabalho. A versão utilizada foi a 0.4.
25
4 Análise dos Resultados
A área de recomendação de informação preocupa-se com a coerência dos dados
apresentados, com a eficiência no processamento dos dados e com sua apresentação. O
principal problema dessa área é unir esses dois pontos: qualidade e eficiência. Quando o
foco é a recomendação de notícias esses problemas se agravam, pois notícias são
postadas diariamente em websites, o que implica em uma busca constante pela
informação e um processamento pesado desses dados.
4.1 Modelos de Representação
Neste trabalho foram escolhidas técnicas com o intuito de conciliar a eficiência do
processamento de notícias com a qualidade dos resultados gerados, fazendo-se uso de
técnicas de redução de dimensionalidade (remoção de stop words, stemming, etc.), de
um classificador Naive Bayes para classificar novas notícias e do algoritmo de
similaridade pelo cosseno para a recomendação de notícias ao usuário. Além do mais,
percebeu-se que a utilização em conjunto da técnica coeficiente de Jaccard (para cálculo
de similaridade entre um usuário e documentos) e de um conjunto de termos, sem
considerar suas frequências (para representar os documentos), não se mostrou adequada,
gerando resultados não satisfatórios. Portanto, essas duas últimas técnicas deixaram de
ser utilizadas.
4.2 Qualidade do Ranking de Notícias
Com o intuito de verificar a qualidade do ranking das notícias contidas nas
categorias do sistema, por meio do classificador Naive Bayes, ao longo de cinco dias
foram analisadas manualmente as 10 notícias melhor classificadas em cada uma das
áreas de interesse, considerando apenas as notícias diárias para evitar dados duplicados
ao longo da análise. Ao todo foram inspecionadas 300 notícias, sendo 50 dessas
pertencentes a cada uma das áreas de interesse do sistema. Vale ressaltar que os
períodos de treinamento e teste do classificador são distintos, ou seja, os conjuntos de
notícias são diferentes. O resultado obtido é representado na Tabela 3, com valores entre
0 e 1 que representam a corretude da classificação das notícias analisadas.
26
Tabela 3. Resultado do teste de qualidade do ranking de notícias.
Mundo Esporte Tecnologia Ciência Saúde Negócios
1º dia 1 1 1 0,8 1 1
2º dia 1 1 1 0,9 0,9 0,8
3º dia 1 1 1 0,8 1 1
4º dia 1 1 0,9 0,9 1 0,8
5º dia 1 1 1 1 0,8 0,7
A Figura 15 apresenta graficamente o desempenho do classificador durante o teste
para cada uma das categorias do sistema. As notícias apresentadas na categoria
“Mundo” e na categoria “Esporte” foram corretamente classificadas ao longo dos cinco
dias de avaliação, obtendo 100% de corretude com suas áreas de interesse. As notícias
apresentadas na categoria “Tecnologia” obtiveram 98% de compatibilidade com esta
categoria, com apenas uma notícia erroneamente classificada. As categorias “Ciência” e
“Saúde” obtiveram 90% e 94% de compatibilidade, respectivamente. Por fim, a
categoria “Negócios” obteve 86% de compatibilidade com as notícias apresentadas,
sendo o pior ranking entre as áreas de interesse. A média da qualidade do ranking das
notícias apresentadas nas seis áreas de interesse durante os cinco dias de avaliação foi
de 94.6%, sendo um resultado satisfatório para o protótipo.
27
Figura 15. Ranking das notícias por categorias utilizando 100% dos termos para representação de
notícias.
Já foi dito neste trabalho, que uma boa relação entre qualidade dos resultados e
eficiência de processamento é buscada. A fim de verificar esta relação, foi realizado um
teste quanto ao custo de processamento do sistema.
4.3 Custo de Processamento do Sistema
Durante os testes realizados na Seção 4.2 deste trabalho, foi calculado o tempo de
processamento das etapas de pré-processamento de 100% das notícias de suas fontes, da
remoção das notícias antigas, da pontuação das notícias por meio do classificador Naive
Bayes e da ordenação delas por áreas de interesse. Com esses testes, chegaram-se aos
dados apresentado na Tabela 4 (em segundos).
Tabela 4. Resultado do teste de desempenho do sistema.
Pré-
Processamento
Remoção Pontuação Ordenação Tempo Total
1º dia 4.688,55 0,15 46,48 1,72 4.736,91
2º dia 4.277,10 0,09 25,24 1,76 4.304,20
3º dia 4.293,31 1,46E-06 57,16 3,67 4.354,14
4º dia 5.019,67 9,76E-07 53,06 3,36 5.076,10
5º dia 4.854,54 1,95E-06 25,88 1,75 4.882,17
Com a formulação dos dados apresentados na Tabela 4, pôde-se elaborar o gráfico
da Figura 16, que representa a distribuição do tempo em função das etapas de
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%Mundo
Esporte
Tecnologia
Ciência
Saúde
Negócio
Ranking das notícias por categorias
28
processamento do sistema, percebendo-se em quais etapas é gasto mais tempo de
processamento.
Figura 16. Custo de processamento do sistema utilizando 100% de termos do texto.
Com os dados apresentados na Figura 16, percebe-se que o gargalo do sistema está
na etapa de pré-processamento das notícias, que gasta 99,056% do tempo de
processamento do sistema. Como já era esperado, o processamento de linguagem
natural mostrou-se uma atividade custosa, como já citado na literatura por Marchi
(2010) e, para obter um melhor desempenho do sistema, é necessário atacar esta fase
buscando otimizá-la. Uma alternativa para a melhoria do processamento de linguagem
natural é a redução de dimensionalidade do documento a ser trabalho. Assim, pode-se
utilizar o princípio 80/20 de Pareto (Koch, 2000).
4.4 Desempenho de 20% e 100% de Termos Utilizados até a Classificação
Buscando melhorar o desempenho do processamento de dados do sistema, testou-se
a utilização de um número menor de termos para a representação das notícias. Escolheu-
se utilizar o Princípio 80/20 de Vilfredo Pareto como princípio de corte, selecionando
apenas 20% dos termos com maior frequência nos documentos, considerando estes os
mais relevantes. O novo teste consistiu em refazer o teste da Seção 4.2, porém aplicando
o corte de 20% de termos. Após a realização deste teste, os dados obtidos pelo teste
anterior, que contém 100% dos termos, e pelo novo teste, que contém 20% dos termos,
99,056% 0,001%
0,890%
0,053% 0,942%
Custo de Processamento do Sistema
Pré-Processamento Remoção Pontuação Ordenaçao
29
foram inseridos na Tabela 5, a qual apresenta as médias do tempo de processamento
(em segundos) de cada etapa do sistema.
Tabela 5. Comparação de desempenho entre 20% e 100% de termos de documentos utilizados.
Pré-
Processamento
Remoção Pontuação Ordenação Tempo Total
20% 4.661,05 1,46E-06 10,68 1,764 4.673,50
100% 4.661,19 1,46E-06 27,29 1,762 4.690,24
O tempo obtido na fase de pré-processamento, apresentado na Tabela 5, foi
relativamente similar entre a utilização de 20% e 100% dos termos. Isto se dá porque o
corte no número de termos ocorre apenas ao final da fase de pré-processamento, ou seja,
ambos os testes processaram 100% dos termos nessa fase.
A fase de remoção obteve-se o mesmo tempo de processamento tanto na utilização
de 20% de termos quanto na utilização de 100% de termos, uma vez que foi utilizada a
mesma base de notícias durante os testes e também foram consideradas apenas as
notícias diárias, zerando-se a base de notícias a cada dia. Desta maneira não houve
remoção de notícias antigas.
A fase de pontuação foi 60% mais eficiente com a utilização de 20% dos termos
para representação das notícias, pois menos termos foram testados no classificador
Naive Bayes, o que lhe permite uma melhor aprendizagem.
A fase de ordenação teve tempo de processamento próximo entre os dois testes
realizados, pois ambos possuem a mesma complexidade de ordenação nesta fase.
Por fim, concluiu-se que a diferença de tempo de processamento entre a utilização
de 20% dos termos e 100% dos termos é pouca e, como ainda não foram analisadas as
implicações de um corte no número de termos durante a fase de recomendação de
notícias, o sistema continuará a adotar 100% de termos na representação de
documentos. Ainda em busca de uma solução para o tempo de processamento do
sistema, decidiu-se testar um novo método de extração das páginas Web, coletando um
menor número de termos.
30
4.5 Representação de Notícias por meio de Títulos e Sumários
Como apresentado na Figura 16, o gargalo do sistema encontra-se na fase de pré-
processamento de documentos. Na tentativa de contornar esse problema, decidiu-se
extrair apenas o título e o sumário de cada notícia, contidos nos documentos RSS. Com
essa nova abordagem, é desejado que o ganho de desempenho seja satisfatório e que a
perda na qualidade dos resultados seja aceitável. Um novo teste com duração de cinco
dias foi realizado, assim como nos testes anteriores para, então, chegar-se aos seguintes
dados apresentados na Tabela 6 (em segundos).
Tabela 6. Comparação de desempenho entre a utilização de “título” e “sumário” e de 100% de termos de
documentos.
Pré-
Processamento
Remoção Pontuação Ordenação Tempo Total
Título/Sumário 162,86 1,86 16,57 2,24 183,54
100% 4.661,19 1,46E-06 27,29 1,762 4.690,24
Em termos de desempenho percebe-se uma acentuada mudança no tempo de
processamento do sistema com a nova abordagem. Enquanto no teste com a utilização
de 100% dos termos das notícias obteve-se um tempo médio de 4.690,24 segundos
(78,17 minutos) de processamento, no teste atual, com a utilização apenas do título e do
sumário das notícias, chegou-se à apenas 183,54 segundos (3,07 minutos) de
processamento, uma melhoria de 94,9% no tempo de processamento, cujo resultado é
extremamente significativo. Porém, ainda se deve analisar a qualidade dos resultados
obtidos com a utilização da nova abordagem.
A qualidade do ranking das notícias, obtida pelo teste realizado com a utilização de
título e sumário para representar notícias, segue apresentado na Tabela 7.
31
Tabela 7. Resultado do teste de qualidade do ranking de notícias com a utilização de “título” e “sumário”
como forma de representação de documentos.
Mundo Esporte Tecnologia Ciência Saúde Negócios
1 1 1 0,7 0,6 0,5
1 1 1 0,5 0,6 0,5
1 1 1 0,7 0,8 0,6
1 1 1 0,5 0,7 0,6
1 1 1 0,5 0,7 0,5
Com os dados apresentados na Tabela 7, pôde-se elaborar um gráfico comparativo
entre a qualidade do ranking das notícias com a utilização desta nova abordagem. O
gráfico segue apresentado na Figura 17.
Figura 17. Ranking das notícias por categorias utilizando “título” e “sumário” para representação de
documentos.
Como apresentado na Figura 17, a qualidade do ranking das notícias apresentadas
nas categorias “Mundo”, “Esporte” e “Tecnologia” foi de 100%, resultado pouco
superior ao teste com a utilização de 100% de termos. A categoria “Ciência” teve 58%
de notícias corretamente classificadas, a categoria “Saúde” 68% e, a categoria
“Negócios”, teve 54% de notícias corretamente classificadas. Como nota geral, para o
caso de teste com a utilização do título e do sumário para representação de notícias, a
qualidade do ranking das notícias nas seis áreas de interesse do sistema foi de 80%, uma
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%Mundo
Esporte
Tecnologia
Ciência
Saúde
Negócio
Ranking das notícias por categorias
32
perda de 14,6% na qualidade dos resultados apresentados em comparação à utilização
de 100% dos termos das notícias para representá-las.
Em termos gerais o resultado obtido neste último teste é satisfatório, pois o ganho de
desempenho é muito grande e a perda na qualidade dos resultados é satisfatória para o
propósito do sistema. Entretanto, na Tabela 7 percebemos que enquanto as categorias
“Mundo”, “Esporte” e “Tecnologia” tiveram suas notícias bem classificadas, as demais
categorias tiveram resultados inferiores ao teste da Subseção 4.2, tendo a categoria
“Negócios” apenas 54% de corretude nas notícias apresentadas. Pensa-se que com um
melhor treinamento do classificador Naive Bayes esse problema seja corrigido,
atingindo melhores resultados.
33
5 Conclusões
A excessiva sobrecarga de informação contida na Web nos levou a desenvolver este
trabalho visando tornar mais hábil o acesso do usuário a informação de seu interesse. A
notícia, sendo apenas um subconjunto da informação, foi o nicho escolhido a ser
trabalhado e, dentro deste grupo, optou-se por criar um sistema recomendador de
notícias pertencentes a um conjunto restrito de áreas de interesse: esporte, ciência,
mundo, negócios, saúde e tecnologia.
Os resultados obtidos ao longo deste trabalho foram satisfatórios. Chegou-se ao
valor médio de 1.227 notícias recuperas diariamente. Foi analisada a aplicação de
técnicas distintas para a modelagem das notícias e também para sua recomendação.
Percebeu-se que o modelo composto pela utilização em conjunto da técnica do
coeficiente de Jaccard (para cálculo de similaridade entre os interesses de um usuário e
documentos) e de um conjunto de termos, sem considerar suas frequências (para
representar os documentos), não se mostrou adequado, devido a uma inconsistente
modelagem do interesse do usuário. Para contornar esse problema, adotou-se o modelo
de representação termo-frequência na modelagem das notícias e do interesse do usuário
e, também, o uso da técnica de similaridade pelo cosseno para o cálculo de
similaridade entre documentos e o modelo do usuário, contornando os problemas
apresentados pelo modelo anterior.
Por meio de testes, foi avaliado o ranking das notícias nas áreas de interesse do
sistema. Inicialmente utilizou-se de 100% dos termos das notícias, obtendo uma
precisão de 94,6%. Porém, a eficiência do processamento do sistema foi baixa, com
valor médio de 4.690,24 segundos (78,17 minutos) de processamento. A fim de se
obter uma boa relação entre ganho de desempenho e qualidade dos resultados, testou-se
a utilização do princípio 80/20 de Pareto, reduzindo a quantidade de termos aos 20%
mais frequentes. Este experimento não produziu resultados melhores que o uso de
100% dos termos. Por meio de testes, percebeu-se que o gargalo do sistema
encontrava-se na fase de pré-processamento das notícias e, como a redução do número
de termos de um documento é realizada ao final desta fase, o ganho de desempenho é
irrisório nas fases seguintes.
34
Ainda na tentativa de otimizar o processamento do sistema, testou-se a utilização
apenas do “título” e do “sumário” na representação das notícias. Em relação à
utilização de 100% dos termos extraídos das notícias, a nova modelagem obteve ganho
de desempenho de 94,9% e perca de 14,6% na qualidade dos resultados. Esse resultado
foi considerado satisfatório, pois o ganho de desempenho é muito grande e a perca na
qualidade dos resultados é aceitável para o propósito do sistema.
Como esse trabalho não está concluído, tem-se como metas futuras, a fim de
otimizar os resultados gerados: o estabelecimento de um bom valor de decaimento
temporal para as notícias; a definição de uma janela de tempo adequada para a
relevância das notícias; a criação de uma nova equação para o cálculo da relevância do
feedback do usuário; e ainda a utilização do modelo TF-IDF para a representação do
interesse do usuário e de documentos.
Entende-se, que um sistema recuperador de notícias é de utilidade conhecida, haja
vista que se encontram inúmeros portais de notícias na Internet. Um sistema que além
de recuperar notícias ainda tem a capacidade de recomendá-las ao usuário em função
de seus interesses vem agregar à Web.
35
6 Referências Bibliográficas
Alag, S. (2009). Collective Intelligence in Action. Manning.
Beautiful Soup, 2012. Beautiful Soup: We called him Tortoise because he taught us.
Acesso em 24 de 09 de 2012, disponível em Beautiful Soup: We called him
Tortoise because he taught us:
http://www.crummy.com/software/BeautifulSoup/
Cardoso, O. N. P. (2000). Recuperação de Informaçao. Infocomp, Revista de
Computação da UFLA, v.1, pp. 33-38, Minas Gerais.
Çelikbaş, Z. What is RSS and how can it serve libraries?, 2004. In First International
Conference on Innovations in Learning for the Future: e-Learning, İstanbul
(Turkey), 26-27 October 2004. Istanbul University. pp. 277-292.
Chen, H. (1994). The vocabulary problem in collaboration. IEEE Computer, v.27, n.5.
CherryPy, 2012. Cherrypy - A Minimalist Python Web Framework. Acesso em 12 de 11
de 2012, disponível em http://www.cherrypy.org/: http://www.cherrypy.org/
CherryPy 3.2.0 Documentation. Acesso em 20 de 09 de 2012, disponível em CherryPy
3.2.0 Documentation: http://docs.cherrypy.org/stable/index.html
Feedparser, 2012. Feedparser 5.1.2 : Python Package Index. Acesso em 12 de 11 de
2012, disponível em http://pypi.python.org/pypi/feedparser/:
http://pypi.python.org/pypi/feedparser/
Fellbaum, C. A. (1998). WordNet: An Electronic Lexical Database. MIT Press.
Ferneda, E. (2003). Recuperação de Informação: Análise sobre a contribuição da
Ciência da Computação para a Ciência da Informação. Tese de Doutorado.
Huang, A. (2008). Similarity Measures for Text Document Clustering. Computer
Science Research Student Conference, NZCSRSC2008, pp. 49-56, New Zealand,
Department of Computer Science, The University of Waikato, Hamilton,
NewZealand..
Jannach, D., Janker, M., Felfernig, A., & Friedrich, G. (2011). Recommender Systems
An Introduction. Cambridge University Press.
36
Koch, R. (2000). O Princípio 80/20: o segredo de se realizar mais com menos. Tradução
de Nivaldo Montingelli Jr. Rio de Janeiro: Rocco.
Lutz, M. (2006). Programming Python. O'Reilly.
Manning, C. D., Raghavan, P., & Schütze, H. (2008). Introduction to Information
Retrieval. Cambridge: Cambridge University Press.
Marchi, K. R. (2010). Uma Abordagem para Personalização de Resultados de Busca na
Web. Dissertação de Mestrado. PCC/UEM.
Marmanis, H., & Babenko, D. (2009). Algorithms of the Intelligent Web. Manning.
Meng, W., & Yu, C. (2010). Web Search Technology for Text Documents. In H.
Bidgoli, The Handbook of Technology Management (pp. 466-481). New Jersey:
Editor-in-Chief.
Natural Language Toolkit - NLTK 2.0 documentation. Acesso em 09 de 24 de 2012,
disponível em Natural Language Toolkit - NLTK 2.0 documentation:
http://nltk.org/
Owen, S., Anil, R., Dunning, T., & Friedman, E. (2012). Mahout in Action. Manning.
Porter, M. F. (1980). An algorithm for suffix stripping, Program: electronic library and
information systems, Vol. 40:3, pp.211 - 218.
Reverend A, 2012. Python's Reverend Thomas library is a naive Bayes classifier
library. Acesso em 24 de 09 de 2012, disponível em Python's Reverend Thomas
library is a naive Bayes classifier library.:
http://news.ycombinator.com/item?id=1363862
Reverend B, 2012. Reverend 0.4: Python Package Index. Acesso em 24 de 09 de 2012,
disponível em Reverend 0.4: Python Package Index:
http://pypi.python.org/pypi/Reverend
Rieh, S. Y. (2002). Judgment of information quality and cognitive authority in the Web.
In: Journal of the American Society for Information Science and Technology
(pp. 145-161). Redwood City.
RSS Libraries - PythonInfo Wiki. Acesso em 24 de 09 de 2012, disponível em RSS
Libraries - PythonInfo Wiki: http://wiki.python.org/moin/RssLibraries
37
Segaran, T. (2007). Programming Collective Intelligence. O'Reilly.
World Wide Web Size. Acesso em 5 de outubro de 2012, disponível em
http://www.worldwidewebsize.com/
38
7 Apêndice
Nesta seção serão apresentados os websites que foram utilizados para recuperar
notícias e também o código fonte do sistema.
7.1 Websites utilizados para recuperar notícias
A seguir, a lista de websites dos quais foram recuperadas notícias ao longo deste
trabalho.
http://feeds.nytimes.com/nyt/rss/Science
http://feeds.nytimes.com/nyt/rss/PersonalTech
http://feeds.nytimes.com/nyt/rss/World
http://feeds.nytimes.com/nyt/rss/Space
http://feeds.bbci.co.uk/news/world/middle_east/rss.xml
http://feeds.nytimes.com/nyt/rss/Research
http://feeds.nytimes.com/nyt/rss/MiddleEast
http://news.google.com/news/section?pz=1&cf=all&ned=us&topic=tc&ict
=ln&output=rss
http://www.nytimes.com/services/xml/rss/nyt/GlobalBusiness.xml
http://feeds.bbci.co.uk/news/world/europe/rss.xml
http://feeds.nytimes.com/nyt/rss/Business
http://feeds.nytimes.com/nyt/rss/Americas
http://feeds.nytimes.com/nyt/rss/EnergyEnvironment
http://feeds.nytimes.com/nyt/rss/Economy
http://news.google.com/news/section?pz=1&cf=all&ned=us&topic=m&ict=
ln&output=rss
http://feeds.nytimes.com/nyt/rss/Technology
http://feeds.news.com.au/public/rss/2.0/tech_computers_508.xml
http://feeds.bbci.co.uk/news/world/asia/rss.xml
http://feeds.news.com.au/public/rss/2.0/ndp_hlth_nlivng_317.xml
http://feeds.bbci.co.uk/news/health/rss.xml
http://feeds.bbci.co.uk/news/science_and_environment/rss.xml
http://feeds.news.com.au/public/rss/2.0/tech_mobiles_507.xml
http://feeds.nytimes.com/nyt/rss/Nutrition
http://news.google.com/news/section?pz=1&cf=all&ned=us&topic=s&ict=
ln&output=rss
http://feeds.bbci.co.uk/news/technology/rss.xml
39
http://feeds.bbci.co.uk/news/world/latin_america/rss.xml
http://feeds.news.com.au/public/rss/2.0/ndp_sci_nat_347.xml
http://feeds.bbci.co.uk/news/business/rss.xml
http://feeds.nytimes.com/nyt/rss/Hockey
http://feeds.nytimes.com/nyt/rss/Africa
http://feeds.bbci.co.uk/news/world/us_and_canada/rss.xml
http://feeds.news.com.au/public/rss/2.0/tech_cameras_509.xml
http://feeds.news.com.au/public/rss/2.0/tech_gaming_511.xml
http://news.google.com/news/section?pz=1&cf=all&ned=us&topic=w&ict=
ln&output=rss
http://feeds.gawker.com/Lifehacker/full
http://feeds.nytimes.com/nyt/rss/Views
http://feeds.bbci.co.uk/news/uk/rss.xml
http://feeds.nytimes.com/nyt/rss/Environment
http://news.google.com/news/section?pz=1&cf=all&ned=us&topic=b&ict=
ln&output=rss
http://feeds.nytimes.com/nyt/rss/Baseball
http://feeds.nytimes.com/nyt/rss/business-computing
http://news.yahoo.com/rss/sports
http://feeds1.nytimes.com/nyt/rss/Sports
http://feeds.nytimes.com/nyt/rss/AsiaPacific
http://feeds.nytimes.com/nyt/rss/HealthCarePolicy
http://feeds.bbci.co.uk/news/world/africa/rss.xml
http://feeds.nytimes.com/nyt/rss/SmallBusiness
http://feeds.news.com.au/public/rss/2.0/tech_reviews_812.xml
http://feeds.nytimes.com/nyt/rss/companies
http://feeds.nytimes.com/nyt/rss/Health
http://feeds.news.com.au/public/rss/2.0/tech_homeent_510.xml
http://feeds.nytimes.com/nyt/rss/Golf
http://feeds.nytimes.com/nyt/rss/Europe
http://feeds.nytimes.com/nyt/rss/Soccer
http://feeds.feedburner.com/newscomauworldnewsndm
40
7.2 Código Fonte
Nesta seção foi incluído o código fonte do sistema recomendador de notícias
desenvolvido. O mesmo encontra-se subdividido conforme as classes implementadas,
apresentadas na Figura 14.
7.2.1 Main
1 import cherrypy
2 from includes.Web import *
3
4 cherrypy.config.update('conf.cfg')
5 web = Web()
6 cherrypy.quickstart(web)
41
7.2.2 NewsSearch
1 from reverend.thomas import Bayes
2 from includes.Scorer import *
3 import pickle
4 import time
5
6 class NewsSearch():
7
8 def run(self):
9 #DICIONARIO DE CATEGORIAS E WEBSITES
10 self.news = set(['http://feeds.nytimes.com/nyt/rss/Te
chnology','http://feeds.nytimes.com/nyt/rss/companies',
'http://feeds.nytimes.com/nyt/rss/business-
computing','http://feeds.nytimes.com/nyt/rss/PersonalTech','http://feeds.bbci
.co.
uk/news/technology/rss.xml','http://news.google.com/news/section?pz=1
&cf=all&ned=us&topic=tc&ict=ln&output=rss','http://feed
s.gawker.com/Lifehacker/full','http://feeds.news.com.au/public/rss/2.
0/tech_cameras_509.xml','http://feeds.news.com.au/publi
c/rss/2.0/tech_homeent_510.xml','http://feeds.news.com.au/public/rss/
2.0/tech_reviews_812.xml','http://feeds.news.com.au/pub
lic/rss/2.0/tech_computers_508.xml','http://feeds.news.com.au/public/
rss/2.0/tech_gaming_511.xml','http://feeds.news.com.au/
public/rss/2.0/tech_mobiles_507.xml','http://feeds1.nytimes.com/nyt/r
ss/Sports','http://feeds.nytimes.com/nyt/rss/Soccer','h
ttp://feeds.nytimes.com/nyt/rss/Golf','http://feeds.nytimes.com/nyt/r
ss/Hockey','http://feeds.nytimes.com/nyt/rss/Baseball',
'http://news.google.com/news/section?pz=1&cf=all&ned=us&topic=s&ict=l
n&output=rss','http://news.yahoo.com/rss/sports','http:
//feeds.nytimes.com/nyt/rss/World','http://feeds.nytimes.com/nyt/rss/
Africa','http://feeds.nytimes.com/nyt/rss/Americas','ht
tp://feeds.nytimes.com/nyt/rss/AsiaPacific','http://feeds.nytimes.com
/nyt/rss/Europe','http://feeds.nytimes.com/nyt/rss/Midd
leEast','http://feeds.bbci.co.uk/news/uk/rss.xml','http://feeds.bbci.
co.uk/news/world/africa/rss.xml','http://feeds.bbci.co.
uk/news/world/asia/rss.xml','http://feeds.bbci.co.uk/news/world/europ
42
e/rss.xml','http://feeds.bbci.co.uk/news/world/latin_am
erica/rss.xml','http://feeds.bbci.co.uk/news/world/middle_east/rss.xm
l','http://feeds.bbci.co.uk/news/world/us_and_canada/rs
s.xml','http://news.google.com/news/section?pz=1&cf=all&ned=us&topic=
w&ict=ln&output=rss','http://feeds.feedburner.com/newsc
omauworldnewsndm','http://feeds.nytimes.com/nyt/rss/Science','http://
feeds.nytimes.com/nyt/rss/Space','http://feeds.nytimes.
com/nyt/rss/Environment','http://feeds.bbci.co.uk/news/science_and_en
vironment/rss.xml','http://feeds.news.com.au/public/rss
/2.0/ndp_sci_nat_347.xml','http://feeds.nytimes.com/nyt/rss/Business'
,'http://feeds.nytimes.com/nyt/rss/EnergyEnvironment','
http://www.nytimes.com/services/xml/rss/nyt/GlobalBusiness.xml','http
://feeds.nytimes.com/nyt/rss/SmallBusiness','http://fee
ds.nytimes.com/nyt/rss/Economy','http://feeds.bbci.co.uk/news/busines
s/rss.xml','http://news.google.com/news/section?pz=1&cf
=all&ned=us&topic=b&ict=ln&output=rss','http://feeds.nytimes.com/nyt/
rss/Health','http://feeds.nytimes.com/nyt/rss/Research'
,'http://feeds.nytimes.com/nyt/rss/Nutrition','http://feeds.nytimes.c
om/nyt/rss/HealthCarePolicy','http://feeds.nytimes.com/
nyt/rss/Views','http://feeds.bbci.co.uk/news/health/rss.xml','http://
news.google.com/news/section?pz=1&cf=all&ned=us&topic=m
&ict=ln&output=rss','http://feeds.news.com.au/public/rss/2.0/ndp_hlth
_nlivng_317.xml'])
11
12 #CARREGA O SCORER
13 self.scorer = Score()
14 self.scorer.load()
15
16 #PERCORRE AS NEWS DOS WEBSITES E CASO A NOTICIA SEJA
NOVA, ADICIONA AO CONJUNTO DE NEWS DO SISTEMA
17 self.scorer.searchNews(self.news)
18
19 #REMOVE NEWS ANTIGAS
20 self.scorer.cleanNews()
21
22 #PONTUA AS NEWS PARA CADA CATEGORIA
23 self.scorer.scoreNews()
24
43
25 #ORDENA AS NEWS POR ORDEM DE RELEVANCIA
26 self.scorer.sortScore()
27
28 #CRIA ARQUIVO PARA CADA CATEGORIA DE NEWS
29 self.scorer.commit()
30
31 #CRIA ARQUIVO DE NEWS
32 self.scorer.save()
44
7.2.3 ClassifierTrainer
1 from reverend.thomas import Bayes
2 from BeautifulSoup import BeautifulSoup as bs
3 from includes.PreProcessing import *
4 import feedparser
5 import nltk
6 import urllib2
7
8 class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
9 def http_error_302(self, req, fp, code, msg, headers):
10 return urllib2.HTTPRedirectHandler.http_error_302(self, req,
fp, code, msg, headers)
11
12 http_error_301 = http_error_303 = http_error_307 = http_error_302
13
14 cookieprocessor = urllib2.HTTPCookieProcessor()
15 opener = urllib2.build_opener(MyHTTPRedirectHandler, cookieprocessor)
16 urllib2.install_opener(opener)
17
18 class ClassifierTrainer():
19
20 def __init__ (self,dicNews=None,guesser=None):
21
22 #CARREGA O CLASSIFICADOR NAIVE BAYES
23 self.guesser = Bayes()
24 self.guesser.load()
25
26 #CRIA DICIONÁRIO DE NOTÍCIAS POR CATEGORIAS
27 self.dicNews = {}
28 self.dicNews['technology'] = ['http://rss.cnn.com/rss/edition
_technology.rss','http://feeds.nytimes.com/nyt/rss/Technolo
gy','http://feeds.nytimes.com/nyt/rss/companies','http://feeds.nytime
s.com/nyt/rss/business-computing','http://feeds.nytimes
.com/nyt/rss/PersonalTech','http://feeds.bbci.co.uk/news/technology/r
45
ss.xml','http://news.google.com/news/section?pz=1&cf=al
l&ned=us&topic=tc&ict=ln&output=rss','http://feeds.gawker.com/Lifehac
ker/full','http://feeds.news.com.au/public/rss/2.0/tech
_cameras_509.xml','http://feeds.news.com.au/public/rss/2.0/tech_homee
nt_510.xml','http://feeds.news.com.au/public/rss/2.0/te
ch_reviews_812.xml','http://feeds.news.com.au/public/rss/2.0/tech_com
puters_508.xml','http://feeds.news.com.au/public/rss/2.
0/tech_gaming_511.xml','http://feeds.news.com.au/public/rss/2.0/tech_
mobiles_507.xml']
29 self.dicNews['sports'] = ['http://feeds1.nytimes.com/nyt/rss/
Sports','http://rss.cnn.com/rss/edition_sport.rss','http://
feeds.nytimes.com/nyt/rss/Soccer','http://feeds.nytimes.com/nyt/rss/G
olf','http://feeds.nytimes.com/nyt/rss/Hockey','http://
feeds.nytimes.com/nyt/rss/Baseball','http://rss.cnn.com/rss/edition_f
ootball.rss','http://rss.cnn.com/rss/edition_golf.rss',
'http://rss.cnn.com/rss/edition_motorsport.rss','http://rss.cnn.com/r
ss/edition_tennis.rss','http://news.google.com/news/sec
tion?pz=1&cf=all&ned=us&topic=s&ict=ln&output=rss','http://news.yahoo
.com/rss/sports']
30 self.dicNews['world'] = ['http://rss.cnn.com/rss/edition_worl
d.rss','http://feeds.nytimes.com/nyt/rss/World','http://fee
ds.nytimes.com/nyt/rss/Africa','http://feeds.nytimes.com/nyt/rss/Amer
icas','http://feeds.nytimes.com/nyt/rss/AsiaPacific','h
ttp://feeds.nytimes.com/nyt/rss/Europe','http://feeds.nytimes.com/nyt
/rss/MiddleEast','http://rss.cnn.com/rss/edition_africa
.rss','http://rss.cnn.com/rss/edition_americas.rss','http://rss.cnn.c
om/rss/edition_asia.rss','http://rss.cnn.com/rss/editio
n_europe.rss','http://rss.cnn.com/rss/edition_meast.rss','http://rss.
cnn.com/rss/edition_us.rss','http://feeds.bbci.co.uk/ne
ws/uk/rss.xml','http://feeds.bbci.co.uk/news/world/africa/rss.xml','h
ttp://feeds.bbci.co.uk/news/world/asia/rss.xml','http:/
/feeds.bbci.co.uk/news/world/europe/rss.xml','http://feeds.bbci.co.uk
/news/world/latin_america/rss.xml','http://feeds.bbci.c
o.uk/news/world/middle_east/rss.xml','http://feeds.bbci.co.uk/news/wo
rld/us_and_canada/rss.xml','http://news.google.com/news
/section?pz=1&cf=all&ned=us&topic=w&ict=ln&output=rss','http://feeds.
feedburner.com/newscomauworldnewsndm']
31 self.dicNews['science'] = ['http://rss.cnn.com/rss/edition_sp
46
ace.rss','http://feeds.nytimes.com/nyt/rss/Science','http:/
/feeds.nytimes.com/nyt/rss/Space','http://feeds.nytimes.com/nyt/rss/E
nvironment','http://feeds.bbci.co.uk/news/science_and_e
nvironment/rss.xml','http://feeds.news.com.au/public/rss/2.0/ndp_sci_
nat_347.xml']
32 self.dicNews['business'] = ['http://feeds.nytimes.com/nyt/rss
/Business','http://feeds.nytimes.com/nyt/rss/EnergyEnvironm
ent','http://www.nytimes.com/services/xml/rss/nyt/GlobalBusiness.xml'
,'http://feeds.nytimes.com/nyt/rss/SmallBusiness','http
://feeds.nytimes.com/nyt/rss/Economy','http://rss.cnn.com/rss/edition
_business.rss','http://feeds.bbci.co.uk/news/business/r
ss.xml','http://news.google.com/news/section?pz=1&cf=all&ned=us&topic
=b&ict=ln&output=rss']
33 self.dicNews['health'] = ['http://feeds.nytimes.com/nyt/rss/H
ealth','http://feeds.nytimes.com/nyt/rss/Research','http://
feeds.nytimes.com/nyt/rss/Nutrition','http://feeds.nytimes.com/nyt/rs
s/HealthCarePolicy','http://feeds.nytimes.com/nyt/rss/V
iews','http://feeds.bbci.co.uk/news/health/rss.xml','http://news.goog
le.com/news/section?pz=1&cf=all&ned=us&topic=m&ict=ln&o
utput=rss','http://feeds.news.com.au/public/rss/2.0/ndp_hlth_nlivng_3
17.xml']
34
35 #CARREGA O PRÉ-PROCESSADOR
36 self.preProcessor = PreProcessing()
37
38 def run(self):
39
40 #TREINA O CLASSIFICADOR
41 for self.key,self.values in self.dicNews.items():
42 for self.url in self.values:
43 self.feed = feedparser.parse(self.url)
44 self.items = self.feed['items']
45 for self.item in self.items:
46 print self.item['link']
47 self.item['link'] = self.item['link'].encode('utf
-8')
48 try:
49 self.page = bs(urllib2.urlopen(self.item['lin
47
k']).read())
50 self.preProcessor.extract(nltk.clean_html(" "
.join([str(self.x) for self.x in self.page.findAll("bod
y")])))
51 except:
52 self.preProcessor.extract(bs(self.item['descr
iption']).getText().encode('utf-8'))
53 self.text = ''
54 self.tuples = self.preProcessor.getTuples()
55 for self.tuple in self.tuples:
56 self.text += self.tuple[0] + ' '
57 self.guesser.train(self.key,self.text)
58
59 self.guesser.save()
48
7.2.4 PreProcessing
1 # -*- coding: utf-8 -*
2 class PreProcessing():
3
4 def __init__ (self):
5
6 self.__tuples = None
7
8 def filter(self,tokensList):
9 '''Filtra o texto: Eliminação de stop words e aplicação de st
emming'''
10 import re
11 import nltk
12
13 self.filterList = nltk.corpus.stopwords.words('english')
14 self.wnl = nltk.WordNetLemmatizer()
15 self.minLenght = 2
16 self.ASC2=["lt","gt","amp","quot"]
17
18 return [self.wnl.lemmatize(self.tk.lower()) for self.tk in to
kensList if self.tk.lower() not in self.filterList and
len(self.tk) > self.minLenght and self.tk not in self.ASC2 and not se
lf.tk.isdigit() and not re.match(r"&(\#?\w+);",self.tk)
]
19
20 def extract(self,bodyRaw):
21 '''Extrai um texto html e retorna um conjunto de tuplas t
ermo-frequência'''
22 import nltk
23
24 # Tokeniza corpo e titulo
25 self.bodyRawTokens = nltk.word_tokenize(bodyRaw)
26
27 ## normaliza tokens do corpo
28 self.bodyTokens = self.filter(self.bodyRawTokens)
29
49
30 # Pontua Tokens por frequencia
31 self.bodyTokensDist = nltk.probability.FreqDist(self.body
Tokens)
32
33 self.__tuples = self.bodyTokensDist.items()
34
35 def getTuples(self,valor=100):
36 return self.__tuples[:len(self.__tuples)*valor//100]
50
7.2.5 Scorer
1 from datetime import datetime
2 from PreProcessing import PreProcessing
3 from News import News
4 from reverend.thomas import Bayes
5 import urllib2, httplib
6 import feedparser
7 from BeautifulSoup import BeautifulSoup as bs
8 import nltk
9
10 httplib.HTTPConnection.debuglevel = 1
11 opener = urllib2.build_opener()
12
13 class Score():
14
15 def __init__ (self):
16 self.news = []
17 self.score = None
18 self.result = None
19
20 def load(self,base="base_news"):
21 import pickle
22 try:
23 self.news = pickle.load(open(base,"r"))
24 except:
25 self.news = []
26
27 def save(self,base="base_news"):
28 import pickle
29 pickle.dump(self.news,open(base,'w'))
30
31 def commit(self,base="preprocessed"):
32 import pickle
33 pickle.dump(self.result,open(base,'w'))
34
35 def sortNews(self,valor):
51
36 valor2 = valor[:]
37 news2 = self.news[:]
38 for i in range(len(valor2)-1, 0, -1):
39 for j in range(i):
40 if valor2[j] < valor2[j+1]:
41 valor2[j],valor2[j+1] = valor2[j+1],valor2[j]
42 news2[j],news2[j+1] = news2[j+1],news2[j]
43 return news2
44
45 def searchNews(self,news):
46 PreProcessor = PreProcessing()
47 time = datetime.now()
48 for url in news:
49 feed = feedparser.parse(url)
50 items = feed['items']
51 for item in items:
52 print item['link']
53 item['link'] = item['link'].encode('utf-8')
54 try:
55 page = bs(opener.open(item['link']).read())
56 PreProcessor.extract(nltk.clean_html(" ".join([st
r(x) for x in page.findAll("body")])))
57 except:
58 PreProcessor.extract(bs(item['description']).getT
ext().encode('utf-8'))
59 text = PreProcessor.getTuples()
60 novo = News()
61 tuples = {}
62 for key,value in text:
63 tuples[key] = value
64 novo.setTitle(item['title'])
65 novo.setDescription(item['description'])
66 novo.setLink(item['link'])
67 novo.setDate(item['published_parsed'])
68 novo.setTokens(tuples)
69 if novo not in self.news and novo.getTitle() not in [
i.getTitle() for i in self.news]:
70 self.news.append(novo)
52
71
72 def cleanNews(self):
73 time = datetime.now()
74 blacklist = []
75 for i in self.news:
76 ano = abs(time.year - i.getDate().tm_year)*365
77 mes = abs(time.month - i.getDate().tm_mon)*30
78 dia = abs(time.day - i.getDate().tm_mday)
79 if ano+mes+dia > 7:
80 blacklist+=[i]
81 for i in blacklist:
82 self.news.remove(i)
83
84 def scoreNews(self):
85 time = datetime.now()
86 guesser = Bayes()
87 guesser.load()
88 self.score = [[],[],[],[],[],[]]
89 for i in self.news:
90 string = ''
91 for j in i.getTokens().keys():
92 string += j + ' '
93 nota = guesser.guess(string)
94 ano = abs(time.year - i.getDate().tm_year)*365
95 mes = abs(time.month - i.getDate().tm_mon)*30
96 dia = abs(time.day - i.getDate().tm_mday)
97 result = ano+mes+dia
98 for j in nota:
99 j = list(j)
100 j[1] = j[1] - (j[1]*result*15/100)
101 if j[0] == 'world':
102 world = j[1]
103 elif j[0] == 'sports':
104 sports = j[1]
105 elif j[0] == 'technology':
106 technology = j[1]
107 elif j[0] == 'science':
108 science = j[1]
53
109 elif j[0] == 'business':
110 business = j[1]
111 elif j[0] == 'health':
112 health = j[1]
113 self.score[0].append(world)
114 self.score[1].append(sports)
115 self.score[2].append(technology)
116 self.score[3].append(science)
117 self.score[4].append(business)
118 self.score[5].append(health)
119
120 def sortScore(self):
121 self.result = {}
122 self.result['world'] = self.sortNews(self.score[0])
123 self.result['sports'] = self.sortNews(self.score[1])
124 self.result['technology'] = self.sortNews(self.score[2])
125 self.result['science'] = self.sortNews(self.score[3])
126 self.result['business'] = self.sortNews(self.score[4])
127 self.result['health'] = self.sortNews(self.score[5])
54
7.2.6 User
1 from reverend.thomas import Bayes
2 from datetime import datetime
3 from math import sqrt
4
5 class User():
6
7 def __init__(self,login=None,password=None):
8 self.login = login
9 self.password = password
10 self.tokens = dict()
11 self.like = []
12 self.dislike = []
13 self.preprocessed = []
14
15 def setTokens(self,tokens):
16 for key,value in tokens.items():
17 if key in self.tokens.keys():
18 self.tokens[key] += value
19 else:
20 self.tokens[key] = value
21 if self.tokens[key] == 0:
22 self.tokens.pop(key)
23
24 def removeTokens(self,tokens):
25 for key,value in tokens.items():
26 if key in self.tokens.keys():
27 self.tokens[key] -= value
28 else:
29 self.tokens[key] = 0 - value
30 if self.tokens[key] == 0:
31 self.tokens.pop(key)
32
33 def setLike(self,link):
34 self.like.append(link)
35
36
37 def setDislike(self,link):
38 self.dislike.append(link)
39
40 def treatLike(self,tokens,link):
41 if link in self.dislike:
42 self.dislike.remove(link)
43 else:
44 if link not in self.like:
45 self.setLike(link)
46 self.setTokens(tokens)
55
47
48 def treatDislike(self,tokens,link):
49 if link in self.like:
50 self.like.remove(link)
51 else:
52 if link not in self.dislike:
53 self.setDislike(link)
54 self.removeTokens(tokens)
55
56 def scalar(self,collection):
57 total = 0
58 for coin, count in collection.items():
59 total += count * count
60 return sqrt(total)
61
62 def similarity(self,A,B): # A and B are coin collections
63 total = 0
64 for kind in A: # kind of coin
65 if kind in B:
66 total += A[kind] * B[kind]
67 try:
68 result = float(total) / (self.scalar(A) * self.scalar(B))
69 except:
70 result = 0
71 return result
72
73 def cosineDistance(self,news):
74 try:
75 if len(self.like) == 0 and len(self.dislike) == 0:
76 self.preprocessed = []
77 else:
78 time = datetime.now()
79 similarity = []
80 news2 = news[:]
81 for i in range(len(news2)):
82 nota = self.similarity(self.tokens,news2[i].token
s)
83 ano = abs(time.year -
news2[i].date_parsed.tm_year)*365
84 mes = abs(time.month -
news2[i].date_parsed.tm_mon)*30
85 dia = abs(time.day -
news2[i].date_parsed.tm_mday)
86 result = ano+mes+dia
87 nota = nota - (nota*result*15/100)
88 if news2[i].link in self.like or news2[i].link in
self.dislike:
89 nota = -999
90 similarity.append(nota)
56
91 for i in range(len(similarity)-1, 0, -1):
92 for j in range(i):
93 if similarity[j] < similarity[j+1]:
94 similarity[j],similarity[j+1] = similarit
y[j+1],similarity[j]
95 news2[j],news2[j+1] = news2[j+1],news2[j]
96 self.preprocessed = news2
97 except:
98 self.preprocessed = []
57
7.2.7 News
1 class News():
2 def __init__(self):
3 self.title = None
4 self.description = None
5 self.date_parsed = None
6 self.link = None
7 self.tokens = None
58
7.2.8 Web
1 # -*- coding: utf-8 -*-
2 import os.path
3 import time
4 import cherrypy
5 import pickle
6 from cherrypy.lib.static import serve_file
7 from includes.User import *
8 import ast #converter string para dict
9
10 class Web():
11
12 def account(self):
13 user = cherrypy.session.get('user')
14 webText = ['<html><head><title>TCC Nathan</title><sty
le>body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,for
m,fieldset,input,textarea,p,blockquote,th,td {margin:0;padding:0;}tab
le {border-collapse:collapse;border-spacing:0;}fieldset
,img {border:0;}address,caption,cite,code,dfn,em,strong,th,var {font-
style:normal;font-weight:normal;}ol,ul {list-style:none
;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6 {font-
size:100%;font-weight:normal;}q:before,q:after {content:'';}abbr,acro
nym {border:0;}.clearfix:after { content: ".";display: block;c
lear: both;visibility: hidden;line-height: 20px;height:
0;}.clearfix {display: inline-
block;}html[xmlns] .clearfix {display: block;font-
family: Verdana, Arial, Helvetica, sans-ser
if;}* html .clearfix {height: 1%;}#limit{width:1000px;margin:0 auto;d
isplay:block;}#news{width:1000px;margin:0 auto;display:
block;border:1px solid gray;border-radius:1em;}#footer{text-
align:center;padding:50px 0 0 0;}#title{text-align:center;displa
y:block;font:bold 60px Helvetica, Arial, sans-
serif;margin: 0 0 20px 0;}#listaTitulo{text-
align:center;display:block;font:bo
ld 30px Helvetica, Arial, sans-
serif;margin: 0 0 20px 0;}.item{width:800px;margin: 0 auto;border-
bottom:solid 1px #EFEFEF;}.
59
item a{margin-
bottom: 10px;display: block;}.item form input{position:relative;left:800px;pa
dding:5px;margin:3px;}#botao{posi
tion:relative;left:800px;width:200px;top:-70px;}form input{font-
size:15px;}#botao input{font-size:15px;}#gsii{position:relat
ive;}#header{height:200px;}#flagLink{position:absolute;width:50px;hei
ght:50px;top:100px}#flagImg{position:absolute;width:50p
x;height:50px;}.bloco{border:1px solid gray;margin:10px;padding:10px;
border-radius:1em; }</style></head><body><div id="limit
"><div id="header"><a id="flagLink" href="/"><img id="flagImg"src="ht
tp://www.veryicon.com/icon/png/System/Fresh%20Addon/Arr
ow%20left.png" alt="arrow"/></a><img id="gsii" src="http://din.uem.br
/gsii/logo.gif" alt="gsii"/><div id="botao"><label>Welc
ome '+cherrypy.session.get('user').login+'</label><br/><button onclic
k="javascript:location.href = \'logout\'">Log out</butt
on><button onclick="javascript:location.href = \'account\'">Account</
button></div></div>']
15 webText += ['<label id="title">Account</label>']
16 webText += ['<div class="bloco"><label id="listaTitul
o">Likes</label>']
17 for i in user.like:
18 webText += ['<div class="item"><a href='+i+'>
'+i+'</a></div>']
19 if len(user.like) == 0:
20 webText += ['You dont have likes yet!']
21 webText += ['</div><div class="bloco"><label id="list
aTitulo">Dislikes</label>']
22 for i in user.dislike:
23 webText += ['<div class="item"><a href='+i+'>
'+i+'</a></div>']
24 if len(user.dislike) == 0:
25 webText += ['You dont have likes yet!']
26 webText += ['</div>']
27 return webText
28
29 def dislike(self,link=None,tokens=None,page=None):
30 news = cherrypy.session.get('news')
31 user = cherrypy.session.get('user')
60
32 user.treatDislike(ast.literal_eval(tokens),link)
33 user.cosineDistance(news)
34 file = open("users/"+user.login,'w')
35 pickle.dump(user,file)
36 file.close()
37 cherrypy.session['user'] = user
38 return "<script>location.href = '"+page+"'</script>"
39
40 def like(self,link=None,tokens=None,page=None):
41 news = cherrypy.session.get('news')
42 user = cherrypy.session.get('user')
43 user.treatLike(ast.literal_eval(tokens),link)
44 user.cosineDistance(news)
45 file = open("users/"+user.login,'w')
46 pickle.dump(user,file)
47 file.close()
48 cherrypy.session['user'] = user
49 return "<script>location.href = '"+page+"'</script>"
50
51 def signin(self,login=None,senha=None):
52 if login == None or senha == None:
53 return "<script>alert('Invalid Data!');histor
y.go(-1);</script>"
54 try:
55 user = pickle.load('users/'+login,'r')
56 return "<script>alert('This user already exis
ts!');history.go(-1);</script>"
57 except:
58 user = User(login,senha)
59 file = open('users/'+login,'w')
60 pickle.dump(user,file)
61 file.close()
62 cherrypy.session['user'] = user
63 return "<script>alert('Congratulations! You a
re now registered!');location.href = '/';</script>"
64
65 def signinForm(self):
61
66 webText = ["<html><head><meta http-equiv='Content-
Type' content='text/html; charset=utf-8'/><style>body,div,
dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,
p,blockquote,th,td {margin:0;padding:0;}table {border-c
ollapse:collapse;border-
spacing:0;}fieldset,img {border:0;}address,caption,cite,code,dfn,em,strong,th
,var {font-style:normal
;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-
align:left;}h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:norm
al;}q:before,q:after {content:'';}abbr,acronym {border:0;}.clearfix:a
fter { content: '.';display: block;clear: both;visi
bility: hidden;line-
height: 20px;height: 0;}.clearfix {display: inline-
block;}html[xmlns] .clearfix {display: block;font-fam
ily: Verdana, Arial, Helvetica, sans-
serif;}* html .clearfix {height: 1%;}#title{text-
align:center;position:relative;font-si
ze:60px;border-bottom: 1px solid black;left:250px;}#footer{text-
align:center;padding:50px 0 0 0;}#limit{width:1000px;margin:
0 auto;display:block;}#header{height:200px;}#botao button{font-
size:15px;}form{display:block;margin:0 auto;width:470;}#gsii{
position:relative;display:block;}#flagLink{position:absolute;width:50
px;height:50px;top:100px}#flagImg{position:absolute;wid
th:50px;height:50px;}</style><title>TCC Nathan</title></head><body><d
iv id='limit'><div id='header'><img id='gsii' src='http
://din.uem.br/gsii/logo.gif' alt='gsii'/><a id='flagLink' href='/'><i
mg id='flagImg'src='http://www.veryicon.com/icon/png/Sy
stem/Fresh%20Addon/Arrow%20left.png' alt='arrow'/></a></div>"]
67 webText += ["<form method='post' id='signinForm' acti
on='signin'>User:<input name='login' type='text'/>Passw
ord:<input name='senha' type='password'/> <input type='submit' value=
'Sign in'/></form>"]
68 webText += ["<div id='footer'><label>Developed by Nat
han Siegle Hartmann, 2012</label></div></body></html>"]
69 return webText
70
71 def login(self,login=None,senha=None,page=None):
62
72 try:
73 user = pickle.load(open('users/'+login,'r'))
74 if user.password == senha:
75 cherrypy.session['user'] = user
76 news = cherrypy.session.get('news')
77 user = cherrypy.session.get('user')
78 user.cosineDistance(news)
79 file = open("users/"+user.login,'w')
80 pickle.dump(user,file)
81 file.close()
82 cherrypy.session['user'] = user
83 return "<script>location.href = '"+pa
ge+"'</script>"
84 else:
85 return "<script>alert('Invalid passwo
rd!');history.go(-1);</script>"
86 except:
87 return "<script>alert('User doesnt exist!');h
istory.go(-1);</script>"
88
89 def logout(self):
90 cherrypy.session['user'] = None
91 return '<script>location.href = "/"</script>'
92
93 def result(self,category=None):
94 webText = ['<html><head><title>TCC Nathan</title><sty
le>body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,for
m,fieldset,input,textarea,p,blockquote,th,td {margin:0;padding:0;}tab
le {border-collapse:collapse;border-spacing:0;}fieldset
,img {border:0;}address,caption,cite,code,dfn,em,strong,th,var {font-
style:normal;font-weight:normal;}ol,ul {list-style:none
;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6 {font-
size:100%;font-weight:normal;}q:before,q:after {content:'';}abbr,acro
nym {border:0;}.clearfix:after { content: ".";display: block;c
lear: both;visibility: hidden;line-height: 20px;height:
0;}.clearfix {display: inline-
block;}html[xmlns] .clearfix {display: block;font-
family: Verdana, Arial, Helvetica, sans-ser
63
if;}* html .clearfix {height: 1%;}#limit{width:1000px;margin:0 auto;d
isplay:block;}#news{width:1000px;margin:0 auto;display:
block;border:1px solid gray;border-radius:1em;}#footer{text-
align:center;padding:50px 0 0 0;}#title{text-align:center;displa
y:block;font:bold 60px Helvetica, Arial, sans-
serif;margin: 0 0 20px 0;}.item{width:800px;padding:10px 30px;border-
bottom:so
lid 1px #EFEFEF;}.item .date{color:gray;display:block;padding:0 5px 5
px 5px;}.item .title{font-size:24px}.item .description{
display: block; width:500px;padding:5px 20px;}.item form input{positi
on:relative;left:800px;padding:5px;margin:3px;}#botao{p
osition:relative;left:800px;width:200px;top:-70px;}form input{font-
size:15px;}#botao input{font-size:15px;}#gsii{position:re
lative;}#header{height:200px;}#flagLink{position:absolute;width:50px;
height:50px;top:100px}#flagImg{position:absolute;width:
50px;height:50px;}</style></head><body><div id="limit"><div id="heade
r"><a id="flagLink" href="/"><img id="flagImg"src="http
://www.veryicon.com/icon/png/System/Fresh%20Addon/Arrow%20left.png" a
lt="arrow"/></a><img id="gsii" src="http://din.uem.br/g
sii/logo.gif" alt="gsii"/>']
95 if cherrypy.session.get('user') == None:
96 webText+=['<div id="botao"><form method="post
" id="login" action="login"><input name="page" type="hi
dden" value="result?category='+category+'"/>User:<input name="login"
type="text"/>Password:<input name="senha" type="passwor
d"/><input type="submit" value="Log in"/></form><button onclick = "ja
vascript:location.href = \'signinForm\';">Sign in</butt
on></div>']
97 else:
98 webText+=['<div id="botao"><label>Welcome '+c
herrypy.session.get('user').login+'</label><br/><button
onclick="javascript:location.href = \'logout\'">Log out</button><but
ton onclick="javascript:location.href = \'account\'">Ac
count</button></div>']
99 if category == 'user':
100 dic = cherrypy.session.get('user').preprocess
ed
101 else:
64
102 dic = cherrypy.session.get('preprocessed')[ca
tegory]
103 webText+=['</div><label id="title">'+category.capital
ize()+'</label><div id="news">']
104 try:
105 for i in range(10):
106 webText+=['<div class="item">']
107 webText+=['<label class="title"><a hr
ef="'+dic[i].link+'">'+dic[i].title.encode('utf-8')+'</
a></label>']
108 webText+=['<label class="date">'+str(
dic[i].date_parsed.tm_mon)+','+str(dic[i].date_parsed.t
m_mday)+','+str(dic[i].date_parsed.tm_year)+'</label>']
109 if cherrypy.session.get('user') != No
ne:
110 webText+=['<form name="like"
method="post" action="like"><input name="page" type="hi
dden" value="result?category='+category+'"/><input name="tokens" type
="hidden" value="'+str(dic[i].tokens)+'"/><input name="
link" type="hidden" value="'+dic[i].link+'"/><input type="submit" ']
111 if dic[i].link in cherrypy.se
ssion.get('user').like:
112 webText += ['style="b
ackground: #b4e391;"']
113 webText += ['value="Like"/></
form>']
114 webText+=['<form name="dislik
e" method="post" action="dislike"><input name="page" ty
pe="hidden" value="result?category='+category+'"/><input name="tokens
" type="hidden" value="'+str(dic[i].tokens)+'"/><input
name="link" type="hidden" value="'+dic[i].link+'"/><input type="submi
t"']
115 if dic[i].link in cherrypy.se
ssion.get('user').dislike:
116 webText += ['style="b
ackground: #ff3019;"']
117 webText += ['value="Dislike"/
></form>']
65
118 webText+=['<label class="description"
>'+dic[i].description.encode('utf-8')+'</label>']
119 webText+=['</div>']
120 except:
121 webText+=['You dont have a model already proc
essed!']
122 webText+=["</div></div><div id='footer'><label>Develo
ped by Nathan Siegle Hartmann, 2012</label></div></body
></html>"]
123 return webText
124
125 def loading(self):
126 file = open('preprocessed','r')
127 preprocessed = pickle.load(file)
128 cherrypy.session['preprocessed'] = preprocessed
129 file = open('base_news','r')
130 news = pickle.load(file)
131 cherrypy.session['news'] = news
132 return '<script>location.href = "/"</script>'
133
134 def index(self):
135 if cherrypy.session.get('preprocessed') == None:
136 return '<script>location.href = "loading"</scrip
t>'
137 webText = ["<html><head><meta http-equiv='Content-
Type' content='text/html; charset=utf-8'/><style>body,div,
dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,
p,blockquote,th,td {margin:0;padding:0;}table {border-c
ollapse:collapse;border-
spacing:0;}fieldset,img {border:0;}address,caption,cite,code,dfn,em,strong,th
,var {font-style:normal
;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-
align:left;}h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:norm
al;}q:before,q:after {content:'';}abbr,acronym {border:0;}.clearfix:a
fter { content: '.';display: block;clear: both;visi
bility: hidden;line-
height: 20px;height: 0;}.clearfix {display: inline-
block;}html[xmlns] .clearfix {display: block;font-fam
66
ily: Verdana, Arial, Helvetica, sans-
serif;}* html .clearfix {height: 1%;}#title{text-
align:center;position:relative;font-si
ze:60px;border-bottom: 1px solid black;left:250px;}#footer{text-
align:center;padding:50px 0 0 0;}#limit{width:1000px;margin:
0 auto;display:block;}#botao{position:relative;left:800px;width:200px
;top:-70px;}#header{height:200px;}#botao input{font-siz
e:15px;}#options{display:block;margin:0 auto;width:520;}#gsii{positio
n:relative;}</style><title>TCC Nathan</title></head><bo
dy><div id='limit'><div id='header'><img id='gsii' src='http://din.ue
m.br/gsii/logo.gif' alt='gsii'/>"]
138 if cherrypy.session.get('user') == None:
139 webText+=['<div id="botao"><form method="post
" id="login" action="login"><input name="page" type="hi
dden" value="index"/>User:<input name="login" type="text"/>Password:<
input name="senha" type="password"/><input type="submit
" value="Log in"/></form><button onclick = "javascript:location.href
= \'signinForm\';">Sign in</button></div>']
140 else:
141 webText+=['<div id="botao"><label>Welcome '+c
herrypy.session.get('user').login+'</label><br/><button
onclick="javascript:location.href = \'logout\'">Log out</button><but
ton onclick="javascript:location.href = \'account\'">Ac
count</button></div>']
142 webText += ["</div><label id='title'>News Search Engi
ne</label><div id='options'><button onclick=\"javascrip
t:location.href = 'result?category=world'\";>World</button><button on
click=\"javascript:location.href = 'result?category=spo
rts'\";>Sports</button><button onclick=\"javascript:location.href = '
result?category=technology'\";>Technology</button><butt
on onclick=\"javascript:location.href = 'result?category=science'\";>
Science</button><button onclick=\"javascript:location.h
ref = 'result?category=health'\";>Health</button><button onclick=\"ja
vascript:location.href = 'result?category=business'\";>
Business</button>"]
143 if cherrypy.session.get('user') == None:
144 webText += ["<button disabled onclick=\"javas
cript:location.href = 'result?category="+str(cherrypy.s
67
ession.get('user'))+"'\";>Personal</button>"]
145 else:
146 webText += ["<button onclick=\"javascript:loc
ation.href = 'result?category=user'\";>Personal</button
>"]
147 webText += ["</div><div id='footer'><label>Developed
by Nathan Siegle Hartmann, 2012</label></div></body></h
tml>"]
148 return webText
149
150 index.exposed = True
151 loading.exposed = True
152 result.exposed = True
153 signinForm.exposed = True
154 signin.exposed = True
155 login.exposed = True
156 logout.exposed = True
157 like.exposed = True
158 dislike.exposed = True
159 account.exposed = True
68
Universidade Estadual de Maringá
Departamento de Informática
Av. Colombo 5790, Maringá-PR, CEP 87020-900
Tel: (44) 3011-4324 Fax: (44) 3263-5874
www.din.uem.br