• Nenhum resultado encontrado

EXTRACÇÃO DE CONHECIMENTO DE DADOS II

N/A
N/A
Protected

Academic year: 2021

Share "EXTRACÇÃO DE CONHECIMENTO DE DADOS II"

Copied!
35
0
0

Texto

(1)

M

ESTRADO EM

A

NÁLISE DE

D

ADOS E

S

ISTEMAS DE

A

POIO À

D

ECISÃO

EXTRACÇÃO DE CONHECIMENTO DE DADOS II

Trabalho Text Mining

Rui Sarmento, nº 110414015

Tiago Cunha, nº 110414013

(2)

Índice

1.

Introdução ... 4

2.

Text Mining e Categorização de Documentos ... 5

3.

Pré-processamento de texto ... 5

4.

Análise ... 12

EXPERIÊNCIA 1 – Classificação sem tfidf ... 12

EXPERIÊNCIA 2 – Classificação com tfidf ... 19

5.

Conclusões Finais ... 26

6.

Bibliografia ... 27

(3)

ÍNDICE DE FIGURAS

Figura 1 – Carregamento do pacote tm do R ... 5

Figura 2 – Criação dos dois Corpus de documentos ... 6

Figura 3 – Exemplo do documento 1 do tópico crude ... 6

Figura 4 – Vectorização de todos os documentos de treino e de teste ... 7

Figura 5 – Obtenção dos índices dos conjuntos de documentos de treino e de teste para posterior

utilização ... 7

Figura 6 – Pré-processamento do texto com a função tm_map ... 7

Figura 7 – Exemplo do documento 1 do tópico crude após pré-processamento. ... 8

Figura 8 – Resultados da função DocumentTermMatrix(). ... 8

Figura 9 – Termos que aparecem pelo menos 150 vezes num documento. ... 9

Figura 10 – Remoção dos termos menos frequentes na matriz dos documentos. ... 9

Figura 11 – Valores exemplo de sparse e respectivo número de termos encontrado. ... 9

Figura 12 – Valores de sparse e respectivo número de termos encontrado. ... 10

Figura 13 – Conversão da DTM em data frame. ... 10

Figura 14 – Preparação da nossa DTM para a classificação – adição da classe ... 11

Figura 15 – Dados de treino e dados de teste da matriz DTM ... 11

Figura 16 – Erro do classificador KNN com variação do parâmetro sparse abaixo de 0.71 ... 12

Figura 17 – Erro de classificação dos diversos classificadores com variação do parâmetro sparse ... 13

Figura 18 – Precision dos classificadores com variação do parâmetro sparse ... 14

Figura 19 – Recall dos classificadores com variação do parâmetro sparse ... 15

Figura 20 – Score f1 dos classificadores com variação do parâmetro sparse ... 16

Figura 21 – Resultados do classificador Redes Neuronais (NN) ... 17

Figura 22 – Gráfico dos Score f1 dos classificadores com variação do parâmetro sparse ... 17

Figura 23 – Criação de DTM com tfidf ... 19

Figura 24 – Erro dos classificadores com variação do parâmetro sparse (com tfidf) ... 20

Figura 25 – Precision dos classificadores com variação do parâmetro sparse (com tfidf) ... 21

Figura 26 – Recall dos classificadores com variação do parâmetro sparse (com tfidf) ... 22

Figura 27 – Score f1 dos classificadores com variação do parâmetro sparse (com tfidf) ... 23

Figura 28 – Resultados do classificador Support Vector Machines (SVM) ... 24

(4)

1. Introdução

O presente trabalho insere-se na disciplina de Extracção de Conhecimento de Dados II do Mestrado em

Análise de Dados e Sistemas de Apoio à Decisão. Este trabalho tem como objetivo a utilização de um programa

(implementado em linguagem R com o uso, entre outros, de funções do pacote {tm} do R) que nos permita fazer a

classificação de documentos de texto. A área em que se insere o trabalho é portanto relacionada com Text Mining,

que se divide em subáreas tais como a categorização de textos, clustering de textos, extração de

conceitos/entidades, análise de sentimento, sumarização de documentos ou ainda modelização de relações entre

entidades. Especificamente, neste documento, aborda-se a subárea da categorização de textos.

O relatório encontra-se organizado em 5 partes/capítulos. A primeira parte que é o presente capítulo

consiste na introdução à temática do relatório. No segundo capítulo, fala-se da temática do Text Mining e no terceiro

realiza-se a descrição dos dados selecionados do conjunto Reuters e expõem-se os resultados obtidos com o

pré-processamento. No quarto capítulo, descreve-se detalhadamente todo o processo de classificação e experiências

efetuadas utilizando o código R e apresenta-se os resultados obtidos com os conjuntos de documentos

considerados na classificação. Por fim e no último capítulo, apresenta-se uma conclusão crítica e reflexiva sobre os

resultados obtidos com as diversas experiências realizadas ao longo do trabalho.

(5)

2. Text Mining e Categorização de Documentos

O Text Mining consiste num processo de extração de informação relevante de um conjunto de documentos.

Os métodos utilizados em Text Mining envolvem operações básicas de pré-processamento, como identificação e

extração de características representativas, e operações avançadas de Text Mining como identificação de padrões

complexos.

A classificação/categorização de documentos ou textos é uma tarefa em que se atribui ao texto uma ou

mais categorias, tópicos ou sob o ponto de vista de classificação, a denominação da(s) sua(s) classe(s) de assunto

abordado. Os documentos podem ser classificados por conteúdo ou outros atributos tais como tipo de documento,

ano de impressão, autor, etc.

Neste relatório apenas se aborda a classificação por conteúdo. Neste tipo de classificação determina-se o

peso com que um documento está associado a determinado assunto ou tópico, no nosso caso de classificação por

algoritmo ou automática interessa-nos o número de vezes que palavras chave associadas a determinado(s)

conteúdo(s) aparecem no texto. A classificação automática será do tipo supervisionada e com um estudo do

comportamento de várias técnicas de classificadores tais como Decision Trees, Naive Bayes, Support Vector

Machines, Redes Neuronais, e K-NN (K Nearest Neighbours).

As representações estruturadas dos documentos por termos tal como descrito conduzem à identificação de

um elevado número de características, estando portanto associadas a uma grande dimensionalidade. Alguns dos

algoritmos a ser utilizados neste trabalho e que foram indicados anteriormente possuem dificuldades em lidar com

este problema pelo que é necessário empregar técnicas de redução de características. Ainda dificultando mais a

classificação, cada documento contem apenas um reduzido número do total de características potenciais.

Quanto aos tópicos de classificação do conjunto Reuters, foram escolhidos os tópicos referentes as classes

crude e money-fx. Os documentos utilizados foram o conjunto de documentos disponibilizados pela Reuters e que

estão disponíveis na página do moodle da cadeira de ECDII ou sob a forma de documentos XML no endereço web

http://ronaldo.cs.tcd.ie/esslli07/data/.

3. Pré-processamento de texto

Os dados utilizados neste estudo foram selecionados de um conjunto de vários temas de artigos da

Reuters, isto é, de um conjunto de dados que foram previamente sujeitos a uma separação prévia. Especificamente,

as duas coleções de documentos simplificados encontrando-se identificadas como crude e money-fx. Os dois

tópicos relativos a petróleo e moedas são compostos por 334 e 344 documentos, respetivamente.

Inicialmente definiu-se o diretório onde se encontravam os conjuntos de documentos arquivados em pastas

com os nomes crude e money-fx através do comando “change directory” do R.

Carregámos o pacote Text Mining do R que nos permitirá processar documentos de texto de uma forma

bastante rápida e eficaz com uma grande quantidade de funções que utilizaremos no decurso deste trabalho:

library(tm)

(6)

A fase seguinte compreendeu a criação de dois Corpus, isto é, duas coleções de textos, um Corpus por

cada tema ou tópico:

moneyfx <- Corpus( DirSource ("money-fx"), readerControl=list(reader=readPlain,language="en_US" ) ) crude <- Corpus( DirSource ("crude"), readerControl=list(reader=readPlain,language="en_US" ) )

Figura 2 – Criação dos dois Corpus de documentos

A figura 3 representa um exemplo de um dos documentos do tópico crude:

> crude[[1]]

CANADA OIL EXPORTS RISE 20 PCT IN 1986 OTTAWA, March 26 -

Canadian oil exports rose 20 pct in 1986

over the previous year to 33.96 mln cubic meters, while oil imports soared 25.2 pct to 20.58 mln cubic meters, Statistics Canada said.

Production, meanwhile, was unchanged from the previous year at 91.09 mln cubic feet.

Natural gas exports plunged 19.4 pct to 21.09 billion cubic meters, while Canadian sales slipped 4.1 pct to 48.09 billion cubic meters.

The federal agency said that in December oil production fell 4.0 pct to 7.73 mln cubic meters, while exports rose 5.2 pct to 2.84 mln cubic meters and imports rose 12.3 pct to 2.1 mln cubic meters.

Natural gas exports fell 16.3 pct in the month 2.51 billion cubic meters and Canadian sales eased 10.2 pct to 5.25 billion cubic meters.

Reuter

Figura 3 – Exemplo do documento 1 do tópico crude

Procedeu-se então à divisão dos dados crude e money-fx em dados de treino e de teste, particularmente,

70% de dados de treino e 30% para dados de teste. O conjunto de documentos crude passou a ser constituído por

233 documentos de treino e 101 de teste enquanto o conjunto de documentos money-fx passou a ser composto por

240 documentos de treino e 104 de teste.

(7)

Uma vez que possuímos quatro conjuntos de documentos com dois tópicos diferentes, procedeu-se a uma

junção destas conjuntos num só através da função de vectorização c():

docs <- c(crude.train, moneyfx.train, crude.test, moneyfx.test)

Figura 4 – Vectorização de todos os documentos de treino e de teste

Os índices de cada conjunto de documentos foram obtidos de modo a permitir uma posterior separação da

coleção de documentos:

l1 <- length(crude.train) l2 <- length(moneyfx.train) l3 <- length(crude.test) l4 <- length(moneyfx.test)

Figura 5 – Obtenção dos índices dos conjuntos de documentos de treino e de teste para posterior utilização

O pré-processamento do conjunto total de documentos (i.e., 678 documentos) permite lidar com o facto de

os documentos serem representados por palavras, termos e conceitos que conduzem a uma enorme diversidade de

palavras possíveis como potenciais indicadores de uma classe. Além disso, evita o problema da construção de um

classificador baseado em poucos casos, isto é, poucas palavras indicadoras de classe. Esta fase de

pré-processamento utilizando a função tm_map permite alterar o formato do documento, retirar palavras irrelevantes

para a língua especificada (i.e., o inglês), espaços em branco, transformar as letras maiúsculas em minúsculas,

retirar símbolos de pontuação e retirar números.

#preprocessamento do texto de todos os conjuntos de teste e treino docs.p <- docs

docs.p <- tm_map(docs.p, PlainTextDocument)

docs.p <- tm_map(docs.p, removeWords, stopwords(language="english")) docs.p <- tm_map(docs.p, stripWhitespace)

docs.p <- tm_map(docs.p, tolower)

docs.p <- tm_map(docs.p, removePunctuation) docs.p <- tm_map(docs.p, removeNumbers)

Figura 6 – Pré-processamento do texto com a função tm_map

O resultado do pré-processamento pode ser observado na Figura 7.

> docs.p[[1]]

canada oil exports rise pct in ottawa march

canadian oil exports rose pct previous mln cubic meters oil

(8)

imports soared pct mln cubic meters statistics canada

production meanwhile unchanged previous mln cubic feet

natural gas exports plunged pct billion cubic meters canadian sales slipped pct billion cubic meters

the federal agency december oil production fell pct mln cubic meters exports rose pct mln cubic meters imports rose pct mln cubic meters

natural gas exports fell pct month billion cubic meters canadian sales eased pct billion cubic meters

reuter

Figura 7 – Exemplo do documento 1 do tópico crude após pré-processamento.

Os classificadores que exploram a representação proposicional exigem que os dados se encontrem

representados em forma de dataframe do R onde: cada linha contém um documento e cada coluna representa um

atributo/característica (i.e., palavra/termo). A fase seguinte consiste em criar uma matriz de documento-termo (DTM)

através da função DocumentTermMatrix(). A Figura 8 representa os resultados da DTM:

> dtm.mx <- DocumentTermMatrix(docs.p,control=list(minWordLength=3, minDocFreq=2)) > dtm.mx

A document-term matrix (678 documents, 2417 terms) Non-/sparse entries: 11903/1626823

Sparsity : 99% Maximal term length: 20

Weighting : term frequency (tf)

Figura 8 – Resultados da função DocumentTermMatrix().

Podemos ter uma ideia dos termos mais frequentes através da utilização do seguinte código:

> freqterms150 <- findFreqTerms(dtm.mx,150) > freqterms150

[1] "bank" "banks" "barrels" "billion" "blah" [6] "bpd" "central" "crude" "currency" "dealers" [11] "dlrs" "dollar" "energy" "exchange" "foreign" [16] "gas" "government" "japan" "march" "market" [21] "mln" "money" "oil" "opec" "pct"

[26] "price" "prices" "production" "rate" "rates" [31] "reserves" "saudi" "stg" "the" "trade"

(9)

[36] "yen"

Figura 9 – Termos que aparecem pelo menos 150 vezes num documento.

Ainda, de modo a facilitar a aplicação dos algoritmos de classificação, aplicou-se a função

removeSparseTerms(DTM,S) para eliminar os termos que têm relativamente poucos valores numa coluna:

#remove os termos menos frequentes

dtm.mx.aux <- removeSparseTerms(dtm.mx, sparse)

Figura 10 – Remoção dos termos menos frequentes na matriz dos documentos.

Por exemplo para um valor de sparse de 0.95 definimos que retemos mais termos para classificação do

que se utilizarmos um valor menor de sparse. Exemplificando, foram retirados alguns exemplos com um ciclo de

iterações, ciclo sobre o qual falaremos mais num dos próximos capítulos. Assim e prosseguindo com o exemplo, o

número de termos da nossa matriz DTM para sparse = 0.95 é de 51 termos e para sparse = 0.85 é de 9 termos:

> var.sparse[,15] [1] 0.85 9.00 > var.sparse[,25] [1] 0.95 51.00

Figura 11 – Valores exemplo de sparse e respectivo número de termos encontrado.

(10)

Figura 12 – Valores de sparse e respectivo número de termos encontrado.

Por fim, é necessário converter a DTM num data frame utilizando a função as.data.frame():

#transforma DTM em Dataframe para posterior classificação do documento dtm <- as.data.frame(inspect(dtm.mx.aux))

Figura 13 – Conversão da DTM em data frame.

É este formato específico de tabela que permite que os classificadores sejam aplicados. O conjunto total de

documentos necessita agora de ser separada em classes de informação (crude e moneyfx) sob a forma de um

vector coluna no final do data frame:

(11)

# Prepara DTM para a classificação # com classe na última coluna

class <- c(rep("crude", 233),rep("moneyfx", 240),rep("crude", 101),rep("moneyfx", 104)) class.ts <- class[474:678]

class.tr <- class[1:473] dtm <- cbind(dtm, class)

Figura 14 – Preparação da nossa DTM para a classificação – adição da classe

A última fase do pré-processamento dos dados consiste em gerar dados de treino e de teste com linhas

apropriadas de DTM:

#Generate the training data with the appropriate lines of dtm dtm.tr <- dtm[1:(l1+l2), 1:ncol(dtm)]

#Generate the test data with the appropriate lines of dtm #retira a coluna das classes

dtm.ts <- dtm[(l1+l2+1):(l1+l2+l3+l4),1:(ncol(dtm)-1)]

(12)

4. Análise

Para esta fase do trabalho desenvolvemos um pequeno acrescento ao código original que nos permitiu

variar o valor do parâmetro sparse da função removeSparseTerms(dtm.mx, sparse). O acrescento de código

consistiu essencialmente na criação de um ciclo de iterações while que envolvia grande parte do código

correspondente à fase de classificação e de todos os classificadores (código completo disponível em anexos).

EXPERIÊNCIA 1 – Classificação sem tfidf

Variou-se o valor de input sparse da função removeSparseTerms entre 0.71 e 0.99 para podermos

comparar os resultados dos diferentes classificadores. Estes valores foram escolhidos porque nos pareceu o

intervalo em que a classificação é possível, isto é, para sparse de 0.71 obtemos o valor mínimo de termos que se

pode obter para que o programa tenha resultados válidos, uma vez que para valores abaixo deste a classificação

com KNN é inviabilizada tal como se pode ver pelo output do R obtido com o código:

Error in knn(dtm.tr[, info.terms], dtm.ts[, info.terms], class.tr, k = 1) : dims of 'test' and 'train' differ

In addition: Warning message: In weighting(x) : empty document > info.terms

[1] "the"

Figura 16 – Erro do classificador KNN com variação do parâmetro sparse abaixo de 0.71

Esta questão é explicada pelo facto de que com o valor inferior a 0.71 o número de termos de informação é

igual a 1 (apenas “the”) e a função KNN passa a tratar o caso de classificação como um vector linha que deverá ter

o mesmo tamanho para treino e teste o que não se verifica (mais informação na documentação da função KNN do

R). O valor limite de 0.99 para sparse é o valor correspondente ao máximo de termos possíveis para a classificação

em que não se retira praticamente termos nenhuns, mesmo aqueles que são menos frequentes em diversos

documentos.

Assim, temos como resultados para análise dos classificadores que o classificador com melhor resultado a

nível de erro de classificação foi, tal como se pode ver na figura seguinte, dado pelo classificador de redes neuronais

e com um valor de sparse de 0.93:

(13)

Figura 17 – Erro de classificação dos diversos classificadores com variação do parâmetro sparse

Os resultados quanto à precisão denotam a alta precisão da classificação em geral, para todos os

classificadores mas com resultado 100% certeiro em alguns classificadores no intervalo entre 0.77 e 0.87 do valor

para a variável sparse. Veja-se a figura 18.

(14)

Figura 18 – Precision dos classificadores com variação do parâmetro sparse

Quanto a recall o valor mais elevado de 1 (100%) foi atingido pelo classificador SVM com sparse de 0.98

como se pode ver na seguinte figura:

(15)

Figura 19 – Recall dos classificadores com variação do parâmetro sparse

Obtidos estes resultados e como temos muitos classificadores e uma grande variação do valor sparse

obtivemos os valores do score f1 representado na figura 20 e com máximo de 0.944 ou 94.4% para o classificador

de redes neuronais e sparse de 0.93 ou 93%:

(16)

Figura 20 – Score f1 dos classificadores com variação do parâmetro sparse

Mais se conclui que nestas condições este classificador tem os seguintes resultados de precision, recall e

erro de classificação:

> resultados["Neural Networks","0.93"] [1] 0.9463415 > resultados_precision["Neural Networks","0.93"] [1] 0.9787234 > resultados_recall["Neural Networks","0.93"]

(17)

[1] 0.910891

> resultados_f1["Neural Networks","0.93"] [1] 0.9435897

Figura 21 – Resultados do classificador Redes Neuronais (NN)

Indique-se ainda que o classificador com pior resultados, com os nossos dados e em termos de score f1,

com o valor de 0.832, foi o SVM para sparse = 0.87.

No gráfico da figura seguinte temos a variação com o valor de sparse dos scores f1 (valores entre um

mínimo de 0.832 e máximo de 0.944) dos diferentes classificadores. A distribuição de scores é a seguinte:

(18)

O classificador KNN atinge valores elevados de score f1 na classificação com valores mais baixos de

sparse (cerca de 0.88), ou seja com menos termos para classificação dos documentos (14 termos para

classificação). Seguidamente atingem o pico de score f1 os classificadores Redes Neuronais e SVM sensivelmente

para valores de sparse de 0.93 (correspondendo a 31 termos para classificação) sendo que o o classificador Naive

Bayes é o último a atingir o seu score mais alto de f1 para sparse de 0.98 (165 termos para classificação) ou seja já

com muitos termos disponíveis e muitos menos significativos para a classificação de uma classe especifica.

(19)

EXPERIÊNCIA 2 – Classificação com tfidf

Avançámos com variação do valor de input sparse da função removeSparseTerms entre 0.71 e 0.99 para

podermos comparar os resultados dos diferentes classificadores mas agora com tfidf. Para tal especificámos o

seguinte código na geração da matriz de dados DTM:

#matriz DTM com Tfidf

dtm.mx.tfidf <- DocumentTermMatrix( docs.p, control=list(weighting=weightTfIdf, minWordLength=3, minDocFreq=2))

Figura 23 – Criação de DTM com tfidf

Repare-se que mantivemos os valores do tamanho mínimo da palavra e frequência da mesma, em relação

à matriz previamente gerada sem tfidf.

Os resultados do erro de classificação dos diversos classificadores podem ser consultados na seguinte

figura do output do R:

(20)

Figura 24 – Erro dos classificadores com variação do parâmetro sparse (com tfidf)

Os resultados quanto à precisão denotam a alta precisão da classificação em geral para todos os

classificadores mas com resultado 100% certeiro no classificador SVM no intervalo entre 0.71 e 0.87 do valor para a

variável sparse. Veja-se a figura 25.

(21)

Figura 25 – Precision dos classificadores com variação do parâmetro sparse (com tfidf)

Quanto a recall o valor mais elevado de 0.980 foi atingido pelo classificador de Redes Neuronais com

(22)

Figura 26 – Recall dos classificadores com variação do parâmetro sparse (com tfidf)

Obtidos estes resultados e como temos muitos classificadores e uma grande variação do valor sparse

obtivemos os valores do score f1 representado na figura 27 e com máximo de 0.959 ou 95.9% para o classificador

SVM e sparse de 0.94 ou 94%:

(23)

Figura 27 – Score f1 dos classificadores com variação do parâmetro sparse (com tfidf)

Mais se conclui que nestas condições este classificador tem os seguintes resultados de erro de

classificação, precision e recall:

> resultados["Support Vector Machines","0.94"] [1] 0.9609756

(24)

[1] 0.9793814

> resultados_recall["Support Vector Machines","0.94"] [1] 0.940594

> resultados_f1["Support Vector Machines","0.94"] [1] 0.959596

Figura 28 – Resultados do classificador Support Vector Machines (SVM)

Indique-se ainda que o classificador com pior resultados com os nossos dados (com tfidf) e em termos de

score f1, com o valor de 0.812 foi o Naive Bayes para sparse = 0.86.

No gráfico da figura seguinte temos a variação dos scores f1 (valores entre um mínimo de 0.812 e máximo

de 0.959) dos diferentes classificadores com o valor de sparse. A distribuição de scores é a seguinte:

(25)

O classificador SVM atinge valores mais elevados de score f1 desde o inicio do intervalo dos valores de

sparse o que nos leva a concluir que com tfidf é por ligeira margem o melhor classificador em termos gerais para a

(26)

5. Conclusões Finais

Como conclusões do nosso trabalho reconhecemos de forma mais vincada que no inicio do trabalho, toda a

importância de um bom pré-processamento dos dados de forma a obter boa qualidade nas classificações

automáticas de textos. Em geral as classificações obtidas são de boa qualidade para todos os classificadores e com

os nossos dados de crude e moeda.

Podemos verificar ainda que o parâmetro sparse faz variar em grande medida a qualidade de classificação

em quase todos os classificadores. O classificador Decision Trees é o que menos varia com estas alterações sendo

que outros classificadores podem variar o seu score f1 em 10% com a otimização do parâmetro sparse. Pensamos

ser este o parâmetro mais importante ou influenciador na obtenção de melhores resultados no código em R

utilizado.

A utilização de tfidf na criação da DTM apenas melhorou ligeiramente a qualidade do até então melhor

classificador que era o de redes neuronais para 31 termos (sparse = 0.94). Assim o classificador SVM passou a ser

o melhor classificador com o tfidf sendo de notar agora que com 39 termos (sparse = 0.94). A diferença não é

grande mas implica a necessidade de ter mais 8 termos disponíveis na matriz utilizada para classificação dos

documentos.

(27)

6. Bibliografia

Brazdil, P. P. (08 de 2011). Classification of Documents using Text Mining Package “tm”. FEP slides.

Brazdil, P. P. (01 de 2012). Classification of Documents using Text Mining Package “tm”: Additional Topics. FEP

slides.

Feinerer, I. (20 de 02 de 2011). Introduction to the tm Package.

(28)

7. Anexos

Código utilizado na realização do trabalho:

library(tm)

########################################## ###### TRABALHO ECDII - TEXT MINING ###### ########################################## #Create the Corpus of documents

moneyfx <- Corpus( DirSource ("money-fx"), readerControl=list(reader=readPlain,language="en_US" ) ) crude <- Corpus( DirSource ("crude"), readerControl=list(reader=readPlain,language="en_US" ) ) #Criamos dados de treino e de teste para cada um dos classificadores

moneyfx.train <- moneyfx[1:as.integer(length(moneyfx)*0.7)] moneyfx.test <- moneyfx[(as.integer(length(moneyfx)*0.7)+1):length(moneyfx)] crude.train <- crude[1:as.integer(length(crude)*0.7)] crude.test <- crude[(as.integer(length(crude)*0.7)+1):length(crude)] l1 <- length(crude.train) l2 <- length(moneyfx.train) l3 <- length(crude.test) l4 <- length(moneyfx.test)

docs <- c(crude.train, moneyfx.train, crude.test, moneyfx.test) #preprocessamento do texto de todos os conjuntos de teste e treino docs.p <- docs

docs.p <- tm_map(docs.p, PlainTextDocument)

docs.p <- tm_map(docs.p, removeWords, stopwords(language="english")) docs.p <- tm_map(docs.p, stripWhitespace)

docs.p <- tm_map(docs.p, tolower)

docs.p <- tm_map(docs.p, removePunctuation) docs.p <- tm_map(docs.p, removeNumbers) #browser()

#matriz DTM Document-Term Matrix

dtm.mx <- DocumentTermMatrix(docs.p,control=list(minWordLength=3, minDocFreq=2)) #matriz DTM com Tfidf

(29)

dtm.mx.tfidf <- DocumentTermMatrix( docs.p, control=list(weighting=weightTfIdf, minWordLength=3, minDocFreq=2))

#browser()

#procura termos frequentes que aparecem pelo menos 100 vezes em um dos documentos freqterms100 <- findFreqTerms( dtm.mx, 100)

#procura termos frequentes que aparecem pelo menos 100 vezes em um dos documentos freqterms40 <- findFreqTerms( dtm.mx, 40)

#browser()

##Ciclo que varia a quantidade de remoção de termos menos frequentes para encontrar os melhores resultados ##da classificação com os diversos classificadores

#inicialização de algumas variaveis sparse <- 0.71

sparse1 <- sparse

resultados <- data.frame(row.names = c("Decision Trees", "K-Nearest Neighbours","Neural Networks","Naive Bayes","Support Vector Machines"))

resultados_recall <- data.frame(row.names = c("Decision Trees", "K-Nearest Neighbours","Neural Networks","Naive Bayes","Support Vector Machines"))

resultados_precision <- data.frame(row.names = c("Decision Trees", "K-Nearest Neighbours","Neural Networks","Naive Bayes","Support Vector Machines"))

resultados_f1 <- data.frame(row.names = c("Decision Trees", "K-Nearest Neighbours","Neural Networks","Naive Bayes","Support Vector Machines"))

var.sparse <- data.frame(row.names = c("Sparse Value", "Number of Terms")) while (sparse < 1){

#remove os termos menos frequentes, variar valor de input para procurar melhores classificações dtm.mx.aux <- removeSparseTerms(dtm.mx, sparse)

dtm.mx.tfidf.aux <- removeSparseTerms(dtm.mx.tfidf, sparse) #browser()

#transforma DTM em Dataframe para posterior classificação dtm <- as.data.frame(inspect(dtm.mx.aux))

var.sparse <- cbind(var.sparse,c(sparse,ncol(dtm))) dtm.tfidf <- as.data.frame(inspect(dtm.mx.tfidf.aux)) #browser()

(30)

# com classe na última coluna

class <- c(rep("crude", 233),rep("moneyfx", 240),rep("crude", 101),rep("moneyfx", 104)) class.ts <- class[474:678]

class.tr <- class[1:473] dtm <- cbind(dtm, class)

dtm.tfidf <- cbind(dtm.tfidf, class)

#Generate the training data with the appropriate lines of dtm dtm.tr <- dtm[1:(l1+l2), 1:ncol(dtm)]

#O mesmo para DTM com tfidf

dtm.tfidf.tr <- dtm.tfidf[1:(l1+l2), 1:ncol(dtm.tfidf)] #dim(dtm.tr)

#Generate the test data with the appropriate lines of dtm #retira a coluna das classes

dtm.ts <- dtm[(l1+l2+1):(l1+l2+l3+l4),1:(ncol(dtm)-1)]

dtm.tfidf.ts <- dtm.tfidf[(l1+l2+1):(l1+l2+l3+l4),1:(ncol(dtm.tfidf)-1)] #Teste com tfidf - é comentado para classificação sem tfidf

# dtm <- dtm.tfidf # dtm.ts <- dtm.tfidf.ts # dtm.tr <- dtm.tfidf.tr

######################################### ####Classificação com Decision Trees##### ######################################### library(rpart) info.terms <- vector() find.info.terms <- function(dtm.tr,min.info){ ix.class <- ncol(dtm.tr) default.info <- info(table(dtm.tr[,ix.class])) #cat("default.info: ", default.info, "\n") n.atr <- ncol(dtm.tr)-1 n.info.terms <- 0 info.term.ixs <- vector() col.names <- names(dtm.tr) for (atri in 1:n.atr) {

if (sum(dtm.tr[,atri])>0) { # begin if

(31)

atr.class.table<-table(dtm.tr[,atri],dtm.tr[,ix.class]) n.rows<-nrow(dtm.tr)

atr.info <- 0

for (atr.val in 1: no.dif.atr.val) { # begin for

atr.peso <- sum( atr.class.table[atr.val,]) / n.rows atr.info1 <- atr.peso * info(atr.class.table[atr.val,]) atr.info<-atr.info + atr.info1 }

info.gain <- default.info - atr.info if (info.gain > min.info)

{ info.term.ixs[n.info.terms] <- atri n.info.terms <- n.info.terms+1 } } #end for

} # end if

#cat("\n", "Vão ser mantidos ", n.info.terms, " atributos: ", "\n") #cat( col.names[info.term.ixs[1:10]], " etc. ")

#cat( col.names[info.term.ixs[n.info.terms-1]],"\n")

#cat("Vão ser eliminados ", n.atr-n.info.terms, " atributos", "\n") return(col.names[info.term.ixs]) # Corrected 29 June 2011 } # end function

#Function “info” calculates information relative to a list specifying a distribution: info <- function(x){ inf <- 0 sumx <- sum(x) for (i in x) { pi <- i/sumx infi <- (pi)*log2(pi) if (is.na(infi)) infi <- 0 inf <- inf - infi } return(inf) }

info.terms <- find.info.terms(dtm.tr,0.005) rename.terms.in.list <- function(list) { for (i in 1:length(list)) {

#cat("replaced", list[i], "at", i, "with", paste(list[i],".t", sep=""), "\n") list[i]<- paste(list[i],".t", sep="")

} #end for i return(list) }

#renomeia os termos para evitar problemas na classificação com DT info.terms.dt <- rename.terms.in.list(info.terms)

(32)

rename.terms.in.dtm <- function(dtm) { for (i in 1:length(dtm)) {

#cat("replaced", names(dtm)[i], "at", i, "with", paste(names(dtm)[i],".t", sep=""), "\n") names(dtm)[i] <- paste(names(dtm)[i],".t", sep="")

} #end for i return(dtm) }

dtm.tr.dt <- rename.terms.in.dtm(dtm.tr) dtm.ts.dt <- rename.terms.in.dtm(dtm.ts) names.tr.dt <- paste(info.terms.dt, collapse="+") names.tr <- paste(info.terms, collapse="+") #Formula para a classificação com decision trees

clas.formula <- as.formula( paste("class.t", names.tr.dt, sep="~") ) #browser()

dt <- rpart(clas.formula, dtm.tr.dt)

#Prediction

preds.dt <- predict(dt, dtm.ts.dt, type="class") #browser()

#Construct a confusion matrix: conf.mx.dt <- table(class.ts, preds.dt) #Percentagem de erros de previsão

error.rate.dt <- (sum(conf.mx.dt) - sum(diag(conf.mx.dt))) / sum(conf.mx.dt) #Avaliação do classificador

tp.dt <- conf.mx.dt[1,1] #(true positives) fp.dt <- conf.mx.dt[2,1] #(false positives) tn.dt <- conf.mx.dt[2,2] #(true negatives) fn.dt <- conf.mx.dt[1,2] #(false negatives)

error.rate.dt <- (tp.dt + tn.dt) / (tp.dt + tn.dt + fp.dt + fn.dt) recall.dt = tp.dt / (tp.dt + fn.dt)

precision.dt = tp.dt / (tp.dt + fp.dt)

f1.dt = 2 * precision.dt * recall.dt / (precision.dt + recall.dt) #Formula para a classificação dos restantes classificadores clas.formula <- as.formula( paste("class", names.tr, sep="~") ) #########################################

(33)

####Classificação com Redes Neuronais#### ######################################### #browser()

library(nnet)

nnet.classifier <- nnet(clas.formula, data = dtm.tr, size=2, rang=0.1,decay=5e-4, maxit=200) preds.nn <- predict(nnet.classifier, dtm.ts, type="class")

conf.mx.nn <- table(class.ts, preds.nn)

error.rate.nn <- (sum(conf.mx.nn) - sum(diag(conf.mx.nn))) / sum(conf.mx.nn) #Avaliação do classificador

tp.nn <- conf.mx.nn[1,1] #(true positives) fp.nn <- conf.mx.nn[2,1] #(false positives) tn.nn <- conf.mx.nn[2,2] #(true negatives) fn.nn <- conf.mx.nn[1,2] #(false negatives)

error.rate.nn <- (tp.nn + tn.nn) / (tp.nn + tn.nn + fp.nn + fn.nn) recall.nn = tp.nn / (tp.nn + fn.nn)

precision.nn = tp.nn / (tp.nn + fp.nn)

f1.nn = 2 * precision.nn * recall.nn / (precision.nn + recall.nn) ############################################ ####Classificação com Classificador K-NN#### ############################################ #browser()

#Notes:

#Usage of tfidf coding could improve this result library(class)

preds.knn <- knn(dtm.tr[, info.terms], dtm.ts[, info.terms], class.tr, k=1) conf.mx.knn <- table(class.ts, preds.knn)

error.rate.knn <- (sum(conf.mx.knn) - sum(diag(conf.mx.knn))) / sum(conf.mx.knn) #Avaliação do classificador

tp.knn <- conf.mx.knn[1,1] #(true positives) fp.knn <- conf.mx.knn[2,1] #(false positives) tn.knn <- conf.mx.knn[2,2] #(true negatives) fn.knn <- conf.mx.knn[1,2] #(false negatives)

error.rate.knn <- (tp.knn + tn.knn) / (tp.knn + tn.knn + fp.knn + fn.knn) recall.knn = tp.knn / (tp.knn + fn.knn)

precision.knn = tp.knn / (tp.knn + fp.knn)

f1.knn = 2 * precision.knn * recall.knn / (precision.knn + recall.knn) #############################

(34)

####Classificação com SVM#### ############################# #browser() library(e1071) svm.classifier <- svm(clas.formula, dtm.tr) preds.svm <- predict(svm.classifier, dtm.ts) conf.mx.svm <- table(class.ts, preds.svm)

error.rate.svm <- (sum(conf.mx.svm) - sum(diag(conf.mx.svm))) / sum(conf.mx.svm) #Avaliação do classificador

tp.svm <- conf.mx.svm[1,1] #(true positives) fp.svm <- conf.mx.svm[2,1] #(false positives) tn.svm <- conf.mx.svm[2,2] #(true negatives) fn.svm <- conf.mx.svm[1,2] #(false negatives)

error.rate.svm <- (tp.svm + tn.svm) / (tp.svm + tn.svm + fp.svm + fn.svm) recall.svm = tp.svm / (tp.svm + fn.svm)

precision.svm = tp.svm / (tp.svm + fp.svm)

f1.svm = 2 * precision.svm * recall.svm / (precision.svm + recall.svm)

##################################### ####Classificação com Naive Bayes#### ##################################### #browser() library(RWeka) NB<-make_Weka_classifier("weka/classifiers/bayes/NaiveBayes") nb.classifier<-NB(clas.formula, dtm.tr) preds.nb<-predict(nb.classifier, dtm.ts) conf.mx.nb<-table(class.ts, preds.nb)

error.rate.nb <- (sum(conf.mx.nb) - sum(diag(conf.mx.nb))) / sum(conf.mx.nb) #Avaliação do classificador

tp.nb <- conf.mx.nb[1,1] #(true positives) fp.nb <- conf.mx.nb[2,1] #(false positives) tn.nb <- conf.mx.nb[2,2] #(true negatives) fn.nb <- conf.mx.nb[1,2] #(false negatives)

error.rate.nb <- (tp.nb + tn.nb) / (tp.nb + tn.nb + fp.nb + fn.nb) recall.nb = tp.nb / (tp.nb + fn.nb)

precision.nb = tp.nb / (tp.nb + fp.nb)

(35)

resultados <- cbind(resultados, c(error.rate.dt,error.rate.knn,error.rate.nn,error.rate.nb,error.rate.svm)) resultados_recall <- cbind(resultados_recall, c(recall.dt,recall.knn,recall.nn,recall.nb,recall.svm))

resultados_precision <- cbind(resultados_precision, c(precision.dt,precision.knn,precision.nn,precision.nb,precision.svm)) resultados_f1 <- cbind(resultados_f1, c(f1.dt,f1.knn,f1.nn,f1.nb,f1.svm)) sparse <- sparse + 0.01 } colnames(resultados) = c(as.character(seq(sparse1,0.99,0.01))) colnames(resultados_precision) = c(as.character(seq(sparse1,0.99,0.01))) colnames(resultados_recall) = c(as.character(seq(sparse1,0.99,0.01))) colnames(resultados_f1) = c(as.character(seq(sparse1,0.99,0.01)))

Referências

Documentos relacionados

resident male in presence of another male; IF) aggressive calls emitted in response to.. playback of

FACULDADE DE ENGENHARIA DE ILHA SOLTEIRA - UNESP - DEPARTAMENTO DE FITOSSANIDADE, ENGENHARIA RURAL E SOLOS ÁREA DE ENGENHARIA RURAL - HIDRÁULICA e IRRIGAÇÃO FONE: 0xx18 3743 -1180

O foco fundamental desse trabalho é a utilização de técnicas de processamento e análise digital de imagens para a estimativa da fração volumétrica de estruturas

A incidência de FO no estado de Sergipe obtida através dos dados do SINASC, no mesmo período da pesquisa, foi de 0,54 novos casos de fissura para cada 1000 nascidos vivos..

Entretanto, encontramos evidências neste trabalho de que estas variáveis não satisfazem as condições para serem utilizadas como instrumentos (Cap.2, seção 3.1.).

Contudo, não é possível imaginar que essas formas de pensar e agir, tanto a orientada à Sustentabilidade quanto a tradicional cartesiana, se fomentariam nos indivíduos

Os indicadores do Balanced Scorecard devem relatar a história durante a implementação da estratégia, começando pelas metas financeiras de longo prazo e relacionando-os

Parágrafo segundo – Não ocorrendo a citada homologação por responsabilidade do SESI-SP, em até 30 (trinta) dias após o prazo máximo para o pagamento das